pax_global_header00006660000000000000000000000064146475267110014527gustar00rootroot0000000000000052 comment=85af2929937d516997451cbd52d352cf93125ed2 RenderKit-ospray-85af292/000077500000000000000000000000001464752671100152735ustar00rootroot00000000000000RenderKit-ospray-85af292/.clang-format000066400000000000000000000055131464752671100176520ustar00rootroot00000000000000--- Language: Cpp # BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: DontAlign AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false #EscapedNewlineAlignmentStyle: Right AlignEscapedNewlines: Right AlignOperands: false AlignTrailingComments: false AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Empty #AllowShortLambdasOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false BraceWrapping: AfterClass: true AfterControlStatement: false AfterEnum: true AfterFunction: true AfterNamespace: false AfterStruct: true AfterUnion: true BeforeCatch: false BeforeElse: false IndentBraces: false SplitEmptyFunction: false BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: Custom BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false #BreakConstructorInitializersStyle: BeforeComma BreakStringLiterals: false ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: [ foreach, foreach_active, foreach_tiled, foreach_unique, cdo, cfor, cif, cwhile ] IncludeCategories: - Regex: '^<.*\.i?h>' Priority: 1 - Regex: '^<.*' Priority: 2 - Regex: '.*' Priority: 3 IncludeIsMainRegex: '([-_](test|unittest))?$' IndentCaseLabels: false IndentWidth: 2 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 #PPDirectiveIndentStyle: AfterHash PointerAlignment: Right ReflowComments: true SortIncludes: true SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp11 TabWidth: 2 UseTab: Never ... RenderKit-ospray-85af292/.gitattributes000066400000000000000000000001051464752671100201620ustar00rootroot00000000000000*.rc text working-tree-encoding=UTF-16LE-BOM eol=CRLF *.patch eol=lf RenderKit-ospray-85af292/.github/000077500000000000000000000000001464752671100166335ustar00rootroot00000000000000RenderKit-ospray-85af292/.github/workflows/000077500000000000000000000000001464752671100206705ustar00rootroot00000000000000RenderKit-ospray-85af292/.github/workflows/baseline.yml000066400000000000000000000034331464752671100232000ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: Baseline on: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### build-ubuntu2004-gcc: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:20.04 cmd: | scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-ubuntu2004-gcc artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt ### Benchmarks ### generate-ci-baseline-avx2: needs: build-ubuntu2004-gcc uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:20.04 runs-on: '"avx2"' cmd: | export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build/install/ospray/lib:$LD_LIBRARY_PATH export PATH=$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH scripts/tests/generate_baseline.sh artifact-in: build-ubuntu2004-gcc artifact-out: generate-ci-baseline-avx2 artifact-path: generated_test_images generate-ci-baseline-avx512skx: needs: build-ubuntu2004-gcc uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:20.04 cmd: | export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build/install/ospray/lib:$LD_LIBRARY_PATH export PATH=$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH scripts/tests/generate_baseline.sh artifact-in: build-ubuntu2004-gcc artifact-out: generate-ci-baseline-avx512skx artifact-path: generated_test_images RenderKit-ospray-85af292/.github/workflows/benchmark.yml000066400000000000000000000057011464752671100233500ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: Benchmark on: schedule: - cron: '30 0 * * *' workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### build-linux: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8.7 env-from-files: .github/workflows/dpcpp.env cmd: | module load cmake/3.25.3 module load mpi/mpich-x86_64 export CC=clang export CXX=clang++ scripts/build/linux.sh -DBUILD_GPU_SUPPORT=ON artifact-out: build-linux artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt ### Benchmarks ### benchmark-x8280-1: needs: build-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main secrets: inherit with: runs-on: '"vis-perf-x8280-1"' setup-benny: true cmd: | scripts/tests/run-benchmarks.sh artifact-in: build-linux benchmark-x8380-1: needs: build-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main secrets: inherit with: runs-on: '"vis-perf-x8380-1"' setup-benny: true cmd: | scripts/tests/run-benchmarks.sh artifact-in: build-linux benchmark-a-1: needs: build-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main secrets: inherit with: runs-on: '"vis-perf-a3970x-1"' setup-benny: true cmd: | scripts/tests/run-benchmarks.sh artifact-in: build-linux benchmark-adl-1: needs: build-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main secrets: inherit with: runs-on: '"vis-perf-i9-12900k-1"' setup-benny: true cmd: | scripts/tests/run-benchmarks.sh artifact-in: build-linux benchmark-dg2: needs: build-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"vis-perf-dg2-01"' setup-benny: true cmd: | scripts/tests/run-benchmarks.sh GPU artifact-in: build-linux benchmark-pvc: needs: build-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"vis-perf-spr-pvc-01"' setup-benny: true cmd: | scripts/tests/run-benchmarks.sh GPU artifact-in: build-linux RenderKit-ospray-85af292/.github/workflows/ci.linux.gpu.yml000066400000000000000000000227141464752671100237440ustar00rootroot00000000000000## Copyright 2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: CI Linux GPU on: push: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### ubu22-mpi-dpcpp-build: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:22.04 env-from-files: .github/workflows/dpcpp.env cmd: | module load cmake/3.25.3 export CC=clang export CXX=clang++ scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_GPU_SUPPORT=ON -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-ubuntu2204-mpi-dpcpp artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt ubu22-mpi-icx-build: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:22.04 env-from-files: .github/workflows/icx-linux.env .github/workflows/gfx-ubuntu22.env # OIDN AOT needs ocloc cmd: | module load cmake/3.25.3 scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_GPU_SUPPORT=ON -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN_FROM_SOURCE=ON artifact-out: build-ubuntu2204-mpi-icx artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt suse-icx-build: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: opensuse/leap:15.3 env-from-files: .github/workflows/icx-linux.env cmd: | module load cmake/3.25.3 scripts/build/linux.sh -DBUILD_GPU_SUPPORT=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON rocky8-mpich-dpcpp-build: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 env-from-files: .github/workflows/dpcpp.env cmd: | module load cmake/3.25.3 module load mpi/mpich-x86_64 export CC=clang export CXX=clang++ scripts/build/linux.sh -DBUILD_GPU_SUPPORT=ON -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-rocky8-mpich-dpcpp artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt ### TEST JOBS ### dpcpp-dg2-ubu22-test: needs: ubu22-mpi-dpcpp-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"dg2"' artifact-in: build-ubuntu2204-mpi-dpcpp artifact-out: test-ubuntu2204-dpcpp-dg2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | module load cmake/3.25.3 export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" dpcpp-pvc-ubu22-test: needs: ubu22-mpi-dpcpp-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"pvc"' artifact-in: build-ubuntu2204-mpi-dpcpp artifact-out: test-ubuntu2204-dpcpp-pvc artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | module load cmake/3.25.3 export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" mpi-dpcpp-pvc-ubu22-test: needs: ubu22-mpi-dpcpp-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"pvc"' artifact-in: build-ubuntu2204-mpi-dpcpp artifact-out: test-ubuntu2204-mpi-dpcpp-pvc artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | module load cmake/3.25.3 export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" SKIP_GPU TEST_MPI multidev-dpcpp-pvc-ubu22-test: needs: ubu22-mpi-dpcpp-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"pvc"' artifact-in: build-ubuntu2204-mpi-dpcpp artifact-out: test-ubuntu2204-multidev-dpcpp-pvc artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | module load cmake/3.25.3 export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" SKIP_GPU TEST_MULTIDEVICE icx-dg2-ubu22-test: needs: ubu22-mpi-icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/icx-linux.env .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"dg2"' artifact-in: build-ubuntu2204-mpi-icx artifact-out: test-ubuntu2204-icx-dg2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" mpi-icx-dg2-ubu22-test: needs: ubu22-mpi-icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/icx-linux.env .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"dg2"' artifact-in: build-ubuntu2204-mpi-icx artifact-out: test-ubuntu2204-mpi-icx-dg2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" SKIP_GPU TEST_MPI icx-pvc-ubu22-test: needs: ubu22-mpi-icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/icx-linux.env .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"pvc"' artifact-in: build-ubuntu2204-mpi-icx artifact-out: test-ubuntu2204-icx-pvc artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" mpi-icx-pvc-ubu22-test: needs: ubu22-mpi-icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/icx-linux.env .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"pvc"' artifact-in: build-ubuntu2204-mpi-icx artifact-out: test-ubuntu2204-mpi-icx-pvc artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" SKIP_GPU TEST_MPI multidev-icx-pvc-ubu22-test: needs: ubu22-mpi-icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/icx-linux.env .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"pvc"' artifact-in: build-ubuntu2204-mpi-icx artifact-out: test-ubuntu2204-multidev-icx-pvc artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_gpu_tests.sh "$GITHUB_WORKSPACE" SKIP_GPU TEST_MULTIDEVICE RenderKit-ospray-85af292/.github/workflows/ci.linux.yml000066400000000000000000000421071464752671100231500ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: CI Linux on: push: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### build-arch-clang: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: archlinux:latest cmd: | export CC=clang export CXX=clang++ scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF build-arch-clang-extras: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: archlinux:latest cmd: | export CC=clang export CXX=clang++ scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_OSPRAY_CI_EXTRAS=ON -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON build-arch-gcc: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: archlinux:latest cmd: | scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF build-ubuntu2404-gcc-extras: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:24.04 cmd: | scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_OSPRAY_CI_EXTRAS=ON build-rocky8-gcc: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 cmd: | scripts/build/linux.sh -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN=OFF -DBUILD_ISA_AVX512=OFF -DTBB_VERSION=2021.9.0 artifact-out: build-rocky8-gcc artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-rocky8-icx: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 cmd: | module load cmake module load intel/2022.1 export CC=icx export CXX=icpx export CXXFLAGS="-fhonor-infinities -fhonor-nans" export CFLAGS=$CXXFLAGS export LDFLAGS="-static-intel" scripts/build/linux.sh -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN=OFF -DTBB_VERSION=2021.9.0 artifact-out: build-rocky8-icx artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-rocky8-mpi-impi: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 cmd: | module load cmake module load impi/2021.6 scripts/build/linux.sh -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN=OFF -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_ISA_AVX512=OFF -DTBB_VERSION=2021.9.0 build-rocky8-mpi-mpich: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 cmd: | module load cmake module load mpi/mpich-x86_64 scripts/build/linux.sh -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN=OFF -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_ISA_AVX512=OFF -DTBB_VERSION=2021.9.0 artifact-out: build-rocky8-mpi-mpich artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-rocky8-mpi-openmpi: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 cmd: | module load cmake module load mpi/openmpi-x86_64 scripts/build/linux.sh -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN=OFF -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_ISA_AVX512=OFF -DTBB_VERSION=2021.9.0 build-centos8: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: centos:8 cmd: | scripts/build/linux.sh -G Ninja artifact-out: build-centos8 artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-centos8-mpi-mpich: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: centos:8 cmd: | module load mpi/mpich-x86_64 scripts/build/linux.sh -DBUILD_OSPRAY_MODULE_MPI=ON build-centos8-mpi-openmpi: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: centos:8 cmd: | module load mpi/openmpi-x86_64 scripts/build/linux.sh -DBUILD_OSPRAY_MODULE_MPI=ON build-rocky8-oidn-mpi: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 cmd: | module load cmake/3.15.2 module load mpi/mpich-x86_64 scripts/build/linux.sh -DBUILD_OSPRAY_MODULE_MPI=ON artifact-out: build-rocky8-oidn-mpi artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-linux-debug: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: archlinux:latest cmd: | export CC=clang export CXX=clang++ export CFLAGS=-fsanitize=address export CXXFLAGS=-fsanitize=address export LDFLAGS=-fsanitize=address scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DCMAKE_BUILD_TYPE=Debug -DBUILD_OSPRAY_MODULE_MPI=ON artifact-out: build-linux-debug artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build/install/embree build-ubuntu2404-gcc: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:24.04 cmd: | scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF artifact-out: build-ubuntu2404-gcc artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-ubuntu2004-gcc: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:20.04 cmd: | scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-ubuntu2004-gcc artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-ubuntu2204-oidn-mpi: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:22.04 cmd: | scripts/build/linux.sh -DBUILD_OSPRAY_MODULE_MPI=ON artifact-out: build-ubuntu2204-oidn-mpi artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-ubuntu2204-arm: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main with: runs-on: '[ "Linux", "ARM64" ]' cmd: | scripts/build/linux.sh -DBUILD_GLFW=OFF -DBUILD_TBB_FROM_SOURCE=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN_FROM_SOURCE=ON artifact-out: build-ubuntu2204-arm artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt ### TEST JOBS ### test-rocky8-gcc-avx2: needs: build-rocky8-gcc uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX2 artifact-in: build-rocky8-gcc artifact-out: test-rocky8-gcc-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-rocky8-gcc-mpi-mpich-avx2: needs: build-rocky8-mpi-mpich uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 cmd: | module load cmake module load mpi/mpich-x86_64 PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX2 TEST_MPI artifact-in: build-rocky8-mpi-mpich artifact-out: test-rocky8-gcc-mpi-mpich-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-rocky8-icx-avx2: needs: build-rocky8-icx uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 runs-on: '"avx2"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX2 artifact-in: build-rocky8-icx artifact-out: test-rocky8-icx-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-rocky8-icx-avx512skx: needs: build-rocky8-icx uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 runs-on: '"avx512"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-rocky8-icx artifact-out: test-rocky8-icx-avx512skx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-centos8-avx512skx: needs: build-centos8 uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: centos:8 runs-on: '"avx512"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-centos8 artifact-out: test-centos8-avx512skx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-rocky8-oidn-mpi-avx512skx: needs: build-rocky8-oidn-mpi uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 runs-on: '"avx512"' cmd: | module load cmake/3.15.2 module load mpi/mpich-x86_64 export OIDN_DEFAULT_DEVICE=cpu PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX TEST_MPI artifact-in: build-rocky8-oidn-mpi artifact-out: test-rocky8-oidn-mpi-avx512skx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-find-ospray: needs: build-centos8 uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: centos:8 cmd: | module load cmake mkdir buildtut cd buildtut cmake -D ospray_DIR=`echo $GITHUB_WORKSPACE/build/install/ospray/lib/cmake/ospray-*` ../apps/ospTutorial/ospTutorialFindospray cmake --build . artifact-in: build-centos8 test-ubuntu2404-gcc-avx512skx: needs: build-ubuntu2404-gcc uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:24.04 runs-on: '"avx512"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-ubuntu2404-gcc artifact-out: test-ubuntu2404-gcc-avx512skx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-ubuntu2004-gcc-avx2: needs: build-ubuntu2004-gcc uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:20.04 runs-on: '"avx2"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX2 artifact-in: build-ubuntu2004-gcc artifact-out: test-ubuntu2004-gcc-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-ubuntu2004-gcc-avx512skx: needs: build-ubuntu2004-gcc uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:20.04 runs-on: '"avx512"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX TEST_MULTIDEVICE artifact-in: build-ubuntu2004-gcc artifact-out: test-ubuntu2004-gcc-avx512skx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-ubuntu2204-oidn-mpi-avx2-dg2: needs: build-ubuntu2204-oidn-mpi uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: ubuntu:22.04 env-from-files: .github/workflows/dpcpp.env .github/workflows/gfx-ubuntu22.env submodules: true options: --device=/dev/dri:/dev/dri runs-on: '"dg2"' cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" export OIDN_DEFAULT_DEVICE=sycl export OIDN_VERBOSE=2 mkdir build_regression_tests cd build_regression_tests cmake -D OSPRAY_TEST_ISA=AVX2 $GITHUB_WORKSPACE/test_image_data cmake --build . --target ospray_test_data ospTestSuite --baseline-dir=regression_test_baseline --gtest_filter="DenoiserOp.DenoiserOp" OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 mpiexec -np 1 ospTestSuite --baseline-dir=regression_test_baseline --gtest_filter="DenoiserOp.DenoiserOp" --osp:load-modules=mpi_offload --osp:device=mpiOffload : -np 2 ospray_mpi_worker artifact-in: build-ubuntu2204-oidn-mpi test-ubuntu2204-arm: needs: build-ubuntu2204-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main with: runs-on: '[ "Linux", "ARM64" ]' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-ubuntu2204-arm artifact-out: test-ubuntu2204-arm artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* #artifact-on-failure: true test-tutorials: needs: build-centos8 uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: centos:8 cmd: scripts/tests/run_tutorials.sh artifact-in: build-centos8 test-mpi-tutorials: needs: build-rocky8-oidn-mpi uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 cmd: | module load cmake/3.15.2 module load mpi/mpich-x86_64 scripts/tests/run_tutorials.sh TEST_MPI artifact-in: build-rocky8-oidn-mpi sanitize-cpu: needs: build-linux-debug uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: archlinux:latest cmd: | export PATH=$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build/install/embree/lib:$GITHUB_WORKSPACE/build/install/ospray/lib:$LD_LIBRARY_PATH export TBB_ENABLE_SANITIZERS=1 scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX artifact-in: build-linux-debug sanitize-bench: needs: build-linux-debug uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: archlinux:latest cmd: | export PATH=$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build/install/embree/lib:$GITHUB_WORKSPACE/build/install/ospray/lib:$LD_LIBRARY_PATH export TBB_ENABLE_SANITIZERS=1 build/install/ospray/bin/ospBenchmark --benchmark_min_time=0s artifact-in: build-linux-debug sanitize-mpi: needs: build-linux-debug uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: archlinux:latest cmd: | export PATH=$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build/install/embree/lib:$GITHUB_WORKSPACE/build/install/ospray/lib:$LD_LIBRARY_PATH export TBB_ENABLE_SANITIZERS=1 OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX SKIP_CPU TEST_MPI artifact-in: build-linux-debug RenderKit-ospray-85af292/.github/workflows/ci.macos.yml000066400000000000000000000063461464752671100231200ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: CI MacOS on: push: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### build-osx-clang: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main secrets: inherit with: runs-on: '["x86_64", "build"]' cmd: | scripts/build/macosx.sh -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-osx-clang artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-osx-arm: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main secrets: inherit with: runs-on: '["arm", "build"]' cmd: | scripts/build/macosx.sh -DBUILD_TBB_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON artifact-out: build-osx-arm artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt build-osx-x64-on-arm: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main secrets: inherit with: runs-on: '["arm", "build"]' cmd: | scripts/build/macosx.sh -DCMAKE_TOOLCHAIN_FILE=../scripts/superbuild/toolchains/macos-rosetta.cmake -DBUILD_TBB_FROM_SOURCE=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN_FROM_SOURCE=ON -DBUILD_ISA_AVX=OFF -DBUILD_ISA_AVX2=OFF -DBUILD_ISA_AVX512=OFF artifact-out: build-osx-x64 artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt ### TEST JOBS ### test-osx-clang: needs: build-osx-clang uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["x86_64", "avx2", "build"]' cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX2 TEST_MULTIDEVICE artifact-in: build-osx-clang artifact-out: test-osx-clang artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-osx-arm: needs: build-osx-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["arm", "build"]' cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-osx-arm artifact-out: test-osx-arm artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-osx-x64-on-arm: needs: build-osx-x64-on-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["arm", "build"]' cmd: | export PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-osx-x64 artifact-out: test-osx-x64 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true RenderKit-ospray-85af292/.github/workflows/ci.windows.gpu.yml000066400000000000000000000115231464752671100242730ustar00rootroot00000000000000## Copyright 2023 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: CI Windows GPU on: push: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### dpcpp-build: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: runs-on: '["build", "mpi"]' env-from-files: .github/workflows/dpcpp.env cmd: | $env:SYCL_BUNDLE_ROOT = $env:DPCPP_ROOT # disable warnings which lead to excessively large log files $env:CXXFLAGS = '-w' $env:CFLAGS = '-w' scripts\build\win.ps1 -G Ninja -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER=clang-cl -DBUILD_GPU_SUPPORT=ON -DBUILD_OSPRAY_MODULE_MPI=ON artifact-out: build-windows-dpcpp artifact-path: build/install/ospray build/CMakeCache.txt build/ospray/build/CMakeCache.txt icx-build: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: runs-on: '["build", "mpi"]' env-from-files: .github/workflows/icx-windows.env ocloc-version: 77a13ae6-6100-4ddc-b069-0086ff44730c/ocloc_win_101.5082 cmd: | # disable warnings which lead to excessively large log files $env:CXXFLAGS = '-w' $env:CFLAGS = '-w' scripts\build\win.ps1 -G Ninja -DCMAKE_CXX_COMPILER=icx -DCMAKE_C_COMPILER=icx -DBUILD_GPU_SUPPORT=ON -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN_FROM_SOURCE=ON artifact-out: build-windows-icx artifact-path: build/install/ospray build/CMakeCache.txt build/ospray/build/CMakeCache.txt ### TEST JOBS ### dpcpp-test: needs: dpcpp-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: timeout-minutes: 100 runs-on: '"dg2"' env-from-files: .github/workflows/gfx-windows.env cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_gpu_tests.ps1 "$env:GITHUB_WORKSPACE" artifact-in: build-windows-dpcpp artifact-out: test-windows-dpcpp artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true mpi-dpcpp-test: needs: dpcpp-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: timeout-minutes: 100 runs-on: '["dg2"]' # FIXME, "mpi" env-from-files: .github/workflows/gfx-windows.env cmd: | $env:Path += ";C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin\utils;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin\release;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin" $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_gpu_tests.ps1 "$env:GITHUB_WORKSPACE" SKIP_GPU TEST_MPI artifact-in: build-windows-dpcpp artifact-out: test-windows-dpcpp-mpi artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true icx-test: needs: icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: timeout-minutes: 100 runs-on: '"dg2"' env-from-files: .github/workflows/icx-windows.env .github/workflows/gfx-windows.env cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_gpu_tests.ps1 "$env:GITHUB_WORKSPACE" artifact-in: build-windows-icx artifact-out: test-windows-icx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true mpi-icx-test: needs: icx-build uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: timeout-minutes: 100 runs-on: '["dg2"]' # FIXME, "mpi" env-from-files: .github/workflows/icx-windows.env .github/workflows/gfx-windows.env cmd: | $env:Path += ";C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin\utils;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin\release;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin" $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_gpu_tests.ps1 "$env:GITHUB_WORKSPACE" SKIP_GPU TEST_MPI artifact-in: build-windows-icx artifact-out: test-windows-icx-mpi artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true RenderKit-ospray-85af292/.github/workflows/ci.windows.yml000066400000000000000000000105241464752671100235010ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: CI Windows on: push: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### build-windows-msvc15: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: cmd: | scripts\build\win.ps1 -G "Visual Studio 15 2017 Win64" artifact-out: build-windows-msvc15 artifact-path: build/install/ospray build/CMakeCache.txt build/ospray/build/CMakeCache.txt build-windows-msvc16-mpi_and_md: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: runs-on: '["build", "mpi"]' cmd: | scripts\build\win.ps1 -G "Visual Studio 16 2019" -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-windows-msvc16-mpi_and_md artifact-path: build/install/ospray build/CMakeCache.txt build/ospray/build/CMakeCache.txt build-windows-msvc17: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: cmd: | scripts\build\win.ps1 -G "Visual Studio 17 2022" artifact-out: build-windows-msvc17 artifact-path: build/install/ospray build/CMakeCache.txt build/ospray/build/CMakeCache.txt ### TEST JOBS ### test-windows-msvc15-avx2: needs: build-windows-msvc15 uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '"avx2"' cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_tests.ps1 "$env:GITHUB_WORKSPACE" AVX2 artifact-in: build-windows-msvc15 artifact-out: test-windows-msvc15-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-windows-msvc15-avx512skx: needs: build-windows-msvc15 uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '"avx512"' cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_tests.ps1 "$env:GITHUB_WORKSPACE" AVX512SKX artifact-in: build-windows-msvc15 artifact-out: test-windows-msvc15-avx512 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-windows-msvc16-avx2: needs: build-windows-msvc16-mpi_and_md uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '["avx2", "mpi"]' cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_tests.ps1 "$env:GITHUB_WORKSPACE" AVX2 TEST_MULTIDEVICE TEST_MPI artifact-in: build-windows-msvc16-mpi_and_md artifact-out: test-windows-msvc16-mpi_and_md-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-windows-msvc16-avx512skx: needs: build-windows-msvc16-mpi_and_md uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '["avx512", "mpi"]' cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" echo $env:Path scripts\tests\run_tests.ps1 "$env:GITHUB_WORKSPACE" AVX512SKX TEST_MULTIDEVICE TEST_MPI artifact-in: build-windows-msvc16-mpi_and_md artifact-out: test-windows-msvc16-mpi_and_md-avx512skx artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true test-windows-msvc17: needs: build-windows-msvc17 uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '"avx512"' cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_tests.ps1 "$env:GITHUB_WORKSPACE" AVX512SKX artifact-in: build-windows-msvc17 artifact-out: test-windows-msvc17-avx512 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true RenderKit-ospray-85af292/.github/workflows/dpcpp.env000066400000000000000000000000571464752671100225120ustar00rootroot00000000000000DPCPP_VERSION=intel-llvm/nightly-2023-10-26-rk RenderKit-ospray-85af292/.github/workflows/gfx-ubuntu22.env000066400000000000000000000000401464752671100236440ustar00rootroot00000000000000GFX_DRIVER_VERSION=linux-latest RenderKit-ospray-85af292/.github/workflows/gfx-windows.env000066400000000000000000000000441464752671100236540ustar00rootroot00000000000000GFX_DRIVER_VERSION=windows-101.5445 RenderKit-ospray-85af292/.github/workflows/icx-linux.env000066400000000000000000000000351464752671100233200ustar00rootroot00000000000000DPCPP_VERSION=intel/2024.1.0 RenderKit-ospray-85af292/.github/workflows/icx-windows.env000066400000000000000000000000451464752671100236540ustar00rootroot00000000000000DPCPP_VERSION=oneAPI/compiler/2024.1 RenderKit-ospray-85af292/.github/workflows/release.yml000066400000000000000000000503401464752671100230350ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: Release on: push: branches: - devel - '**release**' - master workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### DOC JOBS ### pdf: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ospray/docker-images:docu submodules: true cmd: | cd doc git clone --depth 1 -b release-2.12.x https://${RENDERKIT_GITHUB_TOKEN}@github.com/intel-innersource/documentation.graphics.renderkit.ospray-website.git ospray-doc make pdf make checklinks artifact-out: pdf artifact-path: readme.pdf ### BUILD JOBS ### release-linux: needs: pdf uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: rockylinux:8 env-from-files: .github/workflows/dpcpp.env cmd: | module load cmake/3.25.3 module load mpi/mpich-x86_64 export CC=clang export CXX=clang++ scripts/release/linux.sh cp build_release/*.gz $STORAGE_PATH/packages/renderkit/ || true artifact-in: pdf artifact-out: release-linux artifact-path: build_release/*.gz release-linux-arm: needs: pdf uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main secrets: inherit with: runs-on: '[ "Linux", "ARM64" ]' env-from-files: .github/workflows/dpcpp.env cmd: | scripts/release/linux.sh -DBUILD_GLFW=OFF -DBUILD_TBB_FROM_SOURCE=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN_FROM_SOURCE=ON cp build_release/*.gz $STORAGE_PATH/packages/renderkit/ || true artifact-in: pdf artifact-out: release-linux-arm artifact-path: build_release/*.gz release-osx: needs: pdf secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["sign", "x86_64"]' cmd: | export CC=clang export CXX=clang++ scripts/release/macosx.sh cp build_release/*.zip $STORAGE_PATH/packages/renderkit/ || true artifact-in: pdf artifact-out: release-osx artifact-path: build_release/*.zip release-osx-arm: needs: pdf secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["arm", "build"]' cmd: | scripts/release/macosx.sh -DBUILD_TBB_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON cp build_release/*.zip $STORAGE_PATH/packages/renderkit/ || true artifact-in: pdf artifact-out: release-osx-arm artifact-path: build_release/*.zip release-windows: needs: pdf uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: runs-on: '["build", "mpi"]' env-from-files: .github/workflows/dpcpp.env cmd: | $env:SYCL_BUNDLE_ROOT = $env:DPCPP_ROOT # disable warnings which lead to excessively large log files $env:CXXFLAGS = '-w' $env:CFLAGS = '-w' $exitCode = 0 # keep job status to properly fail scripts\release\win.ps1 -G Ninja -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER=clang-cl if ($LastExitCode) { $exitCode++ } & $env:SIGN_FILE_WINDOWS ospray*.msi if ($LastExitCode) { $exitCode++ } cp (Get-ChildItem *.zip | Select-Object -Expand FullName) $env:STORAGE_PATH/packages/renderkit/ cp (Get-ChildItem *.msi | Select-Object -Expand FullName) $env:STORAGE_PATH/packages/renderkit/ exit $exitCode artifact-in: pdf artifact-out: release-windows artifact-path: "build_release/ospray*.zip build_release/ospray*.msi" ### SCAN JOBS ### static-analysis: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/static_analysis.yml@main with: coverity: true project: OSPRay prebuild: > module load impi/latest && echo "Configure dependencies" && cmake -L -S scripts/superbuild -B build_deps -DBUILD_DEPENDENCIES_ONLY=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN_FROM_SOURCE=ON -DBUILD_OSPRAY_MODULE_MPI=ON -DINSTALL_IN_SEPARATE_DIRECTORIES=OFF -DBUILD_ISA_AVX512=OFF && echo "Build dependencies" && cmake --build build_deps && INSTALL_DIR=$(pwd)/build_deps/install && export CMAKE_PREFIX_PATH=${INSTALL_DIR} && echo "Configure OSPRay" && cmake -L -S . -B build -DTBB_ROOT=$INSTALL_DIR -DOSPRAY_MODULE_DENOISER=ON -DOSPRAY_MODULE_BILINEAR_PATCH=ON -DOSPRAY_MODULE_MPI=ON && echo "Done: Configure OSPRay" build: cmake --build build binary-analysis: needs: - release-linux - release-osx - release-windows secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/binary_analysis.yml@main with: project: ospray artifact-in-linux: release-linux artifact-in-macos: release-osx artifact-in-windows: release-windows path: build_release/ospray-* binary-analysis-arm: needs: - release-linux-arm - release-osx-arm secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/binary_analysis.yml@main with: project: ospray artifact-in-linux: release-linux-arm artifact-in-macos: release-osx-arm path: build_release/ospray-* artifact-out-name: binary-analysis-arm antivirus-scan: needs: - release-linux - release-osx - release-windows secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/antivirus_scan.yml@main with: project: ospray artifact-in-linux: release-linux artifact-in-macos: release-osx artifact-in-windows: release-windows path: build_release/ospray-* antivirus-scan-arm: needs: - release-linux-arm - release-osx-arm secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/antivirus_scan.yml@main with: project: ospray artifact-in-linux: release-linux-arm artifact-in-macos: release-osx-arm path: build_release/ospray-* artifact-out-name: antivirus-scan-arm ### TEST JOBS ### test-rocky-cpu: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 cmd: | module load cmake/3.15.2 tar -xzf build_release/*.gz export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX artifact-in: release-linux test-rocky-mpi-cpu: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: rockylinux:8 cmd: | module load cmake/3.15.2 module load mpi/mpich-x86_64 tar -xzf build_release/*.gz export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX SKIP_CPU TEST_MPI artifact-in: release-linux test-ubuntu-oidnsycl: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: timeout-minutes: 100 image: ubuntu:22.04 env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri runs-on: '"dg2"' cmd: | module load cmake/3.15.2 tar -xzf build_release/*.gz export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH export OIDN_DEFAULT_DEVICE=sycl export OIDN_VERBOSE=2 mkdir build_regression_tests cd build_regression_tests cmake -G Ninja -D OSPRAY_TEST_ISA=AVX2 $GITHUB_WORKSPACE/test_image_data cmake --build . --target ospray_test_data ospTestSuite --baseline-dir=regression_test_baseline --gtest_filter="DenoiserOp.DenoiserOp" artifact-in: release-linux test-ubuntu-cpu: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:22.04 cmd: | tar -xzf build_release/*.gz export OIDN_VERBOSE=2 export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX artifact-in: release-linux test-ubuntu-mpi-cpu: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: ubuntu:22.04 cmd: | tar -xzf build_release/*.gz update-alternatives --set mpi-x86_64-linux-gnu /usr/include/x86_64-linux-gnu/mpich update-alternatives --set mpirun /usr/bin/mpirun.mpich OSPDIR=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/) ln -s /usr/lib/x86_64-linux-gnu/libmpich.so.12 $OSPDIR/lib/libmpi.so.12 # XXX find better way ln -s /usr/lib/x86_64-linux-gnu/libmpichcxx.so.12 $OSPDIR/lib/libmpicxx.so.12 export OIDN_VERBOSE=2 export PATH=$OSPDIR/bin:$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX SKIP_CPU TEST_MPI artifact-in: release-linux test-ubuntu-dg2: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: timeout-minutes: 100 image: ubuntu:22.04 runs-on: '"dg2"' env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri cmd: | tar -xzf build_release/*.gz export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_gpu_tests.sh $GITHUB_WORKSPACE artifact-in: release-linux test-ubuntu-mpi-dg2: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: timeout-minutes: 100 image: ubuntu:22.04 runs-on: '"dg2"' env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri cmd: | tar -xzf build_release/*.gz update-alternatives --set mpi-x86_64-linux-gnu /usr/include/x86_64-linux-gnu/mpich update-alternatives --set mpirun /usr/bin/mpirun.mpich OSPDIR=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/) ln -s /usr/lib/x86_64-linux-gnu/libmpich.so.12 $OSPDIR/lib/libmpi.so.12 # XXX find better way ln -s /usr/lib/x86_64-linux-gnu/libmpichcxx.so.12 $OSPDIR/lib/libmpicxx.so.12 export OIDN_VERBOSE=2 export PATH=$OSPDIR/bin:$PATH scripts/tests/run_gpu_tests.sh $GITHUB_WORKSPACE SKIP_GPU TEST_MPI artifact-in: release-linux test-ubuntu-pvc: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: timeout-minutes: 100 image: ubuntu:22.04 runs-on: '"pvc"' env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri cmd: | tar -xzf build_release/*.gz export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_gpu_tests.sh $GITHUB_WORKSPACE artifact-in: release-linux test-ubuntu-mpi-pvc: needs: release-linux uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: timeout-minutes: 100 image: ubuntu:22.04 runs-on: '"pvc"' env-from-files: .github/workflows/gfx-ubuntu22.env options: --device=/dev/dri:/dev/dri cmd: | tar -xzf build_release/*.gz update-alternatives --set mpi-x86_64-linux-gnu /usr/include/x86_64-linux-gnu/mpich update-alternatives --set mpirun /usr/bin/mpirun.mpich OSPDIR=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/) ln -s /usr/lib/x86_64-linux-gnu/libmpich.so.12 $OSPDIR/lib/libmpi.so.12 # XXX find better way ln -s /usr/lib/x86_64-linux-gnu/libmpichcxx.so.12 $OSPDIR/lib/libmpicxx.so.12 export OIDN_VERBOSE=2 export PATH=$OSPDIR/bin:$PATH scripts/tests/run_gpu_tests.sh $GITHUB_WORKSPACE SKIP_GPU TEST_MPI artifact-in: release-linux test-ubuntu-cpu-arm: needs: release-linux-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main with: runs-on: '[ "Linux", "ARM64" ]' cmd: | tar -xzf build_release/*.gz export OIDN_VERBOSE=2 export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX artifact-in: release-linux-arm test-ubuntu-mpi-cpu-arm: needs: release-linux-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main with: runs-on: '[ "Linux", "ARM64" ]' cmd: | tar -xzf build_release/*.gz export OIDN_VERBOSE=2 export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX SKIP_CPU TEST_MPI artifact-in: release-linux-arm test-osx-avx2: needs: release-osx uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["x86_64", "build", "avx2"]' cmd: | unzip build_release/*.zip export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX2 artifact-in: release-osx test-osx-avx512: needs: release-osx uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["x86_64", "build", "avx512"]' cmd: | unzip build_release/*.zip export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX artifact-in: release-osx test-osx-arm: needs: release-osx-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main with: runs-on: '["arm", "build"]' cmd: | unzip build_release/*.zip export PATH=$GITHUB_WORKSPACE/$(ls -d1 ./ospray-*/bin):$PATH scripts/tests/run_tests.sh $GITHUB_WORKSPACE AVX512SKX artifact-in: release-osx-arm test-osx-signing: needs: release-osx uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main secrets: inherit with: runs-on: '["sign", "x86_64" ]' cmd: | unzip build_release/*.zip sign-path-verify: ospray-* artifact-in: release-osx test-osx-signing-arm: needs: release-osx-arm uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main secrets: inherit with: runs-on: '"arm"' cmd: | unzip build_release/*.zip sign-path-verify: ospray-* artifact-in: release-osx-arm test-windows-signing: needs: release-windows uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: cmd: | $exitCode = 0 # keep job status to properly fail Expand-Archive build_release/*.zip -DestinationPath . if ($LastExitCode) { $exitCode++ } $msiFile = (Get-ChildItem build_release/*.msi | Select-Object -Expand FullName) Start-Process msiexec "/a $msiFile /qn TARGETDIR=$env:GITHUB_WORKSPACE" -Wait if ($LastExitCode) { $exitCode++ } & $env:SIGN_FILE_WINDOWS -t build_release\*.msi (Get-ChildItem "Intel\OSPRay*\bin\*" | Select-Object -Expand FullName) (Get-ChildItem "ospray-*\bin\*" | Select-Object -Expand FullName) if ($LastExitCode) { $exitCode++ } exit $exitCode artifact-in: release-windows test-windows-cpu: needs: release-windows uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '"avx512"' cmd: | $exitCode = 0 # keep job status to properly fail Expand-Archive build_release/*.zip -DestinationPath . if ($LastExitCode) { $exitCode++ } $env:Path += ";" + (Get-ChildItem ospray-*\bin | Select-Object -Expand FullName) scripts\tests\run_tests.ps1 $env:GITHUB_WORKSPACE AVX512SKX if ($LastExitCode) { $exitCode++ } exit $exitCode artifact-in: release-windows test-windows-mpi-cpu: needs: release-windows uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '["avx512", "mpi"]' cmd: | $exitCode = 0 # keep job status to properly fail Expand-Archive build_release/*.zip -DestinationPath . if ($LastExitCode) { $exitCode++ } $env:Path += ";" + (Get-ChildItem ospray-*\bin | Select-Object -Expand FullName) scripts\tests\run_tests.ps1 $env:GITHUB_WORKSPACE AVX512SKX SKIP_CPU TEST_MPI if ($LastExitCode) { $exitCode++ } exit $exitCode artifact-in: release-windows test-windows-oidnsycl: needs: release-windows uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: timeout-minutes: 100 runs-on: '"dg2"' env-from-files: .github/workflows/gfx-windows.env cmd: | $exitCode = 0 # keep job status to properly fail Expand-Archive build_release/*.zip -DestinationPath . if ($LastExitCode) { $exitCode++ } $env:Path += ";" + (Get-ChildItem ospray-*\bin | Select-Object -Expand FullName) $env:OIDN_DEFAULT_DEVICE="sycl" $env:OIDN_VERBOSE="2" md build_regression_tests cd build_regression_tests cmake -G Ninja -D OSPRAY_TEST_ISA=AVX2 $env:GITHUB_WORKSPACE\test_image_data if ($LastExitCode) { $exitCode++ } cmake --build . --config Release --target ospray_test_data if ($LastExitCode) { $exitCode++ } ospTestSuite.exe --baseline-dir=regression_test_baseline --gtest_filter="DenoiserOp.DenoiserOp" if ($LastExitCode) { $exitCode++ } exit $exitCode artifact-in: release-windows test-windows-dg2: needs: release-windows uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: timeout-minutes: 100 runs-on: '"dg2"' env-from-files: .github/workflows/gfx-windows.env cmd: | $exitCode = 0 # keep job status to properly fail $env:Path += ";C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin\utils;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin\release;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin" Expand-Archive build_release/*.zip -DestinationPath . if ($LastExitCode) { $exitCode++ } $env:Path += ";" + (Get-ChildItem ospray-*\bin | Select-Object -Expand FullName) scripts\tests\run_gpu_tests.ps1 $env:GITHUB_WORKSPACE if ($LastExitCode) { $exitCode++ } exit $exitCode artifact-in: release-windows test-windows-mpi-dg2: needs: release-windows uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: timeout-minutes: 100 runs-on: '"dg2"' # FIXME: mpi env-from-files: .github/workflows/gfx-windows.env cmd: | $exitCode = 0 # keep job status to properly fail $env:Path += ";C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin\utils;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\libfabric\bin;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin\release;C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin" Expand-Archive build_release/*.zip -DestinationPath . if ($LastExitCode) { $exitCode++ } $env:Path += ";" + (Get-ChildItem ospray-*\bin | Select-Object -Expand FullName) scripts\tests\run_gpu_tests.ps1 $env:GITHUB_WORKSPACE SKIP_GPU TEST_MPI if ($LastExitCode) { $exitCode++ } exit $exitCode artifact-in: release-windows RenderKit-ospray-85af292/.github/workflows/scheduled.yml000066400000000000000000000103041464752671100233510ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: Scheduled on: schedule: - cron: '30 0 * * *' workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all jobs: ### BUILD JOBS ### build-arch-clang-devel: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: archlinux:latest cmd: | export CC=clang export CXX=clang++ scripts/build/linux.sh -G Ninja -DBUILD_GLFW=OFF -DBUILD_OSPRAY_CI_EXTRAS=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DEMBREE_VERSION=devel -DBUILD_OIDN_FROM_SOURCE=ON -DOIDN_VERSION=devel -DOPENVKL_VERSION=devel -DRKCOMMON_VERSION=devel build-linux-debug-all: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main secrets: inherit with: image: archlinux:latest cmd: | export CC=clang export CXX=clang++ scripts/build/linux.sh -G Ninja -DCMAKE_BUILD_TYPE=Debug -DDEPENDENCIES_BUILD_TYPE=Debug -DBUILD_GLFW=OFF -DBUILD_OSPRAY_CI_EXTRAS=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_OIDN=OFF -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-linux-debug-all artifact-path: build/install/ospray build/CMakeCache.txt build/*/build/CMakeCache.txt # build-mpi-cluster: # with: # runs-on: '["Cluster", "build"]' # script: # - module load cmake # - module load impi # - module load gnu # - scripts/build/linux.sh -DBUILD_OSPRAY_MODULE_MPI=ON -DOSPRAY_BUILD_GLM=OFF -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON # <<: *build_artifacts build-windows-debug-all: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: runs-on: '["build", "NAS", "mpi"]' cmd: | scripts\build\win.ps1 -G "Visual Studio 17 2022" -buildType Debug -DBUILD_OSPRAY_CI_EXTRAS=ON -DBUILD_EMBREE_FROM_SOURCE=ON -DBUILD_OPENVKL_FROM_SOURCE=ON -DBUILD_ISA_AVX512=OFF -DBUILD_OIDN=OFF -DBUILD_OSPRAY_MODULE_MPI=ON -DBUILD_OSPRAY_MODULE_MULTIDEVICE=ON artifact-out: build-windows-debug-all artifact-path: build/install/ospray build/CMakeCache.txt build/ospray/build/CMakeCache.txt build-windows-no-volume: uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main secrets: inherit with: cmd: | scripts\build\win.ps1 -G "Visual Studio 17 2022" -DBUILD_ISA_AVX=OFF -DOSPRAY_BUILD_ISA=AVX2 -DBUILD_OPENVKL=OFF ### TEST JOBS ### test-linux-debug-all: needs: build-linux-debug-all uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: archlinux:latest runs-on: '"avx512"' cmd: | PATH="$GITHUB_WORKSPACE/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$GITHUB_WORKSPACE" AVX512SKX artifact-in: build-linux-debug-all artifact-out: test-linux-debug-all artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true # test-mpi-cluster: # <<: *test_job_unix_avx512skx # tags: [cluster] # script: # - module load impi # - module load gnu # - LD_LIBRARY_PATH="$CI_PROJECT_DIR/build/install/ospray/lib:$LD_LIBRARY_PATH" PATH="$CI_PROJECT_DIR/build/install/ospray/bin:$PATH" scripts/tests/run_tests.sh "$CI_PROJECT_DIR" AVX512SKX TEST_MPI TEST_MULTIDEVICE # env: # needs: build-mpi-cluster # needs: ${{ env.needs }} test-windows-debug-all: needs: build-windows-debug-all uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '"avx2"' cmd: | $env:Path += ";$env:GITHUB_WORKSPACE\build\install\ospray\bin" scripts\tests\run_tests.ps1 "$env:GITHUB_WORKSPACE" AVX2 artifact-in: build-windows-debug-all artifact-out: test-windows-debug-all-avx2 artifact-path: build_regression_tests/tests*.xml build_regression_tests/failed* artifact-on-failure: true RenderKit-ospray-85af292/.gitignore000066400000000000000000000006301464752671100172620ustar00rootroot00000000000000*~ *# bin *.user* /build* install* *.sw? tags .ycm_extra_conf.pyc *.autosave *DS_Store* *.gz *.rpm *.zip *.bak *.patch .vscode deps tbb embree ispc ./ospray-doc readme.pdf !/modules /modules/* !/modules/cpu !/modules/denoiser !/modules/mpi !/modules/multiDevice !/modules/pluggableGeometryExample !/modules/simdGeometryExample *.vim .idea/ premake.local.* cmake-build*/ .clangd compile_commands.json .cache/ RenderKit-ospray-85af292/.gitmodules000066400000000000000000000000001464752671100174360ustar00rootroot00000000000000RenderKit-ospray-85af292/CHANGELOG.md000066400000000000000000002027631464752671100171160ustar00rootroot00000000000000Version History --------------- ### Changes in v3.2.0: - Sampling improvements: - Better performance (lower rendering time and faster convergence) - More pleasing blue noise enabled when the total number of frames to be accumulated is known in advance and set as the `targetFrames` parameter at the framebuffer - Note a maximum of 64k samples is supported - Improved `denoiser` image operation: - User-controlled quality levels via parameter `quality` - Optionally denoise alpha channel as well, enabled via parameter `denoiseAlpha` - Support half-precision (16\ bit float) texture formats `OSP_TEXTURE_[RGBA16F|RGB16F|RA16F|R16F]` and two-channel 32\ bit float textures `OSP_TEXTURE_RA32F` - New parameter `limitIndirectLightSamples` for the `pathtracer` which limits the number of light samples after the first non-specular (i.e., diffuse and glossy) bounce to at most one - Implement MIP Mapping for better texture filtering. If the additional memory per texture needed cannot be spared, applications can disable the generation of MIP maps with device parameter `disableMipMapGeneration` - The backplate (background texture) is now always sampled at the pixel center and thus not blurred by the pixel filter anymore - Avoid color bleeding across eye-subimages when stereo rendering - Superbuild uses binary packages of Open VKL - Removed Intel ISPCRT dependency (ISPC compiler is still needed): - oneAPI Level Zero Loader is no longer necessary - `zeContext` and `zeDevice`device parameters are no longer supported - `ispcrtContext` and `ispcrtDevice`device parameters are no longer supported - Clarify the size of `OSP_BOOL` to be 1 byte - Fix artifacts occasionally appearing with `gpu` device - The new minimum versions of dependencies: - Embree v4.3.3 (better error reporting) - Open Image Denoise v2.3 (better image quality with `HIGH` quality mode, added `FAST` quality mode) - rkcommon v1.14.0 ### Changes in v3.1.0: - Principled and Luminous materials support emissive textures - Add native support for disc and oriented disc geometry - Add support for mirror repeat and clamp to edge texture wrap modes - GPU device now also supports motion blur - Improve noise in reflections of ThinGlass - Improve adaptive accumulation: working with GPU, fix correlations - Fix indirectly seen albedo and normal buffer - Fix artifacts when using specular texture for Principled - Fixes for PixelFilter - Parameter was ignored (always using the default Gaussian) - Avoid a shift/misalignment within the pixel for first sample - Fix empty image on Windows when `focusDistance=0` - Fix missing SDK headers for `ISPCDevice*` - The new minimum versions of dependencies: - Embree v4.3.1 - Open VKL v2.0.1 - Open Image Denoise v2.2 (better quality with fine details, support AArch64 CPU on Linux) - ISPCRT v1.23.0 (uses environment variable `ISPCRT_GPU_DRIVER` to select GPU to run on when multiple (i)GPUs are present) - rkcommon v1.13.0 (fixes crash using GPU and emissive geometry) ### Changes in v3.0.0: - Beta support for Intel Xe GPUs (Intel Arcâ„¢ GPUs a Intel Data Center GPU Flex and Max Series), exploiting ray tracing hardware support. Implementation is based on the [SYCL](https://www.khronos.org/sycl/) cross-platform programming language implemented by [Intel oneAPI Data Parallel C++ (DPC++)](https://www.intel.com/content/www/us/en/developer/tools/oneapi/data-parallel-c-plus-plus.html). Note that the following features are not implemented yet or are not working correctly on the new `gpu` device: - Multiple volumes in the scene - Clipping - Motion blur - Subdivision surfaces - Progress reporting via `ospGetProgress` or canceling the frame via `ospCancel` - Picking via `ospPick` - Adaptive accumulation via `OSP_FB_VARIANCE` and `varianceThreshold` - Framebuffer channels `OSP_FB_ID_*` (id buffers) - Experimental support for shared device-only data, works only for `structuredRegular` volume - Further known issues - Some delay on start-up or when changing the scene, because kernel code is JIT compiled and specialized. JIT compilation can be cached by setting environment variable `SYCL_CACHE_PERSISTENT=1`, then consecutive starts or rendering the same scene configuration is without delay - For some combination of compiler, GPU driver and scene the rendered images might show artifacts (e.g., vertical lines or small blocks) - Multidevice does not support `OSPImageOperation`s for denoising or tone mapping - Add implicit indexing for `mesh` geometry - Add support for transferring ownership of temporary buffers: `ospNewSharedData` accepts an optional deleter callback - Optimizations for MPI module, supported by new integrated performance tracing framework - Optimize `scivis` gradient shading - Main thread does not set FTZ/DAZ anymore for denormals handling - Compute intersection epsilon for Mesh to avoid rendering artifacts due to self-intersection - Fix energy conservation of Pricipled material under certain parameter combinations - Fix `denoiser` to not wipe the alpha channel - Fix crash in HDRI light - Fix link order for Debug build on Windows - The new minimum versions of dependencies: - Embree v4.3.0 - Open VKL v2.0.0 - Open Image Denoise v2.1.0 - ISPC v1.21.1 - rkcommon v1.12.0 - Breaking API changes - Renamed `OSP_TEXTURE_FILTER_BILINEAR` to `OSP_TEXTURE_FILTER_LINEAR ` and `OSP_VOLUME_FILTER_TRI[LINEAR|CUBIC]` to `OSP_VOLUME_FILTER_[LINEAR|CUBIC]` - Most enums now use storage type `uint32` - `gridSpacing` of spherical regular volume defaults to full sphere - Remove deprecated parameters and API calls - error callback signatures without user pointer - first argument of `ospNewMaterial` - module name `ispc`; use `cpu` - `volume` texture and `isosurface` geometry: `volumetricModel`; use `OSPVolume volume` - Transfer function `vec2f valueRange`; use `box1f value` - `hdri` and `sun-sky` lights: `intensityQuantity` `OSP_INTENSITY_QUANTITY_RADIANCE` - `spot` light with `intensityDistribution`: `intensityQuantity` other than `OSP_INTENSITY_QUANTITY_SCALE` ### Changes in v2.12.0: - Support denoising on the GPU with OIDN 2.0, which is the new minimum version. The `denoiser` now uses HDR mode - New parameter `maxScatteringEvents` for the `pathtracer` which limits the number of non-specular (i.e., diffuse and glossy) bounces - Optimized dynamic load balancing for MPI devices - Fix crash when using small image resolution and many MPI ranks - Fix crash in `pathtracer` when `lightSamples > 0` but there are lights in the scene - Fix transparent shadows with too high `minContribution` setting - The new minimum version for ISPC is v1.20.0 - Release binaries on Linux are built on Rocky 8 ### Changes in v2.11.0: - Support single ISPC target on Windows - OSPRay's superbuild can now be provided a CMake toolchain file for cross-compilation - Add support for double pumped NEON instruction on ARM64 - Reduce the memory overhead of the `mpiOffload` device and resolve memory and `MPI_Comm` handle leaks - Support for volume rendering (and thus the dependency to Open VKL) can now be compile-time controlled via CMake variable `OSPRAY_ENABLE_VOLUMES` - OSPRay's MPI modules have been split up and renamed, the `mpiOffload` device is now in the `mpi_offload` module, while the `mpiDistributed` device is now in the `mpi_distributed_cpu` module - Add native support for spheres via Embree, which requires the positions and radius of the spheres to be interleaved in memory; if this is not the case, OSPRay will internally create a copy of the data - Fix `dynamicScene` flag on World and Group to influence BVH quality again: default is now "high", which should improve rendering performance, depending on the scene; and "low" when `dynamicScene` is enabled (improving BVH build performance) - Fix a crash in `pathtracer` when there are no lights - Fix a data corruption bug when setting string parameters for objects in the `mpiOffload` device - Various documentation fixes - OSPRay now has a new dependency, which is ISPC Run Time (ISPCRT) in minimum 1.19.0 version - Adapt to Embree v4.0.0 API changes, which is thus the new minimum version; additionally, the new minimum version for Open VKL is v1.3.2 and for ISPC v1.19.0 - Removed support of MSVC14.0 (Visual Studio 2015) and the second generation Intel Xeon Phi processor (codename Knights Landing) ### Changes in v2.10.0: - Add support for primitive, object, and instance ID buffers as framebuffer channels - Support face-varying attributes for Mesh and Subdivision geometry - Replace CMake variable `OSPRAY_PIXELS_PER_JOB` by `OSPRAY_RENDER_TASK_SIZE`; variance tracking for adaptive accumulation is now per task instead of per tile, allowing for more granular adaptation - OSPRay now requires minimum Open VKL v1.3.0 to bring the following improvements: - VDB volumes added support for contiguous data layouts, which can provide improved performance (`nodesPackedDense`, `nodesPackedTile` parameters) - Particle volumes are more memory efficiency and improved performance - OSPRay now requires minimum ISPC v1.18.0 for Open VKL and to include a fix for parallel dispatch of uniform function pointers - MPI Offload: resolve object life time tracking issue that would result in framebuffer and data info being release too early, leading to a crash - Fix crash with OpenMPI due to argument handling - Fix clipping when rays are parallel to clipping planes - Fix missing SDK headers from CPU and MPI module - Deprecated the `vec2f valueRange` parameter of the `piecewiseLinear` transfer function, use `box1f value` instead ### Changes in v2.9.0: - Add support for multi-segment deformation motion blur for `mesh` geometry - OSPRay now requires minimum Open VKL v1.2.0 to bring the following improvements: - Structured regular volumes support for cell-centered data via the `cellCentered` parameter (vertex-centered remains the default) - Particle volumes ignore particles with zero radius - Add support for dynamic load balancing in MPI Offload device - Support for photometric lights (e.g., IES or EULUMDAT) also for `sphere` and `quad` lights. When setting `intensityDistribution`, other values for `intensityQuantity` than `OSP_INTENSITY_QUANTITY_SCALE` are deprecated - Changed CMake variables for enabling app categories: - `OSPRAY_ENABLE_APPS_BENCHMARK` replaces `OSPRAY_APPS_BENCHMARK` - `OSPRAY_ENABLE_APPS_EXAMPLES` replaces `OSPRAY_APPS_EXAMPLES` - `OSPRAY_ENABLE_APPS_TUTORIALS` replaces `OSPRAY_APPS_TUTORIALS` - `OSPRAY_ENABLE_APPS_TESTING` replaces `OSPRAY_APPS_TESTING` - Improve sampling of quad lights in the `pathtracer` (solid angle instead of area) - Instances can now have the group object rebound via a parameter - Fix leaking framebuffers in the MPI Offload device - Resolve possible race condition in assigning IDs to distributed objects in the MPI device - Move ISPC module to `modules/` folder and renamed the module to `cpu` - Minimum version of rkcommon is 1.9.0, which brings the following improvements: - Add detection of Intel oneAPI DPC++/C++ compiler - Fix memory leak ### 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 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 - 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 - Clarify documentation and error messages ### Changes in v2.7.0: - 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) using the superbuild. Thus, new minimum versions are for ISPC 1.16.0, for Embree 3.13.1 and for rkcommon 1.7.0 - OSPRay now requires minimum Open VKL v1.0.0 to bring the following improvements: - Configurable `background` values for all volume types (default `NaN`), defining region outside the volume domain - Better default sampling rate for scaled VDB volumes, improved robustness - Structured regular volumes now support tricubic filtering and more accurate gradient computations as well as more robust isosurfaces - The multidevice module contains a new OSPRay device implementation that delegates work to any number of subdevices. This is an experimental feature in this release but we invite feedback - SciVis Renderer now ignores normal/albedo/depth hits on surfaces that are fully transmissive (material `d = 0`) - Changed the behavior of background rendering in SciVis renderer to more closely reflect that of the path tracer: Background hits are rendered in background color in the albedo buffer and black in the normal buffer - The SciVis renderer does not compute depth of field (DoF) anymore, as this effect does not align with the SciVis renderer definition and exposed artifacts - Fixed crash on exit when using the MPI device - Fixed rendering of depth buffer in the example application - The first argument to material constructor `ospNewMaterial`, i.e., `renderer_type`, is now deprecated and will be removed in a future release. AO and SciVis renderers still assume "obj" like behavior for all material types - Deprecated the `xfm` parameter of the instance, use `transform` instead - Dependencies Google Benchmark, GoggleTest, and Snappy moved out-of-source to superbuild ExternalProjects ### Changes in v2.6.0: - Added new `intensityQuantity` type `OSP_INTENSITY_QUANTITY_SCALE` for the `hdri` and `sunSky` light source. For the future this is the only supported quantity for these lights, the value `OSP_INTENSITY_QUANTITY_RADIANCE` is deprecated. When `OSP_INTENSITY_QUANTITY_SCALE` is used for `sunSky` the default value of `intensity` is `0.025` to match the old behavior - The MPI module is included in the releases packages. An [MPICH-ABI](https://www.mpich.org/abi/) compatible build is provided for Linux that can be run with the Intel oneAPI HPC Toolki, MPICH, and other MPICH-ABI compatible MPI distributions. The Windows release is built against MPI provided in the Intel oneAPI HPC Toolkit - OSPRay now requires minimum Open VKL v0.13.0 to bring the following improvements: - Support half precision float (fp16) voxel data in structured volumes (regular and spherical) and VDB volume - Supporting tricubic filtering via `VKL_FILTER_TRICUBIC` filter for VDB volume - Fixed artifacts for isosurfaces of unstructured volumes - Performance improvements for isosurfaces when multiple isovalues are selected - Better, adaptive sampling of AMR volumes - The `mpiOffload` and `mpiDistributed` devices now support picking. Picking in the distributed device will return the globally closest object on the rank that owns that object. Other ranks will report no hit - Messages issued from ISPC code use the same reporting path as the C++ code, thus now the whole OSPRay console output can be consistently filtered with log levels - Open VKL and Embree internal errors are now correctly mapped to their corresponding OSPRay errors - Fix behavior of committing the framebuffer in distributed rendering to match that of local rendering ### Changes in v2.5.0: - Add native support for cones or cylinders with curves geometry of type `OSP_DISJOINT`, requiring minimum version 3.12.0 of Embree - Replaced OSPRay's internal implementation of round linear curves by Embree's native implementation. Internal surfaces at joints are now correctly removed, leading to higher quality renderings with transparency, at the cost of intersection performance - SciVis renderer improvements: - Colored transparency, colored shadows - Light sources are visible including HDRI Light environment map - The MPI module is now distributed as part of OSPRay in the modules directory - The socket-based communication layer has been removed - Add `intensityQuantity` parameter to light sources to control the interpretation and conversion of the `intensity` into a radiative quantity - OSPRay now requires minimum Open VKL v0.12.0 to bring the following improvements: - Better default sampling rate for scaled volumes, improving performance - Higher robustness for axis-aligned rays - Removed limit on the number of volumes (both overlapped and separate) that a ray can intersect while rendering. Now it is limited by available memory only. - Move to OIDN v1.3.0 to bring the following improvements: - Improved denoising quality (sharpness of fine details, fewer noisy artifacts) - Slightly improved performance and lower memory consumption - Both geometric and volumetric models can now have their child geometry/volume objects rebound using an object parameter - Fix light leaking artifacts at poles of HDRI (and Sun-Sky) light - Add sRGB conversion to `ospExamples` such that the color of the widget for `backgroundColor` actually matches - Dropping support for MSVC14, new minimum compiler on Windows is MSVC15 (Visual Studio 2017) ### Changes in v2.4.0: - The `pathtracer` optionally allows for alpha blending even if the background is seen through refractive objects like glass, by enabling `backgroundRefraction` - OSPRay now requires minimum Open VKL v0.11.0 to bring the following improvements: - Improved rendering performance of VDB volumes - Added support for configurable iterator depth via the `maxIteratorDepth` parameters for unstructured and particle volumes, improved performance - Added support for filter modes for structured volumes (regular and spherical) - Expose parameter `horizonExtension` of Sun-sky light, which extends the sky dome by stretching the horizon over the lower hemisphere - Optimize handling of geometry lights by the `pathtracer` - The optional `denoiser` image operation now respects frame cancellation, requiring Intel® Open Image Denoise with minimum version 1.2.3 - Fixed normals of (transformed) isosurfaces - Robust calculation of normals of `boxes` geometry - Clipping geometry is now working correctly with `map_maxDepth` renderer parameter - Using materials in a renderer with a mismatched `renderer_type` no longer causes crashes while rendering - Significant improvements have been made to loading performance in the MPI Offload device. Applications which make large numbers of API calls or create many smaller geometries or volumes should see substantial load time improvements. - MPI module compacts strided data arrays on the app rank before sending ### Changes in v2.3.0: - Re-add SciVis renderer features (the previous version is still available as `ao` renderer) - Lights are regarded, and thus the OBJ material terms `ks` and `ns` have effect again - Hard shadows are enabled via the `shadows` parameter - The control of ambient occlusion changed: - The `aoIntensity` parameter is replaced by the combined intensity of ambient lights in the `World` - The effect range is controlled via `aoDistance` - Added support for data arrays with a stride between voxels in volumes - Application thread waiting for finished image via `ospWait` participates in rendering, increasing CPU utilization; via rkcommon v1.5.0 - Added `ospray_cpp` compatibility headers for C++ wrappers to understand rkcommon and glm short vector types - For rkcommon, include `ospray/ospray_cpp/ext/rkcommon.h` - For glm, include `ospray/ospray_cpp/ext/glm.h` - Note in debug builds some compilers will not optimize out type trait definitions. This will require users to manually instantiate the glm definitions in one translation unit within the application using `#define OSPRAY_GLM_DEFINITIONS` before including `ext/glm.h`: see `ospTutorialGLM` as an example - Changed parameters to `volume` texture: it now directly accepts the `volume` and the `transferFunction` - Fixed many memory leaks - Handle `NaN` during volume sampling, which led to bounding boxes being visible for some volumes and settings - Depth is now "accumulated" as well, using the minimum - Fix shading for multiple modes of the `debug` renderer - New minimum ISPC version is 1.14.1 ### Changes in v2.2.0: - Support for texture transformation in SciVis OBJ material - Add transformations for volume textures; volume texture lookups are now with local object coordinates (not world coordinates anymore) - Changed behavior: if solely a texture is given, then the default value of the corresponding parameter is *not* multiplied - Support for better antialiasing using a set of different pixel filters (e.g, box, Gaussian, ...). The size of the pixel filter is defined by the used filter type. Previously OSPRay implicitly used a box filter with a size of 1, for better results the default filter is now `OSP_PIXELFILTER_GAUSS` - Support stereo3d mode for panoramic camera - Add new camera `stereoMode` `OSP_STEREO_TOP_BOTTOM` (with left eye at top half of the image) - Added support for random light sampling to the `pathtracer`, the number of sampled light sources per path vertex is defined by the `lightSamples` parameter - Support ring light by extending spot with `innerRadius` - Fixed nonphysical behavior of the `spot` and `sphere` light sources - for area lights (when `radius > 0`) surfaces close to the light will be darker - the `spot` now has an angular falloff, such that a disk light is a proper lambertian area light, which leads to darker regions perpendicular to its direction (thus barely visible with a typically small `openingAngle`) - Support for Open VKL v0.10.0 and its new sampler object API, thus this is now the required minimum version - Added support for particle and VDB volumes - Move from `ospcommon` to `rkcommon` v1.4.2 - New minimum ISPC version is 1.10.0 - Status and error callbacks now support a user pointer - Enabled C++ wrappers (`ospray_cpp`) to work with non-rkcommon math types - Note that while the C API remains the same, the C++ wrappers will require some application updates to account for these changes - MPI module improved parallelism of framebuffer compression & decompression when collecting the final framebuffer to the head rank. This provides a substantial performance improvement when using just a few ranks or large framebuffers (both in pixel count or channel count). - The MPI module will now default to setting thread affinity off, if no option is selected. This improves thread usage and core assignment of threads in most cases, where no specific options are provided to the MPI runtime. - Fix bug where `ospGetCurrentDevice` would crash if used before `ospInit` - Allow `NULL` handles to be passed to `ospDeviceRetain` and `ospDeviceRelease` - ISPC generated headers containing the exported functions for OSPRay's ISPC types and functions are now distributed with the SDK - Add CarPaint `flakeColor` parameter, defaults to current Aluminium - Fixed Debug build (which were producing different images) - The path tracer now also regards the renderer materialist when creating geometry lights - Fix bug where OSPObject handles where not translated to worker-local pointers when committing an OSPData in the MPIOffloadDevice. - MPI module: Fix handling of `OSP_STRING` parameters ### Changes in v2.1.1: - CarPaint material obeys `coat` weight parameter - Correct depth buffer values with SciVis renderer - Adaptions to Embree v3.10.0 - The Linux binary release finds `ospcommon` again ### Changes in v2.1.0: - New clipping geometries feature that allows clipping any scene (geometry and volumes); all OSPRay geometry types can by used as clipping geometry - Inverted clipping is supported via new `invertNormals` parameter of `GeometricModel` - Currently there is a fixed upper limit (64) of how many clipping geometries can be nested - When clipping with curves geometry (any basis except linear) some rendering artifacts may appear - New plane geometry defined via plane equation and optional bounding box - Sun-sky light based on physical model of HoÅ¡ek-Wilkie - Support for photometric lights (e.g., IES or EULUMDAT) - Add new `ospGetTaskDuration` API call to query execution time of asynchronous tasks - Support for 16bit (unsigned short) textures - Add static `cpp::Device::current` method as a C++ wrapper equivalent to `ospGetCurrentDevice` - Generalized `cpp::Device` parameter setting to match other handle types - Passing `NULL` to `ospRelease` is not reported as error anymore - Fix computation of strides for `OSPData` - Fix transparency in `scivis` renderer - Add missing C++ wrapper for `ospGetVariance` - Proper demonstration of `ospGetVariance` in `ospTutorialAsync` - Fix handling of `--osp:device-params` to process and set all passed arguments first before committing the device, to ensure it is committed in a valid state - Object factory functions are now registered during module initialization via the appropriate `registerType` function - MPI module: Use flush bcasts to allow us to use non-owning views for data transfer. Note that shared `ospData` with strides is currently transmitted as whole - Fix issue with OSPRay ignoring tasking system thread count settings - Fix issue where OSPRay always loaded the ISPC module, even if not required - Fixes for MPI module - Fix member variable type for bcast - Fix incorrect data size computation in `offload` device - Fix large data chunking support for MPI Bcast - OSPRay now requires minimum Open VKL v0.9.0 ### Changes in v2.0.1: - Fix bug where Embree user-defined geometries were not indexed correctly in the scene, which now requires Embree v3.8.0+ - Fix crash when the path tracer encounters geometric models that do not have a material - Fix crash when some path tracer materials generated `NULL` bsdfs - Fix bug where `ospGetBounds` returned incorrect values - Fix missing symbol in denoiser module - Fix missing symbol exports on Windows for all OSPRay built modules - Add the option to specify a single color for geometric models - The `scivis` renderer now respects the opacity component of `color` on geometric models - Fix various inconsistent handling of framebuffer alpha between renderers - `ospGetCurrentDevice` now increments the ref count of the returned `OSPDevice` handle, so applications will need to release the handle when finished by using `ospDeviceRelease` accordingly - Added denoiser to `ospExamples` app - Added `module_mpi` to superbuild (disabled by default) - The superbuild now will emit a CMake error when using any 32-bit CMake generator, as 32-bit builds are not supported ### Changes in v2.0.0: - New major revision of OSPRay brings API breaking improvements over v1.x. See [doc/ospray2_porting_guide.md] for a deeper description of migrating from v1.x to v2.0 and the latest [API documentation](README.md#ospray-api) - `ospRenderFrame` now takes all participating objects as function parameters instead of setting some as renderer params - `ospRenderFrame` is now asynchronous, where the task is managed through a returned `OSPFuture` handle - The hierarchy of objects in a scene are now more granular to aid in scene construction flexibility and reduce potential object duplication - Type-specific parameter setting functions have been consolidated into a single `ospSetParam` API call - C++ wrappers found in `ospray_cpp.h` now automatically track handle lifetimes, therefore applications using them do not need to use `ospRelease` (or the new `ospRetain`) with them: see usage example in `apps/tutorials/ospTutorial.cpp` - Unused parameters are reported as status messages when `logLevel` is at least `warning` (most easily set by enabling OSPRay debug on initialization) - New utility library which adds functions to help with new API migration and reduction of boilerplate code - Use `ospray_util.h` to access these additional functions - All utility functions are implemented in terms of the core API found in `ospray.h`, therefore they are compatible with any device backend - Introduction of new Intel® Open Volume Kernel Library (Open VKL) for greatly enhanced volume sampling and rendering features and performance - Added direct support for Intel® Open Image Denoise as an optional module, which adds a `denoiser` type to `ospNewImageOperation` - OSPRay now requires minimum Embree v3.7.0 - New CMake superbuild available to build both OSPRay's dependencies and OSPRay itself - Found in `scripts/superbuild` - See documentation for more details and example usage - The `ospcommon` library now lives as a stand alone repository and is required to build OSPRay - The MPI module is now a separate repository, which also contains all MPI distributed rendering documentation - Log levels are now controlled with enums and named strings (where applicable) - A new flag was also introduced which turns all `OSP_LOG_WARNING` messages into errors, which are submitted to the error callback instead of the message callback - Any unused parameters an object ignores now emit a warning message - New support for volumes in the `pathtracer` - Several parameters are available for performance/quality trade-offs for both photorealistic and scientific visualization use cases - Simplification of the SciVis renderer - Fixed AO lighting and simple ray marched volume rendering for ease of use and performance - Overlapping volumes are now supported in both the `pathtracer` and `scivis` renderers - New API call for querying the bounds of objects (`OSPWorld`, `OSPInstance`, and `OSPGroup`) - Lights now exist as a parameter to the world instead of the renderer - Removal of `slices` geometry. Instead, any geometry with volume texture can be used for slicing - Introduction of new `boxes` geometry type - Expansion of information returned by `ospPick` - Addition of API to query version information at runtime - Curves now supports both, per vertex varying radii as in `vec4f[] vertex.position_radius` and constant radius for the geometry with `float radius`. It uses `OSP_ROUND` type and `OSP_LINEAR` basis by default to create the connected segments of constant radius. For per vertex varying radii curves it uses Embree curves. - Add new Embree curve type `OSP_CATMULL_ROM` for curves - Minimum required Embree version is now 3.7.0 - Removal of `cylinders` and `streamlines` geometry, use `curves` instead - Triangle mesh and Quad mesh are superseded by the `mesh` geometry - Applications need to use the various error reporting methods to check whether the creation (via `ospNew...`) of objects failed; a returned `NULL` is not a special handle anymore to signify an error - Changed module init methods to facilitate version checking: `extern "C" OSPError ospray_module_init_(int16_t versionMajor, int16_t versionMinor, int16_t versionPatch)` - The `map_backplate` texture is supported in all renderers and does not hide lights in infinity (like the HDRI light) anymore; explicitly make lights in`visible` if this is needed - Changed the computation of variance for adaptive accumulation to be independent of `TILE_SIZE`, thus `varianceThreshold` needs to be adapted if using a different `TILE_SIZE` than default 64 - `OSPGeometricModel` now has the option to index a renderer-global material list that lives on the renderer, allowing scenes to avoid renderer-specific materials - Object type names and parameters all now follow the camel-case convention - New `ospExamples` app which consolidates previous interactive apps into one - New `ospBenchmark` app which implements a runnable benchmark suite - Known issues: - ISPC v1.11.0 and Embree v3.6.0 are both incompatible with OSPRay and should be avoided (OSPRay should catch this during CMake configure) - MPI module - The MPI module is now provided separately from the main OSPRay repository - Users can now extend OSPRay with custom distributed renderers and compositing operations, by extending `ospray::mpi::DistributedRenderer` and the `ospray::mpi::TileOperation`, respectively. See the `ospray::mpi::DistributedRaycastRenderer` for an example to start from. - The MPI Offload device can now communicate over sockets, allowing for remote rendering on clusters in the listen/connect mode - Data and commands are now sent asynchronously to the MPI workers in the Offload device, overlapping better with application work. The number of data copies performed has also been significantly reduced, and should improve load times - The MPI Distributed device will now infer the rank's local data bounds based on the volumes and geometry specified if no bounding boxes are specified - When specifying custom bounds on each rank IDs are no longer required, and ranks sharing data will be determined by finding any specifying the same bounding boxes. This will also be done if no bounds are specified, allowing automatic image and hybrid parallel rendering. - The MPI Distributed device can now be used for image-parallel rendering (e.g., same as offload), where now each application can load data in parallel. See the `ospMPIDistributedTutorialReplicatedData` for an example. ### Changes in v1.8.5: - Fix float precision cornercase (`NaN`s) in sphere light sampling - Fix CMake bug that assumed `.git` was a directory, which is not true when using OSPRay as a git submodule - Fix CMake warning - Fix `DLL_EXPORT` issue with `ospray_testing` helper library on Windows ### Changes in v1.8.4: - Add location of `libospray` to paths searched to find modules ### Changes in v1.8.3: - Fix bug where parameters set by `ospSet1b()` were being ignored - Fix bug in box intersection tests possibly creating `NaN`s - Fix issue with client applications calling `find_package(ospray)` more than once - Fix bug in cylinder intersection when ray and cylinder are perpendicular - Fix rare crash in path tracer / MultiBSDF ### Changes in v1.8.2: - CMake bug fix where external users of OSPRay needed CMake newer than version 3.1 - Fix incorrect propagation of tasking system flags from an OSPRay install - Fix inconsistency between supported environment variables and command line parameters passed to `ospInit()` - Missing variables were `OSPRAY_LOAD_MODULES` and `OSPRAY_DEFAULT_DEVICE` ### Changes in v1.8.1: - CMake bug fix to remove full paths to dependencies in packages ### Changes in v1.8.0: - This will be the last minor revision of OSPRay. Future development effort in the `devel` branch will be dedicated to v2.0 API changes and may break existing v1.x applications. - This will also be the last version of OSPRay to include `ospray_sg` and the Example Viewer. Users which depend on these should instead use the separate OSPRay Studio project, where `ospray_sg` will be migrated. - We will continue to support patch releases of v1.8.x in case of any reported bugs - Refactored CMake to use newer CMake concepts - All targets are now exported in OSPRay installs and can be consumed by client projects with associated includes, libraries, and definitions - OSPRay now requires CMake v3.1 to build - See documentation for more details - Added new minimal tutorial apps to replace the more complex Example Viewer - Added new "`subdivision`" geometry type to support subdivision surfaces - Added support for texture formats `L8`, `LA8` (gamma-encoded luminance), and `RA8` (linear two component). Note that the enum `OSP_TEXTURE_FORMAT_INVALID` changed its value, thus recompilation may be necessary. - Automatic epsilon handling, which removes the "`epsilon`" parameter on all renderers - Normals in framebuffer channel `OSP_FB_NORMAL` are now in world-space - Added support for Intel® Open Image Denoise to the Example Viewer - This same integration will soon be ported to OSPRay Studio - Fixed artifacts for scaled instances of spheres, cylinders and streamlines - Improvements to precision of intersections with cylinders and streamlines - Fixed Quadlight: the emitting side is now indeed in direction `edge1`×`edge2` ### Changes in v1.7.3: - Make sure a "`default`" device can always be created - Fixed `ospNewTexture2D` (completely implementing old behavior) - Cleanup any shared object handles from the OS created from `ospLoadModule()` ### Changes in v1.7.2: - Fixed issue in `mpi_offload` device where `ospRelease` would sometimes not correctly free objects - Fixed issue in `ospray_sg` where structured volumes would not properly release the underlying OSPRay object handles ### Changes in v1.7.1: - Fixed issue where the `Principled` material would sometimes show up incorrectly as black - Fixed issue where some headers were missing from install packages ### Changes in v1.7.0: - Generalized texture interface to support more than classic 2D image textures, thus `OSPTexture2D` and `ospNewTexture2D` are now deprecated, use the new API call `ospNewTexture("texture2d")` instead - Added new `volume` texture type to visualize volume data on arbitrary geometry placed inside the volume - Added new framebuffer channels `OSP_FB_NORMAL` and `OSP_FB_ALBEDO` - Applications can get information about the progress of rendering the current frame, and optionally cancel it, by registering a callback function via `ospSetProgressFunc()` - Lights are not tied to the renderer type, so a new function `ospNewLight3()` was introduced to implement this. Please convert all uses of `ospNewLight()` and/or `ospNewLight2()` to `ospNewLight3()` - Added sheenTint parameter to Principled material - Added baseNormal parameter to Principled material - Added low-discrepancy sampling to path tracer - The `spp` parameter on the renderer no longer supports values less than 1, instead applications should render to a separate, lower resolution framebuffer during interaction to achieve the same behavior ### Changes in v1.6.1: - Many bug fixes - Quad mesh interpolation and sampling - Normal mapping in path tracer materials - Memory corruption with partly emitting mesh lights - Logic for setting thread affinity ### Changes in v1.6.0: - Updated ispc device to use Embree3 (minimum required Embree version is 3.1) - Added new `ospShutdown()` API function to aid in correctness and determinism of OSPRay API cleanup - Added "`Principled`" and "`CarPaint"` materials to the path tracer - Improved flexibility of the tone mapper - Improvements to unstructured volume - Support for wedges (in addition to tets and hexes) - Support for implicit isosurface geometry - Support for cell-centered data (as an alternative to per-vertex data) - Added an option to precompute normals, providing a memory/performance trade-off for applications - Implemented "`quads`" geometry type to handle quads directly - Implemented the ability to set "void" cell values in all volume types: when `NaN` is present as a volume's cell value the volume sample will be ignored by the SciVis renderer - Fixed support for color strides which were not multiples of `sizeof(float)` - Added support for RGBA8 color format to spheres, which can be set by specifying the "`color_format`" parameter as `OSP_UCHAR4`, or passing the "`color`" array through an `OSPData` of type `OSP_UCHAR4`. - Added ability to configure Embree scene flags via `OSPModel` parameters - `ospFreeFrameBuffer()` has been deprecated in favor of using `ospRelease()` to free framebuffer handles - Fixed memory leak caused by incorrect parameter reference counts in ispc device - Fixed occasional crashes in the `mpi_offload` device on shutdown - Various improvements to sample apps and `ospray_sg` - Added new `generator` nodes, allowing the ability to inject programmatically generated scene data (only C++ for now) - Bug fixes and improvements to enhance stability and usability ### Changes in v1.5.0: - Unstructured tetrahedral volume now generalized to also support hexahedral data, now called `unstructured_volume` - New function for creating materials (`ospNewMaterial2()`) which takes the renderer type string, not a renderer instance (the old version is now deprecated) - New `tonemapper` PixelOp for tone mapping final frames - Streamlines now support per-vertex radii and smooth interpolation - `ospray_sg` headers are now installed alongside the SDK - Core OSPRay ispc device now implemented as a module - Devices which implement the public API are no longer required to link the dependencies to core OSPRay (e.g., Embree v2.x) - By default, `ospInit()` will load the ispc module if a device was not created via `--osp:mpi` or `--osp:device:[name]` - MPI devices can now accept an existing world communicator instead of always creating their own - Added ability to control ISPC specific optimization flags via CMake options. See the various `ISPC_FLAGS_*` variables to control which flags get used - Enhancements to sample applications - `ospray_sg` (and thus `ospExampleViewer`/`ospBenchmark`) can now be extended with new scene data importers via modules or the SDK - Updated `ospTutorial` examples to properly call `ospRelease()` - New options in the `ospExampleViewer` GUI to showcase new features (sRGB framebuffers, tone mapping, etc.) - General bug fixes - Fixes to geometries with multiple emissive materials - Improvements to precision of ray-sphere intersections ### Changes in v1.4.3: - Several bug fixes - Fixed potential issue with static initialization order - Correct compiler flags for `Debug` config - Spheres `postIntersect` shading is now 64-bit safer ### Changes in v1.4.2: - Several cleanups and bug fixes - Fixed memory leak where the Embree BVH was never released when an `OSPModel` was released - Fixed a crash when API logging was enabled in certain situations - Fixed a crash in MPI mode when creating lights without a renderer - Fixed an issue with camera lens samples not initialized when `spp` <= 0 - Fixed an issue in `ospExampleViewer` when specifying multiple data files - The C99 tutorial is now indicated as the default; the C++ wrappers do not change the semantics of the API (memory management) so the C99 version should be considered first when learning the API ### Changes in v1.4.1: - Several cleanups and bug fixes - Improved precision of ray intersection with streamlines, spheres, and cylinder geometries - Fixed address overflow in framebuffer, in practice image size is now limited only by available memory - Fixed several deadlocks and race conditions - Fix shadow computation in SciVis renderer, objects behind light sources do not occlude anymore - No more image jittering with MPI rendering when no accumulation buffer is used - Improved path tracer materials - Additionally support RGB `eta`/`k` for Metal - Added Alloy material, a "metal" with textured color - Minimum required Embree version is now v2.15 ### Changes in v1.4.0: - New adaptive mesh refinement (AMR) and unstructured tetrahedral volume types - Dynamic load balancing is now implemented for the `mpi_offload` device - Many improvements and fixes to the available path tracer materials - Specular lobe of OBJMaterial uses Blinn-Phong for more realistic highlights - Metal accepts spectral samples of complex refraction index - ThinGlass behaves consistent to Glass and can texture attenuation color - Added Russian roulette termination to path tracer - SciVis OBJMaterial accepts texture coordinate transformations - Applications can now access depth information in MPI distributed uses of OSPRay (both `mpi_offload` and `mpi_distributed` devices) - Many robustness fixes for both the `mpi_offload` and `mpi_distributed` devices through improvements to the `mpi_common` and `mpi_maml` infrastructure libraries - Major sample app cleanups - `ospray_sg` library is the new basis for building apps, which is a scene graph implementation - Old (unused) libraries have been removed: miniSG, command line, importer, loaders, and scripting - Some removed functionality (such as scripting) may be reintroduced in the new infrastructure later, though most features have remained and have been improved - Optional improved texture loading has been transitioned from ImageMagick to OpenImageIO - Many cleanups, bug fixes, and improvements to `ospray_common` and other support libraries - This will be the last release in which we support MSVC12 (Visual Studio 2013). Future releases will require VS2015 or newer ### Changes in v1.3.1: - Improved robustness of OSPRay CMake `find_package` config - Fixed bugs related to CMake configuration when using the OSPRay SDK from an install - Fixed issue with Embree library when installing with `OSPRAY_INSTALL_DEPENDENCIES` enabled ### Changes in v1.3.0: - New MPI distributed device to support MPI distributed applications using OSPRay collectively for "in-situ" rendering (currently in "alpha") - Enabled via new `mpi_distributed` device type - Currently only supports `raycast` renderer, other renderers will be supported in the future - All API calls are expected to be exactly replicated (object instances and parameters) except scene data (geometries and volumes) - The original MPI device is now called the `mpi_offload` device to differentiate between the two implementations - Support of Intel® AVX-512 for next generation Intel® Xeon® processor (codename Skylake), thus new minimum ISPC version is 1.9.1 - Thread affinity of OSPRay's tasking system can now be controlled via either device parameter `setAffinity`, or command line parameter `osp:setaffinity`, or environment variable `OSPRAY_SET_AFFINITY` - Changed behavior of the background color in the SciVis renderer: `bgColor` now includes alpha and is always blended (no `backgroundEnabled` anymore). To disable the background do not set `bgColor`, or set it to transparent black (0, 0, 0, 0) - Geometries "`spheres`" and "`cylinders`" now support texture coordinates - The GLUT- and Qt-based demo viewer applications have been replaced by an example viewer with minimal dependencies - Building the sample applications now requires GCC 4.9 (previously 4.8) for features used in the C++ standard library; OSPRay itself can still be built with GCC 4.8 - The new example viewer based on `ospray::sg` (called `ospExampleViewerSg`) is the single application we are consolidating to, `ospExampleViewer` will remain only as a deprecated viewer for compatibility with the old `ospGlutViewer` application - Deprecated `ospCreateDevice()`; use `ospNewDevice()` instead - Improved error handling - Various API functions now return an `OSPError` value - `ospDeviceSetStatusFunc()` replaces the deprecated `ospDeviceSetErrorMsgFunc()` - New API functions to query the last error (`ospDeviceGetLastErrorCode()` and `ospDeviceGetLastErrorMsg()`) or to register an error callback with `ospDeviceSetErrorFunc()` - Fixed bug where exceptions could leak to C applications ### Changes in v1.2.1: - Various bug fixes related to MPI distributed rendering, ISPC issues on Windows, and other build related issues ### Changes in v1.2.0: - Added support for volumes with voxelType `short` (16-bit signed integers). Applications need to recompile, because `OSPDataType` has been re-enumerated - Removed SciVis renderer parameter `aoWeight`, the intensity (and now color as well) of AO is controlled via "`ambient`" lights. If `aoSamples` is zero (the default) then ambient lights cause ambient illumination (without occlusion) - New SciVis renderer parameter `aoTransparencyEnabled`, controlling whether object transparency is respected when computing ambient occlusion (disabled by default, as it is considerable slower) - Implement normal mapping for SciVis renderer - Support of emissive (and illuminating) geometries in the path tracer via new material "`Luminous`" - Lights can optionally made invisible by using the new parameter `isVisible` (only relevant for path tracer) - OSPRay Devices are now extendable through modules and the SDK - Devices can be created and set current, creating an alternative method for initializing the API - New API functions for committing parameters on Devices - Removed support for the first generation Intel® Xeon Phiâ„¢ coprocessor (codename Knights Corner) - Other minor improvements, updates, and bug fixes - Updated Embree required version to v2.13.0 for added features and performance - New API function `ospDeviceSetErrorMsgFunc()` to specify a callback for handling message outputs from OSPRay - Added ability to remove user set parameter values with new `ospRemoveParam()` API function - The MPI device is now provided via a module, removing the need for having separately compiled versions of OSPRay with and without MPI - OSPRay build dependencies now only get installed if `OSPRAY_INSTALL_DEPENDENCIES` CMake variable is enabled ### Changes in v1.1.2: - Various bug fixes related to normalization, epsilons and debug messages ### Changes in v1.1.1: - Fixed support of first generation Intel Xeon Phi coprocessor (codename Knights Corner) and the COI device - Fix normalization bug that caused rendering artifacts ### Changes in v1.1.0: - New "scivis" renderer features - Single sided lighting (enabled by default) - Many new volume rendering specific features - Adaptive sampling to help improve the correctness of rendering high-frequency volume data - Pre-integration of transfer function for higher fidelity images - Ambient occlusion - Volumes can cast shadows - Smooth shading in volumes - Single shading point option for accelerated shading - Added preliminary support for adaptive accumulation in the MPI device - Camera specific features - Initial support for stereo rendering with the perspective camera - Option `architectural` in perspective camera, rectifying vertical edges to appear parallel - Rendering a subsection of the full view with `imageStart`/`imageEnd` supported by all cameras - This will be our last release supporting the first generation Intel Xeon Phi coprocessor (codename Knights Corner) - Future major and minor releases will be upgraded to the latest version of Embree, which no longer supports Knights Corner - Depending on user feedback, patch releases are still made to fix bugs - Enhanced output statistics in `ospBenchmark` application - Many fixes to the OSPRay SDK - Improved CMake detection of compile-time enabled features - Now distribute OSPRay configuration and ISPC CMake macros - Improved SDK support on Windows - OSPRay library can now be compiled with `-Wall` and `-Wextra` enabled - Tested with GCC v5.3.1 and Clang v3.8 - Sample applications and modules have not been fixed yet, thus applications which build OSPRay as a CMake subproject should disable them with `-DOSPRAY_ENABLE_APPS=OFF` and `-DOSPRAY_ENABLE_MODULES=OFF` - Minor bug fixes, improvements, and cleanups - Regard shading normal when bump mapping - Fix internal CMake naming inconsistencies in macros - Fix missing API calls in C++ wrapper classes - Fix crashes on MIC - Fix thread count initialization bug with TBB - CMake optimizations for faster configuration times - Enhanced support for scripting in both `ospGlutViewer` and `ospBenchmark` applications ### Changes in v1.0.0: - New OSPRay SDK - OSPRay internal headers are now installed, enabling applications to extend OSPRay from a binary install - CMake macros for OSPRay and ISPC configuration now a part of binary releases - CMake clients use them by calling `include(${OSPRAY_USE_FILE})` in their CMake code after calling `find_package(ospray)` - New OSPRay C++ wrapper classes - These act as a thin layer on top of OSPRay object handles, where multiple wrappers will share the same underlying handle when assigned, copied, or moved - New OSPRay objects are only created when a class instance is explicitly constructed - C++ users are encouraged to use these over the `ospray.h` API - Complete rework of sample applications - New shared code for parsing the `commandline` - Save/load of transfer functions now handled through a separate library which does not depend on Qt - Added `ospCvtParaViewTfcn` utility, which enables `ospVolumeViewer` to load color maps from ParaView - GLUT based sample viewer updates - Rename of `ospModelViewer` to `ospGlutViewer` - GLUT viewer now supports volume rendering - Command mode with preliminary scripting capabilities, enabled by pressing '`:`' key (not available when using Intel C++ Compiler (icc)) - Enhanced support of sample applications on Windows - New minimum ISPC version is 1.9.0 - Support of Intel® AVX-512 for second generation Intel Xeon Phi processor (codename Knights Landing) is now a part of the `OSPRAY_BUILD_ISA` CMake build configuration - Compiling AVX-512 requires icc to be enabled as a build option - Enhanced error messages when `ospLoadModule()` fails - Added `OSP_FB_RGBA32F` support in the `DistributedFrameBuffer` - Updated Glass shader in the path tracer - Many miscellaneous cleanups, bug fixes, and improvements ### Changes in v0.10.1: - Fixed support of first generation Intel Xeon Phi coprocessor (codename Knights Corner) - Restored missing implementation of `ospRemoveVolume()` ### Changes in v0.10.0: - Added new tasking options: `Cilk`, `Internal`, and `Debug` - Provides more ways for OSPRay to interact with calling application tasking systems - `Cilk`: Use Intel® Cilkâ„¢ Plus language extensions (icc only) - `Internal`: Use hand written OSPRay tasking system - `Debug`: All tasks are run in serial (useful for debugging) - In most cases, Intel Threading Building Blocks (Intel `TBB`) remains the fastest option - Added support for adaptive accumulation and stopping - `ospRenderFrame` now returns an estimation of the variance in the rendered image if the framebuffer was created with the `OSP_FB_VARIANCE` channel - If the renderer parameter `varianceThreshold` is set, progressive refinement concentrates on regions of the image with a variance higher than this threshold - Added support for volumes with voxelType `ushort` (16-bit unsigned integers) - `OSPTexture2D` now supports sRGB formats -- actually most images are stored in sRGB. As a consequence the API call `ospNewTexture2D()` needed to change to accept the new `OSPTextureFormat` parameter - Similarly, OSPRay's framebuffer types now also distinguishes between linear and sRGB 8-bit formats. The new types are `OSP_FB_NONE`, `OSP_FB_RGBA8`, `OSP_FB_SRGBA`, and `OSP_FB_RGBA32F` - Changed "scivis" renderer parameter defaults - All shading (AO + shadows) must be explicitly enabled - OSPRay can now use a newer, pre-installed Embree enabled by the new `OSPRAY_USE_EXTERNAL_EMBREE` CMake option - New `ospcommon` library used to separately provide math types and OS abstractions for both OSPRay and sample applications - Removes extra dependencies on internal Embree math types and utility functions - `ospray.h` header is now C99 compatible - Removed loaders module, functionality remains inside of `ospVolumeViewer` - Many miscellaneous cleanups, bug fixes, and improvements - Fixed data distributed volume rendering bugs when using less blocks than workers - Fixes to CMake `find_package()` config - Fix bug in `GhostBlockBrickVolume` when using `double`s - Various robustness changes made in CMake to make it easier to compile OSPRay ### Changes in v0.9.1: - Volume rendering now integrated into the "scivis" renderer - Volumes are rendered in the same way the "dvr" volume renderer renders them - Ambient occlusion works with implicit isosurfaces, with a known visual quality/performance trade-off - Intel Xeon Phi coprocessor (codename Knights Corner) COI device and build infrastructure restored (volume rendering is known to still be broken) - New support for CPack built OSPRay binary redistributable packages - Added support for HDRI lighting in path tracer - Added `ospRemoveVolume()` API call - Added ability to render a subsection of the full view into the entire framebuffer in the perspective camera - Many miscellaneous cleanups, bug fixes, and improvements - The depthbuffer is now correctly populated by in the "scivis" renderer - Updated default renderer to be "ao1" in ospModelViewer - Trianglemesh `postIntersect` shading is now 64-bit safe - Texture2D has been reworked, with many improvements and bug fixes - Fixed bug where MPI device would freeze while rendering frames with Intel TBB - Updates to CMake with better error messages when Intel TBB is missing ### Changes in v0.9.0: The OSPRay v0.9.0 release adds significant new features as well as API changes. - Experimental support for data-distributed MPI-parallel volume rendering - New SciVis-focused renderer ("raytracer" or "scivis") combining functionality of "obj" and "ao" renderers - Ambient occlusion is quite flexible: dynamic number of samples, maximum ray distance, and weight - Updated Embree version to v2.7.1 with native support for Intel AVX-512 for triangle mesh surface rendering on the Intel Xeon Phi processor (codename Knights Landing) - OSPRay now uses C++11 features, requiring up to date compiler and standard library versions (GCC v4.8.0) - Optimization of volume sampling resulting in volume rendering speedups of up to 1.5× - Updates to path tracer - Reworked material system - Added texture transformations and colored transparency in OBJ material - Support for alpha and depth components of framebuffer - Added thinlens camera, i.e., support for depth of field - Tasking system has been updated to use Intel Threading Building Blocks (Intel TBB) - The `ospGet*()` API calls have been deprecated and will be removed in a subsequent release ### Changes in v0.8.3: - Enhancements and optimizations to path tracer - Soft shadows (light sources: sphere, cone, extended spot, quad) - Transparent shadows - Normal mapping (OBJ material) - Volume rendering enhancements - Expanded material support - Support for multiple lights - Support for double precision volumes - Added `ospSampleVolume()` API call to support limited probing of volume values - New features to support compositing externally rendered content with OSPRay-rendered content - Renderers support early ray termination through a maximum depth parameter - New OpenGL utility module to convert between OSPRay and OpenGL depth values - Added panoramic and orthographic camera types - Proper CMake-based installation of OSPRay and CMake `find_package()` support for use in external projects - Experimental Windows support - Deprecated `ospNewTriangleMesh()`; use `ospNewGeometry("triangles")` instead - Bug fixes and cleanups throughout the codebase ### Changes in v0.8.2: - Initial support for Intel AVX-512 and the Intel Xeon Phi processor (codename Knights Landing) - Performance improvements to the volume renderer - Incorporated implicit slices and isosurfaces of volumes as core geometry types - Added support for multiple disjoint volumes to the volume renderer - Improved performance of `ospSetRegion()`, reducing volume load times - Improved large data handling for the `shared_structured_volume` and `block_bricked_volume` volume types - Added support for DDS horizon data to the seismic module - Initial support in the Qt viewer for volume rendering - Updated to ISPC 1.8.2 - Various bug fixes, cleanups and documentation updates throughout the codebase ### Changes in v0.8.1: - The volume renderer and volume viewer can now be run MPI parallel (data replicated) using the `--osp:mpi` command line option - Improved performance of volume grid accelerator generation, reducing load times for large volumes - The volume renderer and volume viewer now properly handle multiple isosurfaces - Added small example tutorial demonstrating how to use OSPRay - Several fixes to support older versions of GCC - Bug fixes to `ospSetRegion()` implementation for arbitrarily shaped regions and setting large volumes in a single call - Bug fix for geometries with invalid bounds; fixes streamline and sphere rendering in some scenes - Fixed bug in depth buffer generation ### Changes in v0.8.0: - Incorporated early version of a new Qt-based viewer to eventually unify (and replace) the existing simpler GLUT-based viewers - Added new path tracing renderer (`ospray/render/pathtracer`), roughly based on the Embree sample path tracer - Added new features to the volume renderer - Gradient shading (lighting) - Implicit isosurfacing - Progressive refinement - Support for regular grids, specified with the `gridOrigin` and `gridSpacing` parameters - New `shared_structured_volume` volume type that allows voxel data to be provided by applications through a shared data buffer - New API call to set (sub-)regions of volume data (`ospSetRegion()`) - Added a subsampling-mode, enabled with a negative `spp` parameter; the first frame after scene changes is rendered with reduced resolution, increasing interactivity - Added multi-target ISA support: OSPRay will now select the appropriate ISA at runtime - Added support for the Stanford SEP file format to the seismic module - Added `--osp:numthreads ` command line option to restrict the number of threads OSPRay creates - Various bug fixes, cleanups and documentation updates throughout the codebase ### Changes in v0.7.2: - Build fixes for older versions of GCC and Clang - Fixed time series support in ospVolumeViewer - Corrected memory management for shared data buffers - Updated to ISPC 1.8.1 - Resolved issue in XML parser RenderKit-ospray-85af292/CMakeLists.txt000066400000000000000000000033361464752671100200400ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.8) ############################################################## # Language setup ############################################################## set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) ############################################################## # Establish project ############################################################## include(cmake/ospray_version.cmake) project(OSPRay VERSION ${OSPRAY_VERSION} LANGUAGES C CXX) ############################################################## # CMake modules and macro files ############################################################## list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${PROJECT_SOURCE_DIR}/cmake/compiler ) include(ispc) include(ospray_macros) include(ospray_options) include(package) if (OSPRAY_INSTALL_DEPENDENCIES) include(ospray_redistribute_deps) endif() ############################################################## # Add library and executable targets ############################################################## ## Main OSPRay library ## add_subdirectory(ospray) ## Modules ## add_subdirectory(modules) ## OSPRay sample apps ## add_subdirectory(apps) ## Regression test images target ## add_subdirectory(test_image_data) ## Clang-format target ## if (OSPRAY_ENABLE_TARGET_CLANGFORMAT) include(clang-format) endif() # Must be last include(CPack) RenderKit-ospray-85af292/LICENSE.txt000066400000000000000000000236371464752671100171310ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. RenderKit-ospray-85af292/README.md000066400000000000000000006724461464752671100165750ustar00rootroot00000000000000OSPRay ====== This is release v3.2.0 of Intel® OSPRay. For changes and new features see the [changelog](CHANGELOG.md). Visit http://www.ospray.org for more information. OSPRay Overview =============== Intel® OSPRay is an **o**pen source, **s**calable, and **p**ortable **ray** tracing engine for high-performance, high-fidelity visualization on Intel Architecture CPUs, Intel Xe GPUs, and ARM64 CPUs. OSPRay is part of the [Intel Rendering Toolkit (Render Kit)](https://software.intel.com/en-us/rendering-framework) and is released under the permissive [Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0). The purpose of OSPRay is to provide an open, powerful, and easy-to-use rendering library that allows one to easily build applications that use ray tracing based rendering for interactive applications (including both surface- and volume-based visualizations). OSPRay runs on anything from laptops, to workstations, to compute nodes in HPC systems. OSPRay internally builds on top of Intel [Embree](https://www.embree.org/), Intel [Open VKL](https://www.openvkl.org/), and Intel [Open Image Denoise](https://openimagedenoise.github.io/). The CPU implementation is based on 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. Hence, a CPU with support for at least SSE4.1 is required to run OSPRay on x86_64 architectures, or a CPU with support for NEON is required to run OSPRay on ARM64 architectures. OSPRay’s GPU implementation (beta status) is based on the [SYCL](https://www.khronos.org/sycl/) cross-platform programming language implemented by [Intel oneAPI Data Parallel C++ (DPC++)](https://www.intel.com/content/www/us/en/developer/tools/oneapi/data-parallel-c-plus-plus.html) and currently supports Intel Arcâ„¢ GPUs on Linux and Windows, and Intel Data Center GPU Flex and Max Series on Linux, exploiting ray tracing hardware support. OSPRay Support and Contact -------------------------- OSPRay is under active development, and though we do our best to guarantee stable release versions a certain number of bugs, as-yet-missing features, inconsistencies, or any other issues are still possible. For any such requests or findings please use [OSPRay’s GitHub Issue Tracker](https://github.com/ospray/OSPRay/issues) (or, if you should happen to have a fix for it, you can also send us a pull request). To receive release announcements simply [“Watch†the OSPRay repository](https://github.com/ospray/OSPRay) on GitHub. Building and Finding OSPRay =========================== The latest OSPRay sources are always available at the [OSPRay GitHub repository](http://github.com/ospray/ospray). The default `master` branch should always point to the latest bugfix release. Prerequisites ------------- OSPRay currently supports Linux, Mac OS X, and Windows. In addition, before you can build OSPRay you need the following prerequisites: - You can clone the latest OSPRay sources via: ``` sh git clone https://github.com/ospray/ospray.git ``` - To build OSPRay you need [CMake](http://www.cmake.org), any form of C++11 compiler (we recommend using GCC, but also support Clang, MSVC, and [Intel® C++ Compiler (icc)](https://software.intel.com/en-us/c-compilers)), and standard Linux development tools. - Additionally you require a copy of the [Intel® Implicit SPMD Program Compiler (ISPC)](http://ispc.github.io), version 1.23.0 or later. Please obtain a release of ISPC from the [ISPC downloads page](https://ispc.github.io/downloads.html). If ISPC is not found by CMake its location can be hinted with the variable `ISPC_EXECUTABLE`. - OSPRay builds on top of the [Intel Rendering Toolkit (Render Kit) common library (rkcommon)](https://www.github.com/ospray/rkcommon). The library provides abstractions for tasking, aligned memory allocation, vector math types, among others. For users who also need to build rkcommon, we recommend the default the Intel [Threading Building Blocks (TBB)](https://www.threadingbuildingblocks.org/) as tasking system for performance and flexibility reasons. TBB must be built from source when targeting ARM CPUs, or can be built from source as part of the [superbuild](#cmake-superbuild). Alternatively you can set CMake variable `RKCOMMON_TASKING_SYSTEM` to `OpenMP` or `Internal`. - OSPRay also heavily uses Intel [Embree](https://www.embree.org/), installing version 4.3.3 or newer is required. If Embree is not found by CMake its location can be hinted with the variable `embree_DIR`. - OSPRay supports volume rendering (enabled by default via `OSPRAY_ENABLE_VOLUMES`), which heavily uses Intel [Open VKL](https://www.openvkl.org/), version 2.0.1 or newer is required. If Open VKL is not found by CMake its location can be hinted with the variable `openvkl_DIR`, or disable `OSPRAY_ENABLE_VOLUMES`. - OSPRay also provides an optional module implementing the `denoiser` image operation, which is enabled by `OSPRAY_MODULE_DENOISER`. This module requires Intel [Open Image Denoise](https://openimagedenoise.github.io/) in version 2.3.0 or newer. You may need to hint the location of the library with the CMake variable `OpenImageDenoise_DIR`. - For the optional MPI modules (enabled by `OSPRAY_MODULE_MPI`), which provide the `mpiOffload` and `mpiDistributed` devices, you need an MPI library and [Google Snappy](https://github.com/google/snappy). - The optional example application, the test suit and benchmarks need some version of OpenGL and GLFW as well as [GoogleTest](https://github.com/google/googletest) and [Google Benchmark](https://github.com/google/benchmark/) Depending on your Linux distribution you can install these dependencies using `yum` or `apt-get`. Some of these packages might already be installed or might have slightly different names. Type the following to install the dependencies using `yum`: ``` sh sudo yum install cmake.x86_64 sudo yum install tbb.x86_64 tbb-devel.x86_64 ``` Type the following to install the dependencies using `apt-get`: ``` sh sudo apt-get install cmake-curses-gui sudo apt-get install libtbb-dev ``` Under Mac OS X these dependencies can be installed using [MacPorts](http://www.macports.org/): ``` sh sudo port install cmake tbb ``` Under Windows please directly use the appropriate installers for [CMake](https://cmake.org/download/), [TBB](https://github.com/oneapi-src/oneTBB/releases), [ISPC](https://ispc.github.io/downloads.html) (for your Visual Studio version) and [Embree](https://github.com/embree/embree/releases/). ### Additional Prerequisites for GPU Build To build OSPRay’s GPU module you need - a SYCL compiler, either the open source [oneAPI DPC++ Compiler 2023-10-26](https://github.com/intel/llvm/releases/tag/nightly-2023-10-26) or the latest [Intel oneAPI DPC++/C++ Compiler](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp) - a recent [CMake](http://www.cmake.org), version 3.25.3 or higher CMake Superbuild ---------------- For convenience, OSPRay provides a CMake Superbuild script which will pull down OSPRay’s dependencies and build OSPRay itself. By default, the result is an install directory, with each dependency in its own directory. Run with: ``` sh mkdir build cd build cmake [/scripts/superbuild] cmake --build . ``` On Windows make sure to select a 64 bit generator, e.g. ``` sh cmake -G "Visual Studio 17 2022" [/scripts/superbuild] ``` The resulting `install` directory (or the one set with `CMAKE_INSTALL_PREFIX`) will have everything in it, with one subdirectory per dependency. CMake options to note (all have sensible defaults): CMAKE_INSTALL_PREFIX will be the root directory where everything gets installed. BUILD_JOBS sets the number given to `make -j` for parallel builds. INSTALL_IN_SEPARATE_DIRECTORIES toggles installation of all libraries in separate or the same directory. BUILD_OPENVKL whether to enable volume rendering via Open VKL BUILD_EMBREE_FROM_SOURCE set to OFF will download a pre-built version of Embree. BUILD_OIDN_FROM_SOURCE set to OFF will download a pre-built version of Open Image Denoise. OIDN_VERSION determines which version of Open Image Denoise to pull down. BUILD_OSPRAY_MODULE_MPI set to ON to build OSPRay’s MPI module for data-replicated and distributed parallel rendering on multiple nodes. BUILD_GPU_SUPPORT enables beta GPU support, fetching the SYCL variants of the dependencies and builds `OSPRAY_MODULE_GPU` BUILD_TBB_FROM_SOURCE set to ON to build TBB from source (required for ARM support). The default setting is OFF. For the full set of options, run: ``` sh ccmake [/scripts/superbuild] ``` or ``` sh cmake-gui [/scripts/superbuild] ``` ### Cross-Compilation with the Superbuild The superbuild can be passed a [CMake Toolchain file](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html) to configure for cross-compilation. This is done by passing the toolchain file when running cmake. When cross compiling it is also likely that you’ll want to build TBB and Embree from source to ensure they’re built for the correct target, rather than the target the Github binaries are built for. It may also be necessary to disable specific ISAs for the target by passing `BUILD_ISA_=OFF` as well. ``` sh mkdir build cd build cmake --toolchain [toolchain_file.cmake] [path/to/this/directory] -DBUILD_TBB_FROM_SOURCE=ON \ -DBUILD_EMBREE_FROM_SOURCE=ON \ ``` While OSPRay supports ARM natively, it may be desirable to cross-compile it for `x86_64` to run in Rosetta depending on the application integrating OSPRay. This can be done using the toolchain file `toolchains/macos-rosetta.cmake`, and by disabling all non-SSE ISAs when building. This can also be done by launching an `x86_64` bash shell and then compiling as usual in this environment, which will cause the compilation chain to target `x86_64`. The `BUILD_ISA_=OFF` flags should be passed to disable all ISAs besides SSE4 for Rosetta: ``` sh arch -x86_64 bash mkdir build cd build cmake [path/to/this/directory] -DBUILD_TBB_FROM_SOURCE=ON \ -DBUILD_EMBREE_FROM_SOURCE=ON \ -DBUILD_ISA_AVX=OFF \ -DBUILD_ISA_AVX2=OFF \ -DBUILD_ISA_AVX512=OFF \ ``` Standard CMake Build -------------------- ### Compiling OSPRay on Linux and Mac OS X Assuming the above requisites are all fulfilled, building OSPRay through CMake is easy: - Create a build directory, and go into it ``` sh mkdir ospray/build cd ospray/build ``` (We do recommend having separate build directories for different configurations such as release, debug, etc.). - The compiler CMake will use will default to whatever the `CC` and `CXX` environment variables point to. Should you want to specify a different compiler, run cmake manually while specifying the desired compiler. The default compiler on most linux machines is `gcc`, but it can be pointed to `clang` instead by executing the following: ``` sh cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. ``` CMake will now use Clang instead of GCC. If you are OK with using the default compiler on your system, then simply skip this step. Note that the compiler variables cannot be changed after the first `cmake` or `ccmake` run. - Open the CMake configuration dialog ``` sh ccmake .. ``` - Make sure to properly set build mode and enable the components you need, etc.; then type ’c’onfigure and ’g’enerate. When back on the command prompt, build it using ``` sh make ``` - You should now have `libospray.[so,dylib]` as well as a set of [example applications](#tutorials). ### Compiling OSPRay on Windows On Windows using the CMake GUI (`cmake-gui.exe`) is the most convenient way to configure OSPRay and to create the Visual Studio solution files: - Browse to the OSPRay sources and specify a build directory (if it does not exist yet CMake will create it). - Click “Configure†and select as generator the Visual Studio version you have; OSPRay needs “Visual Studio 15 2017 Win64†or newer, 32 bit builds are not supported, e.g., “Visual Studio 17 2022â€. - If the configuration fails because some dependencies could not be found then follow the instructions given in the error message, e.g., set the variable `embree_DIR` to the folder where Embree was installed and `openvkl_DIR` to where Open VKL was installed. - Optionally change the default build options, and then click “Generate†to create the solution and project files in the build directory. - Open the generated `OSPRay.sln` in Visual Studio, select the build configuration and compile the project. Alternatively, OSPRay can also be built without any GUI, entirely on the console. In the Visual Studio command prompt type: ``` sh cd path\to\ospray mkdir build cd build cmake -G "Visual Studio 17 2022" [-D VARIABLE=value] .. cmake --build . --config Release ``` Use `-D` to set variables for CMake, e.g., the path to Embree with “`-D embree_DIR=\path\to\embree`â€. You can also build only some projects with the `--target` switch. Additional parameters after “`--`†will be passed to `msbuild`. For example, to build in parallel only the OSPRay library without the example applications use ``` sh cmake --build . --config Release --target ospray -- /m ``` Finding an OSPRay Install with CMake ------------------------------------ Client applications using OSPRay can find it with CMake’s `find_package()` command. For example, ``` sh find_package(ospray 3.0.0 REQUIRED) ``` finds OSPRay via OSPRay’s configuration file `osprayConfig.cmake`[^1]. Once found, the following is all that is required to use OSPRay: ``` sh target_link_libraries(${client_target} ospray::ospray) ``` This will automatically propagate all required include paths, linked libraries, and compiler definitions to the client CMake target (either an executable or library). Advanced users may want to link to additional targets which are exported in OSPRay’s CMake config, which includes all installed modules. All targets built with OSPRay are exported in the `ospray::` namespace, therefore all targets locally used in the OSPRay source tree can be accessed from an install. For example, `ospray_module_cpu` can be consumed directly via the `ospray::ospray_module_cpu` target. All targets have their libraries, includes, and definitions attached to them for public consumption (please [report bugs](#ospray-support-and-contact) if this is broken!). Documentation ============= The following [API documentation](https://www.ospray.org/OSPRay_readme.pdf "OSPRay Documentation") of OSPRay can also be found as a [pdf document](https://www.ospray.org/OSPRay_readme.pdf "OSPRay Documentation"). For a deeper explanation of the concepts, design, features and performance of OSPRay also have a look at the IEEE Vis 2016 paper “[OSPRay – A CPU Ray Tracing Framework for Scientific Visualization](https://www.ospray.org/talks/IEEEVis2016_OSPRay_paper.pdf)†(49MB, or get the [smaller version](https://www.ospray.org/talks/IEEEVis2016_OSPRay_paper_small.pdf) 1.8MB). The [slides of the talk](https://www.ospray.org/talks/IEEEVis2016_OSPRay_talk.pdf) (5.2MB) are also available. OSPRay API ========== To access the OSPRay API you first need to include the OSPRay header ``` cpp #include "ospray/ospray.h" ``` where the API is compatible with C99 and C++. Initialization and Shutdown --------------------------- To use the API, OSPRay must be initialized with a “deviceâ€. A device is the object which implements the API. Creating and initializing a device can be done in either of two ways: command line arguments using `ospInit` or manually instantiating a device and setting parameters on it. ### Command Line Arguments The first is to do so by giving OSPRay the command line from `main()` by calling ``` cpp OSPError ospInit(int *argc, const char **argv); ``` OSPRay parses (and removes) its known command line parameters from your application’s `main` function. For an example see the [tutorial](#osptutorial). For possible error codes see section [Error Handling and Status Messages](#error-handling-and-status-messages). It is important to note that the arguments passed to `ospInit` are processed in order they are listed. The following parameters (which are prefixed by convention with “`--osp:`â€) are understood: | Parameter | Description | |:--------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `--osp:debug` | enables various extra checks and debug output, and disables multi-threading | | `--osp:num-threads=` | use `n` threads instead of per default using all detected hardware threads | | `--osp:log-level=` | set logging level; valid values (in order of severity) are `none`, `error`, `warning`, `info`, and `debug` | | `--osp:warn-as-error` | send `warning` and `error` messages through the error callback, otherwise send `warning` messages through the message callback; must have sufficient `logLevel` to enable warnings | | `--osp:verbose` | shortcut for `--osp:log-level=info` and enable debug output on `cout`, error output on `cerr` | | `--osp:vv` | shortcut for `--osp:log-level=debug` and enable debug output on `cout`, error output on `cerr` | | `--osp:load-modules=[,...]` | load one or more modules during initialization; equivalent to calling `ospLoadModule(name)` | | `--osp:log-output=` | convenience for setting where status messages go; valid values for `dst` are `cerr` and `cout` | | `--osp:error-output=` | convenience for setting where error messages go; valid values for `dst` are `cerr` and `cout` | | `--osp:device=` | use `name` as the type of device for OSPRay to create; e.g., `--osp:device=cpu` gives you the default `cpu` device; Note if the device to be used is defined in a module, remember to pass `--osp:load-modules=` first | | `--osp:set-affinity=` | if `1`, bind software threads to hardware threads; `0` disables binding; default is `0` | | `--osp:device-params=:[,...]` | set one or more other device parameters; equivalent to calling `ospDeviceSet*(param, value)` | Command line parameters accepted by OSPRay’s `ospInit`. ### Manual Device Instantiation The second method of initialization is to explicitly create the device and possibly set parameters. This method looks almost identical to how other [objects](#objects) are created and used by OSPRay (described in later sections). The first step is to create the device with ``` cpp OSPDevice ospNewDevice(const char *type); ``` where the `type` string maps to a specific device implementation. OSPRay always provides the “`cpu`†device, which maps to a fast, local CPU implementation. Other devices can also be added through additional modules, such as distributed MPI device implementations. See next Chapter for details. Once a device is created, you can call ``` cpp void ospDeviceSetParam(OSPObject, const char *id, OSPDataType type, const void *mem); ``` to set parameters on the device. The semantics of setting parameters is exactly the same as `ospSetParam`, which is documented below in the [parameters](#parameters) section. The following parameters can be set on all devices: | Type | Name | Description | |:-------|:------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | int | numThreads | number of threads which OSPRay should use | | bool | disableMipMapGeneration | disable the default generation of MIP maps for textures (e.g., to save the additional memory needed) | | uint | logLevel | logging level; valid values (in order of severity) are `OSP_LOG_NONE`, `OSP_LOG_ERROR`, `OSP_LOG_WARNING`, `OSP_LOG_INFO`, and `OSP_LOG_DEBUG` | | string | logOutput | convenience for setting where status messages go; valid values are `cerr` and `cout` | | string | errorOutput | convenience for setting where error messages go; valid values are `cerr` and `cout` | | bool | debug | set debug mode; equivalent to `logLevel=debug` and `numThreads=1` | | bool | warnAsError | send `warning` and `error` messages through the error callback, otherwise send `warning` messages through the message callback; must have sufficient `logLevel` to enable warnings | | bool | setAffinity | bind software threads to hardware threads if set to 1; 0 disables binding omitting the parameter will let OSPRay choose | Parameters shared by all devices. Once parameters are set on the created device, the device must be committed with ``` cpp void ospDeviceCommit(OSPDevice); ``` To use the newly committed device, you must call ``` cpp void ospSetCurrentDevice(OSPDevice); ``` This then sets the given device as the object which will respond to all other OSPRay API calls. Device handle lifetimes are managed with two calls, the first which increments the internal reference count to the given `OSPDevice` ``` cpp void ospDeviceRetain(OSPDevice) ``` and the second which decrements the reference count ``` cpp void ospDeviceRelease(OSPDevice) ``` Users can change parameters on the device after initialization (from either method above), by calling ``` cpp OSPDevice ospGetCurrentDevice(); ``` This function returns the handle to the device currently used to respond to OSPRay API calls, where users can set/change parameters and recommit the device. If changes are made to the device that is already set as the current device, it does not need to be set as current again. Note this API call will increment the ref count of the returned device handle, so applications must use `ospDeviceRelease` when finished using the handle to avoid leaking the underlying device object. If there is no current device set, this will return an invalid `NULL` handle. When a device is created, its reference count is initially `1`. When a device is set as the current device, it internally has its reference count incremented. Note that `ospDeviceRetain` and `ospDeviceRelease` should only be used with reference counts that the application tracks: removing reference held by the current set device should be handled by `ospShutdown`. Thus, `ospDeviceRelease` should only decrement the reference counts that come from `ospNewDevice`, `ospGetCurrentDevice`, and the number of explicit calls to `ospDeviceRetain`. OSPRay allows applications to query runtime properties of a device in order to do enhanced validation of what device was loaded at runtime. The following function can be used to get these device-specific properties (attributes about the device, not parameter values) ``` cpp int64_t ospDeviceGetProperty(OSPDevice, OSPDeviceProperty); ``` It returns an integer value of the queried property and the following properties can be provided as parameter: ``` cpp OSP_DEVICE_VERSION OSP_DEVICE_VERSION_MAJOR OSP_DEVICE_VERSION_MINOR OSP_DEVICE_VERSION_PATCH OSP_DEVICE_SO_VERSION ``` ### Environment Variables OSPRay’s generic device parameters can be overridden via environment variables for easy changes to OSPRay’s behavior without needing to change the application (variables are prefixed by convention with “`OSPRAY_`â€): | Variable | Description | |:---------------------|:-----------------------------------------------------------------------------------------------------------| | OSPRAY_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. Note that these environment variables take precedence over values specified through `ospInit` or manually set device parameters. ### Error Handling and Status Messages 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 | Possible error codes, i.e., valid named constants of type `OSPError`. These error codes are either directly return by some API functions, or are recorded to be later queried by the application via ``` cpp OSPError ospDeviceGetLastErrorCode(OSPDevice); ``` A more descriptive error message can be queried by calling ``` cpp const char* ospDeviceGetLastErrorMsg(OSPDevice); ``` Alternatively, the application can also register a callback function of type ``` cpp typedef void (*OSPErrorCallback)(void *userData, OSPError, const char* errorDetails); ``` via ``` cpp void ospDeviceSetErrorCallback(OSPDevice, OSPErrorCallback, void *userData); ``` to get notified when errors occur. Applications may be interested in messages which OSPRay emits, whether for debugging or logging events. Applications can call ``` cpp void ospDeviceSetStatusCallback(OSPDevice, OSPStatusCallback, void *userData); ``` in order to register a callback function of type ``` cpp typedef void (*OSPStatusCallback)(void *userData, const char* messageText); ``` which OSPRay will use to emit status messages. By default, OSPRay uses a callback which does nothing, so any output desired by an application will require that a callback is provided. Note that callbacks for C++ `std::cout` and `std::cerr` can be alternatively set through `ospInit` or the `OSPRAY_LOG_OUTPUT` environment variable. Applications can clear either callback by passing `NULL` instead of an actual function pointer. ### Loading OSPRay Extensions at Runtime OSPRay’s functionality can be extended via plugins (which we call “modulesâ€), which are implemented in shared libraries. To load module `name` from `libospray_module_.so` (on Linux and Mac OS X) or `ospray_module_.dll` (on Windows) use ``` cpp OSPError ospLoadModule(const char *name); ``` Modules are searched in OS-dependent paths. `ospLoadModule` returns `OSP_NO_ERROR` if the plugin could be successfully loaded. ### Shutting Down OSPRay When the application is finished using OSPRay (typically on application exit), the OSPRay API should be finalized with ``` cpp void ospShutdown(); ``` This API call ensures that the current device is cleaned up appropriately. Due to static object allocation having non-deterministic ordering, it is recommended that applications call `ospShutdown` before the calling application process terminates. Objects ------- All entities of OSPRay (the [renderer](#renderers), [volumes](#volumes), [geometries](#geometries), [lights](#lights), [cameras](#cameras), …) are a logical specialization of `OSPObject` and share common mechanism to deal with parameters and lifetime. An important aspect of object parameters is that parameters do not get passed to objects immediately. Instead, parameters are not visible at all to objects until they get explicitly committed to a given object via a call to ``` cpp void ospCommit(OSPObject); ``` at which time all previously additions or changes to parameters are visible at the same time. If a user wants to change the state of an existing object (e.g., to change the origin of an already existing camera) it is perfectly valid to do so, as long as the changed parameters are recommitted. The commit semantic allow for batching up multiple small changes, and specifies exactly when changes to objects will occur. This can impact performance and consistency for devices crossing a PCI bus or across a network. Note that OSPRay uses reference counting to manage the lifetime of all objects, so one cannot explicitly “delete†any object. Instead, to indicate that the application does not need and does not access the given object anymore, call ``` cpp void ospRelease(OSPObject); ``` This decreases its reference count and if the count reaches `0` the object will automatically get deleted. Passing `NULL` is not an error. Note that every handle returned via the API needs to be released when the object is no longer needed, to avoid memory leaks. Sometimes applications may want to have more than one reference to an object, where it is desirable for the application to increment the reference count of an object. This is done with ``` cpp void ospRetain(OSPObject); ``` It is important to note that this is only necessary if the application wants to call `ospRelease` on an object more than once: objects which contain other objects as parameters internally increment/decrement ref counts and should not be explicitly done by the application. ### Parameters Parameters allow to configure the behavior of and to pass data to objects. However, objects do *not* have an explicit interface for reasons of high flexibility and a more stable compile-time API. Instead, parameters are passed separately to objects in an arbitrary order, and unknown parameters will simply be ignored (though a warning message will be posted). The following function allows adding various types of parameters with name `id` to a given object: ``` cpp void ospSetParam(OSPObject, const char *id, OSPDataType type, const void *mem); ``` The valid parameter names for all `OSPObject`s and what types are valid are discussed in future sections. Note that `mem` must always be a pointer *to* the object, otherwise accidental type casting can occur. This is especially true for pointer types (`OSP_VOID_PTR` and `OSPObject` handles), as they will implicitly cast to `void *`, but be incorrectly interpreted. To help with some of these issues, there also exist variants of `ospSetParam` for specific types, such as `ospSetInt` and `ospSetVec3f` in the OSPRay utility library (found in `ospray_util.h`). Note that half precision float parameters `OSP_HALF, OSP_VEC[234]H` are not supported. Users can also remove parameters that have been explicitly set from `ospSetParam`. Any parameters which have been removed will go back to their default value during the next commit unless a new parameter was set after the parameter was removed. To remove a parameter, use ``` cpp void ospRemoveParam(OSPObject, const char *id); ``` ### Data OSPRay consumes data arrays from the application using a specific object type, `OSPData`. There are several components to describing a data array: element type, 1/2/3 dimensional striding, and whether the array is shared with the application or copied into opaque, OSPRay-owned memory. Shared data arrays require that the application’s array memory outlives the lifetime of the created `OSPData`, as OSPRay is referring to application memory. Where this is not preferable, applications use opaque arrays to allow the `OSPData` to own the lifetime of the array memory. However, opaque arrays dictate the cost of copying data into it, which should be kept in mind. Thus, the most efficient way to specify a data array from the application is to created a shared data array, which is done with ``` cpp OSPData ospNewSharedData(const void *sharedData, OSPDataType, uint64_t numItems1, int64_t byteStride1 = 0, uint64_t numItems2 = 1, int64_t byteStride2 = 0, uint64_t numItems3 = 1, int64_t byteStride3 = 0, OSPDeleterCallback = NULL, void *userData = NULL); ``` The call returns an `OSPData` handle to the created array. The calling program guarantees that the `sharedData` pointer will remain valid for the duration that this data array is being used. The number of elements `numItems` must be positive (there cannot be an empty data object). The data is arranged in three dimensions, with specializations to two or one dimension (if some `numItems` are 1). The distance between consecutive elements (per dimension) is given in bytes with `byteStride` and can also be negative. If `byteStride` is zero it will be determined automatically (e.g., as `sizeof(type)`). Strides do not need to be ordered, i.e., `byteStride2` can be smaller than `byteStride1`, which is equivalent to a transpose. However, if the stride should be calculated, then an ordering in dimensions is assumed to disambiguate, i.e., `byteStride1 < byteStride2 < byteStride3`. An application can pass ownership of shared data to OSPRay (for example, when it temporarily created a modified version of its data only to make it compatible with OSPRay) by providing a deleter function that OSPRay will call whenever the time comes to deallocate the shared buffer. The deleter function has the following signature: ``` cpp typedef void (*OSPDeleterCallback)(const void *userData, const void *sharedData); ``` where `sharedData` will receive the address of the buffer and `userData` will receive whatever additional state the function needs to perform the deletion (both provided to `ospNewSharedData` when sharing the data with OSPRay). 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_FUTURE | future 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_GROUP | group object reference | | OSP_INSTANCE | instance object reference | | OSP_GEOMETRY | geometry object reference | | OSP_GEOMETRIC_MODEL | geometric model object reference | | OSP_VOLUME | volume object reference | | OSP_VOLUMETRIC_MODEL | volumetric model 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_BOOL | 8 bit boolean | | 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`. If the elements of the array are handles to objects, then their reference counter is incremented. An opaque `OSPData` with memory allocated by OSPRay is created with ``` cpp OSPData ospNewData(OSPDataType, uint64_t numItems1, uint64_t numItems2 = 1, uint64_t numItems3 = 1); ``` To allow for (partial) copies or updates of data arrays use ``` cpp void ospCopyData(const OSPData source, OSPData destination, uint64_t destinationIndex1 = 0, uint64_t destinationIndex2 = 0, uint64_t destinationIndex3 = 0); ``` which will copy the whole[^2] content of the `source` array into `destination` at the given location `destinationIndex`. The `OSPDataType`s of the data objects must match. The region to be copied must be valid inside the destination, i.e., in all dimensions, `destinationIndex + sourceSize <= destinationSize`. The affected region `[destinationIndex, destinationIndex + sourceSize)` is marked as dirty, which may be used by OSPRay to only process or update that sub-region (e.g., updating an acceleration structure). If the destination array is shared with OSPData by the application (created with `ospNewSharedData`), then - the source array must be shared as well (thus `ospCopyData` cannot be used to read opaque data) - if source and destination memory overlaps (aliasing), then behavior is undefined - except if source and destination regions are identical (including matching strides), which can be used by application to mark that region as dirty (instead of the whole `OSPData`) To add a data array as parameter named `id` to another object call also use ``` cpp void ospSetObject(OSPObject, const char *id, OSPData); ``` Volumes ------- Volumes are volumetric data sets with discretely sampled values in 3D space, typically a 3D scalar field. To create a new volume object of given type `type` use ``` cpp OSPVolume ospNewVolume(const char *type); ``` Note that OSPRay’s implementation forwards `type` directly to Open VKL, allowing new Open VKL volume types to be usable within OSPRay without the need to change (or even recompile) OSPRay. ### Structured Regular Volume Structured volumes only need to store the values of the samples, because their addresses in memory can be easily computed from a 3D position. A common type of structured volumes are regular grids. Structured regular volumes are created by passing the type string “`structuredRegular`†to `ospNewVolume`. Structured volumes are represented through an `OSPData` 3D array `data` (which may or may not be shared with the application). The voxel data must be laid out in xyz-order[^3] and can be compact (best for performance) or can have a stride between voxels, specified through the `byteStride1` parameter when creating the `OSPData`. Only 1D strides are supported, additional strides between scanlines (2D, `byteStride2`) and slices (3D, `byteStride3`) are not. The parameters understood by structured volumes are summarized in the 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 | | OSPData | data | | the actual voxel 3D [data](#data) | | bool | cellCentered | false | whether the data is provided per cell (as opposed to per vertex) | | uint | filter | `OSP_VOLUME_FILTER_LINEAR` | filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` and `OSP_VOLUME_FILTER_CUBIC` | | uint | gradientFilter | same as `filter` | filter used during gradient computations | | float | background | `NaN` | value that is used when sampling an undefined region outside the volume domain | Configuration parameters for structured regular volumes. The size of the volume is 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`). Data can be provided either per cell or per vertex (the default), selectable via the `cellCentered` parameter (which will also affect the computed bounding box). ### Structured Spherical Volume Structured spherical volumes are also supported, which are created by passing a type string of “`structuredSpherical`†to `ospNewVolume`. The grid dimensions and parameters are defined in terms of radial distance $r$, inclination angle $\theta$, and azimuthal angle $\phi$, conforming with the ISO convention for spherical coordinate systems. The coordinate system and parameters understood by structured spherical volumes are summarized below.
Coordinate system of structured spherical volumes.
| Type | Name | Default | Description | |:--------|:---------------|----------------------------:|:----------------------------------------------------------------------------------------------------------------| | vec3f | gridOrigin | $(0, 0, 0)$ | origin of the grid in units of $(r, \theta, \phi)$; angles in degrees | | vec3f | gridSpacing | $(1, 180/dim.y, 360/dim.z)$ | size of the grid cells in units of $(r, \theta, \phi)$, per default covering the full sphere; angles in degrees | | OSPData | data | | the actual voxel 3D [data](#data) | | uint | filter | `OSP_VOLUME_FILTER_LINEAR` | filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` | | uint | gradientFilter | same as `filter` | filter used during gradient computations | | float | background | `NaN` | value that is used when sampling an undefined region outside the volume domain | Configuration parameters for structured spherical volumes. The dimensions $(r, \theta, \phi)$ 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`). These grid parameters support flexible specification of spheres, hemispheres, spherical shells, spherical wedges, and so forth. The grid extents (computed as `[gridOrigin, gridOrigin + (dimensions - 1) * gridSpacing]`) however must be constrained such that: - $r \geq 0$ - $0 \leq \theta \leq 180$ - $0 \leq \phi \leq 360$ ### Adaptive Mesh Refinement (AMR) Volume OSPRay currently supports block-structured (Berger-Colella) AMR volumes. Volumes are specified as a list of blocks, which exist at levels of refinement in potentially overlapping regions. Blocks exist in a tree structure, with coarser refinement level blocks containing finer blocks. The cell width is equal for all blocks at the same refinement level, though blocks at a coarser level have a larger cell width than finer levels. There can be any number of refinement levels and any number of blocks at any level of refinement. An AMR volume type is created by passing the type string “`amr`†to `ospNewVolume`. Blocks are defined by three parameters: their bounds, the refinement level in which they reside, and the scalar data contained within each block. Note that cell widths are defined *per refinement level*, not per block. | Type | Name | Default | Description | |:------------|:-------------|------------------:|:-----------------------------------------------------------------------------------------------------------------------| | uint | method | `OSP_AMR_CURRENT` | `OSPAMRMethod` sampling method. Supported methods are: | | | | | `OSP_AMR_CURRENT` | | | | | `OSP_AMR_FINEST` | | | | | `OSP_AMR_OCTANT` | | float\[\] | cellWidth | NULL | array of each level’s cell width | | 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 | | 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. Lastly, note that the `gridOrigin` and `gridSpacing` parameters act just like the structured volume equivalent, but they only modify the root (coarsest level) of refinement. In particular, OSPRay’s / Open VKL’s AMR implementation was designed to 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 finds the finest refinement level at that cell and interpolates through this “current†level 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 interpolates through all available refinement levels at that cell. This method avoids discontinuities at refinement level boundaries at the cost of performance Details and more information can be found in the publication for the implementation \[3\]. 1. M.J. Berger and P. Colella, “Local adaptive mesh refinement for shock hydrodynamics.†Journal of Computational Physics 82.1 (1989): 64-84. DOI: 10.1016/0021-9991(89)90035-1 2. M. Adams, P. Colella, D.T. Graves, J.N. Johnson, N.D. Keen, T.J. Ligocki, D.F. Martin. P.W. McCorquodale, D. Modiano. P.O. Schwartz, T.D. Sternberg, and B. Van Straalen, “Chombo Software Package for AMR Applications – Design Documentâ€, Lawrence Berkeley National Laboratory Technical Report LBNL-6616E. 3. I. Wald, C. Brownlee, W. Usher, and A. Knoll, “CPU volume rendering of adaptive mesh refinement dataâ€. SIGGRAPH Asia 2017 Symposium on Visualization – SA ’17, 18(8), 1–8. DOI: 10.1145/3139295.3139305 ### Unstructured Volume Unstructured volumes can have their topology and geometry freely defined. Geometry can be composed of tetrahedral, hexahedral, wedge or pyramid cell types. The data format used is compatible with VTK and consists of multiple arrays: vertex positions and values, vertex indices, cell start indices, cell types, and cell values. An unstructured volume type is created by passing the type string “`unstructured`†to `ospNewVolume`. Sampled cell values can be specified either per-vertex (`vertex.data`) or per-cell (`cell.data`). If both arrays are set, `cell.data` takes precedence. Similar to a mesh, each cell is formed by a group of indices into the vertices. For each vertex, the corresponding (by array index) data value will be used for sampling when rendering, if specified. The index order for a tetrahedron is the same as `VTK_TETRA`: bottom triangle counterclockwise, then the top vertex. For hexahedral cells, each hexahedron is formed by a group of eight indices into the vertices and data values. Vertex ordering is the same as `VTK_HEXAHEDRON`: four bottom vertices counterclockwise, then top four counterclockwise. For wedge cells, each wedge is formed by a group of six indices into the vertices and data values. Vertex ordering is the same as `VTK_WEDGE`: three bottom vertices counterclockwise, then top three counterclockwise. For pyramid cells, each cell is formed by a group of five indices into the vertices and data values. Vertex ordering is the same as `VTK_PYRAMID`: four bottom vertices counterclockwise, then the top vertex. To maintain VTK data compatibility, the `index` array may be specified with cell sizes interleaved with vertex indices in the following format: $n, id_1, ..., id_n, m, id_1, ..., id_m$. This alternative `index` array layout can be enabled through the `indexPrefixed` flag (in which case, the `cell.type` parameter must be omitted). | Type | Name | Default | Description | |:------------------------|:-------------------|--------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------| | vec3f\[\] | vertex.position | | [data](#data) array of vertex positions | | float\[\] | vertex.data | | [data](#data) array of vertex data values to be sampled | | uint32\[\] / uint64\[\] | index | | [data](#data) array of indices (into the vertex array(s)) that form cells | | bool | indexPrefixed | false | indicates that the `index` array is compatible to VTK, where the indices of each cell are prefixed with the number of vertices | | uint32\[\] / uint64\[\] | cell.index | | [data](#data) array of locations (into the index array), specifying the first index of each cell | | float\[\] | cell.data | | [data](#data) array of cell data values to be sampled | | uint8\[\] | cell.type | | [data](#data) array of cell types (VTK compatible), only set if `indexPrefixed = false`. Supported types are: | | | | | `OSP_TETRAHEDRON` | | | | | `OSP_HEXAHEDRON` | | | | | `OSP_WEDGE` | | | | | `OSP_PYRAMID` | | bool | hexIterative | false | hexahedron interpolation method, defaults to fast non-iterative version which could have rendering inaccuracies may appear if hex is not parallelepiped | | bool | precomputedNormals | false | whether to accelerate by precomputing, at a cost of 12 bytes/face | | float | background | `NaN` | value that is used when sampling an undefined region outside the volume domain | Configuration parameters for unstructured volumes. ### VDB Volume VDB volumes implement a data structure that is very similar to the data structure outlined in Museth \[1\], they are created by passing the type string “`vdb`†to `ospNewVolume`. The data structure is a hierarchical regular grid at its core: Nodes are regular grids, and each grid cell may either store a constant value (this is called a tile), or child pointers. Nodes in VDB trees are wide: Nodes on the first level have a resolution of 323 voxels, on the next level 163, and on the leaf level 83 voxels. All nodes on a given level have the same resolution. This makes it easy to find the node containing a coordinate using shift operations (see \[1\]). VDB leaf nodes are implicit in OSPRay / Open VKL: they are stored as pointers to user-provided data.
Topology of VDB volumes.
VDB volumes interpret input data as constant cells (which are then potentially filtered). This is in contrast to `structuredRegular` volumes, which have a vertex-centered interpretation. The VDB implementation in OSPRay / Open VKL follows the following goals: - Efficient data structure traversal on vector architectures. - Enable the use of industry-standard `.vdb` files created through the OpenVDB library. - Compatibility with OpenVDB on a leaf data level, so that `.vdb` file may be loaded with minimal overhead. VDB volumes have the following parameters: | Type | Name | Description | |:------------|:-----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | int | maxSamplingDepth | do not descend further than to this depth during sampling, the maximum value and the default is 3 | | uint32\[\] | node.level | level on which each input node exists, may be 1, 2 or 3 (levels are counted from the root level = 0 down) | | vec3i\[\] | node.origin | the node origin index (per input node) | | OSPData\[\] | node.data | [data](#data) arrays with the node data (per input node). Nodes that are tiles are expected to have single-item arrays. Leaf-nodes with grid data expected to have compact 3D arrays in zyx layout (z changes most quickly) with the correct number of voxels for the `level`. Only `OSP_FLOAT` is supported as field `OSPDataType`. | | OSPData | nodesPackedDense | optionally provided instead of `node.data`, a single array of all dense node data in a contiguous zyx layout, provided in the same order as the corresponding `node.*` parameters | | OSPData | nodesPackedTile | optionally provided instead of `node.data`, a single array of all tile node data in a contiguous layout, provided in the same order as the corresponding `node.*` parameters | | uint32\[\] | node.format | for each input node, whether it is of format `OSP_VOLUME_FORMAT_DENSE_ZYX` (and thus stored in `nodesPackedDense`), or `OSP_VOLUME_FORMAT_TILE` (stored in `nodesPackedTile`) | | uint | filter | filter used for reconstructing the field, default is `OSP_VOLUME_FILTER_LINEAR`, alternatively `OSP_VOLUME_FILTER_NEAREST`, or `OSP_VOLUME_FILTER_CUBIC`. | | uint | gradientFilter | filter used for reconstructing the field during gradient computations, default same as `filter` | | float | background | value that is used when sampling an undefined region outside the volume domain, default `NaN` | Configuration parameters for VDB volumes. The `nodesPackedDense` and `nodesPackedTile` together with `node.format` parameters may be provided instead of `node.data`; this packed data layout may provide better performance. 1. Museth, K. VDB: High-Resolution Sparse Volumes with Dynamic Topology. ACM Transactions on Graphics 32(3), 2013. DOI: 10.1145/2487228.2487235 ### Particle Volume Particle volumes consist of a set of points in space. Each point has a position, a radius, and a weight typically associated with an attribute. Particle volumes are created by passing the type string “`particle`†to `ospNewVolume`. A radial basis function defines the contribution of that particle. Currently, we use the Gaussian radial basis function $$\phi(P) = w \exp\left(-\frac{(P - p)^2}{2 r^2}\right),$$ where $P$ is the particle position, $p$ is the sample position, $r$ is the radius and $w$ is the weight. At each sample, the scalar field value is then computed as the sum of each radial basis function $\phi$, for each particle that overlaps it. The OSPRay / Open VKL implementation is similar to direct evaluation of samples in Reda et al. \[2\]. It uses an Embree-built BVH with a custom traversal, similar to the method in \[1\]. | Type | Name | Default | Description | |:----------|:------------------------|--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | vec3f\[\] | particle.position | | [data](#data) array of particle positions | | float\[\] | particle.radius | | [data](#data) array of particle radii | | float\[\] | particle.weight | NULL | optional [data](#data) array of particle weights, specifying the height of the kernel. | | float | radiusSupportFactor | 3.0 | The multiplier of the particle radius required for support. Larger radii ensure smooth results at the cost of performance. In the Gaussian kernel, the radius is one standard deviation ($\sigma$), so a value of 3 corresponds to $3 \sigma$. | | float | clampMaxCumulativeValue | 0 | The maximum cumulative value possible, set by user. All cumulative values will be clamped to this, and further traversal (RBF summation) of particle contributions will halt when this value is reached. A value of zero or less turns this off. | | bool | estimateValueRanges | true | Enable heuristic estimation of value ranges which are used in internal acceleration structures as well as for determining the volume’s overall value range. When set to `false`, the user *must* specify `clampMaxCumulativeValue`, and all value ranges will be assumed \[0–`clampMaxCumulativeValue`\]. Disabling this switch may improve volume commit time, but will make volume rendering less efficient. | Configuration parameters for particle volumes. 1. A. Knoll, I. Wald, P. Navratil, A. Bowen, K. Reda, M.E., Papka, and K. Gaither, “RBF Volume Ray Casting on Multicore and Manycore CPUsâ€, 2014, Computer Graphics Forum, 33: 71–80. doi:10.1111/cgf.12363 2. K. Reda, A. Knoll, K. Nomura, M. E. Papka, A. E. Johnson and J. Leigh, “Visualizing large-scale atomistic simulations in ultra-resolution immersive environmentsâ€, 2013 IEEE Symposium on Large-Scale Data Analysis and Visualization (LDAV), Atlanta, GA, 2013, pp. 59–65. ### Transfer Function Transfer functions map the scalar values of volumes to color and opacity and thus they can be used to visually emphasize certain features of the volume. To create a new transfer function of given type `type` use ``` cpp OSPTransferFunction ospNewTransferFunction(const char *type); ``` The returned handle can be assigned to a volumetric model (described below) as parameter “`transferFunction`†using `ospSetObject`. One type of transfer function that is supported by OSPRay is the linear transfer function, which interpolates between given equidistant colors and opacities. It is create by passing the string “`piecewiseLinear`†to `ospNewTransferFunction` and it is controlled by these parameters: | Type | Name | Description | |:----------|:--------|:----------------------------------------------| | vec3f\[\] | color | [data](#data) array of colors (linear RGB) | | float\[\] | opacity | [data](#data) array of opacities | | box1f | value | domain (scalar range) this function maps from | Parameters accepted by the linear transfer function. The arrays `color` and `opacity` can be of different length. ### VolumetricModels Volumes in OSPRay are given volume rendering appearance information through VolumetricModels. This decouples the physical representation of the volume (and possible acceleration structures it contains) to rendering-specific parameters (where more than one set may exist concurrently). To create a volume instance, call ``` cpp OSPVolumetricModel ospNewVolumetricModel(OSPVolume); ``` The passed volume can be `NULL` as long as the volume to be used is passed as a parameter. If both a volume is specified on object creation and as a parameter, the parameter value is used. If the parameter value is later removed, the volume object passed on object creation is again used. | Type | Name | Default | Description | |:--------------------|:-----------------|--------:|:-------------------------------------------------------------------------------------------------------------------------------------| | OSPVolume | volume | | optional [volume](#volumes) object this model references | | OSPTransferFunction | transferFunction | | [transfer function](#transfer-function) to use | | float | densityScale | 1.0 | makes volumes uniformly thinner or thicker | | float | anisotropy | 0.0 | anisotropy of the (Henyey-Greenstein) phase function in \[-1–1\] ([path tracer](#path-tracer) only), default to isotropic scattering | | uint32 | id | -1u | optional user ID, for [framebuffer](#framebuffer) channel `OSP_FB_ID_OBJECT` | Parameters understood by VolumetricModel. Geometries ---------- Geometries in OSPRay are objects that describe intersectable surfaces. To create a new geometry object of given type `type` use ``` cpp OSPGeometry ospNewGeometry(const char *type); ``` Note that in the current implementation geometries are limited to a maximum of 232 primitives. ### Mesh A mesh consisting of either triangles or quads is created by calling `ospNewGeometry` with type string “`mesh`â€. Once created, a mesh recognizes the following parameters: | Type | Name | Description | |:------------------------|:-----------------------|:---------------------------------------------------------------------------------------------------------------------| | vec3f\[\] | vertex.position | [data](#data) array of vertex positions, overridden by `motion.*` arrays | | vec3f\[\] | normal | [data](#data) array of face-varying normals, overridden by `motion.*` arrays | | vec3f\[\] | vertex.normal | [data](#data) array of vertex-varying normals, overridden by `motion.*` arrays | | vec4f\[\] / vec3f\[\] | color | [data](#data) array of face-varying colors (linear RGBA/RGB) | | vec4f\[\] / vec3f\[\] | vertex.color | [data](#data) array of vertex-varying colors (linear RGBA/RGB) | | vec2f\[\] | texcoord | [data](#data) array of face-varying texture coordinates | | vec2f\[\] | vertex.texcoord | [data](#data) array of vertex-varying texture coordinates | | vec3ui\[\] / vec4ui\[\] | index | [data](#data) array of (either triangle or quad) indices (into the vertex array(s)) | | bool | quadSoup | when no explicit `index` is given, indicates whether to assume a ‘soup’ of quads instead of triangles, default false | | vec3f\[\]\[\] | motion.vertex.position | [data](#data) array of vertex position arrays (uniformly distributed keys for deformation motion blur) | | vec3f\[\]\[\] | motion.normal | [data](#data) array of face-varying normal arrays (uniformly distributed keys for deformation motion blur) | | vec3f\[\]\[\] | motion.vertex.normal | [data](#data) array of vertex-varying normal arrays (uniformly distributed keys for deformation motion blur) | | box1f | time | time associated with first and last key in `motion.*` arrays (for deformation motion blur), default \[0, 1\] | Parameters defining a mesh geometry. The data type of index arrays differentiates between the underlying geometry, triangles are used for a index with `vec3ui` type and quads for `vec4ui` type. Quads are internally handled as a pair of two triangles, thus mixing triangles and quads is supported by encoding some triangle as a quad with the last two vertex indices being identical (`w=z`). The `vertex.position` array is mandatory to create a valid mesh. The `index` array is optional. If none is provided, a ‘triangle soup’ is assumed, i.e., each three consecutive vertices form one triangle; unless the boolean `quadSoup` is set to true, then a ‘quad soup’ is assumed i.e., each four subsequent vertices form one quad. If the size of the `vertex.position` array is not a multiple of three for triangles or four for quads, the remainder vertices are ignored. Face-varying attributes (`normal`, `motion.normal`, `color`, `texcoord`) map unique values to each vertex of a primitive/face (triangle or quad), thus attributes can be different for the same vertex that is shared by multiple primitives. Essentially, face-varying attributes are a ‘attribute soup’ and behave similar to the implicit index, the size of the array must be at least three times the number of triangles or four times the number of quads, respectively. Face-varying attributes take precedence over the respective vertex attributes (`vertex.normal`, `motion.vertex.normal`, `vertex.color`, `vertex.texcoord`) when both arrays of the same attribute are present. ### Subdivision A mesh consisting of subdivision surfaces, created by specifying a geometry of type “`subdivision`â€. Once created, a subdivision recognizes the following parameters: | Type | Name | Description | |:----------|:--------------------|:----------------------------------------------------------------------------------------------------------------------| | vec3f\[\] | vertex.position | [data](#data) array of vertex positions | | vec4f\[\] | color | optional [data](#data) array of face-varying colors (linear RGBA) | | vec4f\[\] | vertex.color | optional [data](#data) array of vertex-varying colors (linear RGBA) | | vec2f\[\] | texcoord | optional [data](#data) array of vertex-varying texture coordinates | | vec2f\[\] | vertex.texcoord | optional [data](#data) array of vertex-varying texture coordinates | | float | level | global level of tessellation, default 5 | | uint\[\] | index | [data](#data) array of indices (into the vertex array(s)) | | float\[\] | index.level | optional [data](#data) array of per-edge levels of tessellation, overrides global level | | uint\[\] | face | optional [data](#data) array holding the number of indices/edges (3 to 15) per face, defaults to 4 (a pure quad mesh) | | vec2i\[\] | edgeCrease.index | optional [data](#data) array of edge crease indices | | float\[\] | edgeCrease.weight | optional [data](#data) array of edge crease weights | | uint\[\] | vertexCrease.index | optional [data](#data) array of vertex crease indices | | float\[\] | vertexCrease.weight | optional [data](#data) array of vertex crease weights | | uint | mode | `OSPSubdivisionMode` subdivision edge boundary mode, supported modes are: | | | | `OSP_SUBDIVISION_NO_BOUNDARY` | | | | `OSP_SUBDIVISION_SMOOTH_BOUNDARY` (default) | | | | `OSP_SUBDIVISION_PIN_CORNERS` | | | | `OSP_SUBDIVISION_PIN_BOUNDARY` | | | | `OSP_SUBDIVISION_PIN_ALL` | Parameters defining a Subdivision geometry. The `vertex` and `index` arrays are mandatory to create a valid subdivision surface. If no `face` array is present then a pure quad mesh is assumed (the number of indices must be a multiple of 4). Optionally supported are edge and vertex creases. ### Spheres A geometry consisting of individual spheres, each of which can have an own radius, is created by calling `ospNewGeometry` with type string “`sphere`â€. The spheres will not be tessellated but rendered procedurally and are thus perfectly round. To allow a variety of sphere representations in the application this geometry allows a flexible way of specifying the data of center position and radius within a [data](#data) array: | Type | Name | Default | Description | |:----------|:----------------|--------:|:--------------------------------------------------------------------------| | vec3f\[\] | sphere.position | | [data](#data) array of center positions | | float\[\] | sphere.radius | NULL | optional [data](#data) array of the per-sphere radius | | vec3f\[\] | sphere.normal | NULL | optional [data](#data) array of normals (only for “oriented discâ€) | | vec2f\[\] | sphere.texcoord | NULL | optional [data](#data) array of texture coordinates (constant per sphere) | | float | radius | 0.01 | default radius for all spheres (if `sphere.radius` is not set) | | uint | type | | `OSPSphereType` for rendering the sphere. Supported types are: | | | | | `OSP_SPHERE` (default) | | | | | `OSP_DISC` | | | | | `OSP_ORIENTED_DISC` | Parameters defining a spheres geometry. ### Curves 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 | | uint | type | `OSPCurveType` for rendering the curve. Supported types are: | | | | `OSP_FLAT` | | | | `OSP_ROUND` | | | | `OSP_RIBBON` | | | | `OSP_DISJOINT` | | uint | 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. Positions in `vertex.position_radius` parameter supports per-vertex varying radii with data type `vec4f[]` and instantiate Embree curves 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 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 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 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 $(p0, p1, p2, p3)$ and $(p1, p2, p3, p4)$ 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 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 tangent buffer. This basis is interpolating, thus does exactly go through the first and second control point, and the first order 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 The indices point to the first of 4 consecutive control points in the vertex buffer. If $(p0, p1, p2, p3)$ represent the points then this basis goes through $p1$ and $p2$, with tangents as $(p2-p0)/2$ and $(p3-p1)/2$. The following section describes the properties of different curve types’ and how they define the geometry of a curve: OSP_FLAT This type enables faster rendering as the curve is rendered as a connected sequence of ray facing quads. 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 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 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. ### Boxes OSPRay can directly render axis-aligned bounding boxes without the need to convert them to quads or triangles. To do so create a boxes geometry by calling `ospNewGeometry` with type string “`box`â€. | Type | Name | Description | |:----------|:-----|:-----------------------------| | box3f\[\] | box | [data](#data) array of boxes | Parameters defining a boxes geometry. ### Planes OSPRay can directly render planes defined by plane equation coefficients in its implicit form $ax + by + cz + d = 0$. By default 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 | Parameters defining a planes geometry. ### Isosurfaces OSPRay can directly render multiple isosurfaces of a volume without first tessellating them. To do so create an isosurfaces geometry by calling `ospNewGeometry` with type string “`isosurface`â€. The appearance information of the surfaces is set through the Geometric Model. Per-isosurface colors can be set by passing per-primitive colors to the Geometric Model, in order of the isosurface array. | Type | Name | Description | |:----------|:---------|:---------------------------------------------------| | float | isovalue | single isovalues | | float\[\] | isovalue | [data](#data) array of isovalues | | OSPVolume | volume | handle of the [Volume](#volumes) to be isosurfaced | Parameters defining an isosurfaces geometry. ### GeometricModels Geometries are matched with surface appearance information through GeometricModels. These take a geometry, which defines the surface representation, and applies either full-object or per-primitive color and material information. To create a geometric model, call ``` cpp OSPGeometricModel ospNewGeometricModel(OSPGeometry); ``` The passed geometry can be `NULL` as long as the geometry to be used is passed as a parameter. If both a geometry is specified on object creation and as a parameter, the parameter value is used. If the parameter value is later removed, the geometry object passed on object creation is again used. Color and material are fetched with the primitive ID of the hit (clamped to the valid range, thus a single color or material is fine), or mapped first via the `index` array (if present). All parameters are optional, however, some renderers (notably the [path tracer](#path-tracer)) require a material to be set. Materials are either handles of `OSPMaterial`, or indices into the `material` array on the [renderer](#renderers), which allows to build a [world](#world) which can be used by different types of renderers. An `invertNormals` flag allows to invert (shading) normal vectors of the rendered geometry. That is particularly useful for clipping. By changing normal vectors orientation one can control whether inside or outside of the clipping geometry is being removed. For example, a clipping geometry with normals oriented outside clips everything what’s inside. | Type | Name | Description | |:----------------------------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------| | OSPGeometry | geometry | optional [geometry](#geometries) object this model references | | OSPMaterial / OSPMaterial\[\] / uint32 / uint32\[\] | material | optional ([data](#data) array of per-primitive) [material](#materials), may be an index into the `material` parameter on the renderer (if it exists) | | vec4f / vec4f\[\] | color | optional ([data](#data) array of per-primitive) color assigned to the geometry (linear RGBA) | | uint8\[\] | index | optional [data](#data) array of per-primitive indices into `color` and `material` | | bool | invertNormals | inverts all shading normals (Ns), default false | | uint32 | id | optional user ID, for [framebuffer](#framebuffer) channel `OSP_FB_ID_OBJECT`, default -1u | Parameters understood by GeometricModel. Lights ------ To create a new light source of given type `type` use ``` cpp OSPLight ospNewLight(const char *type); ``` All light sources accept the following parameters: | Type | Name | Default | Description | |:------|:------------------|--------:|:----------------------------------------------------------------------------------------------------------------------------------| | vec3f | color | white | color of the light (linear RGB) | | float | intensity | 1 | intensity of the light (a factor) | | uint | intensityQuantity | | `OSPIntensityQuantity` to set the radiometric quantity represented by `intensity`. The default value depends on the light source. | | bool | visible | true | whether the light can be directly seen | Parameters accepted by all lights. In OSPRay the `intensity` parameter of a light source can correspond to different types of radiometric quantities. The type of the value represented by a light’s `intensity` parameter is set using `intensityQuantity`, which accepts values from the enum type `OSPIntensityQuantity`. The supported types of `OSPIntensityQuantity` 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`, or when using `intensityDistribution`). | Types of radiometric quantities used to interpret a light’s `intensity` parameter. ### Photometric Lights Measured light sources (IES, EULUMDAT, …) are supported by the `sphere`, `spot`, and `quad` lights when setting an `intensityDistribution` [data](#data) array to modulate the intensity per direction. The mapping is using the C-γ coordinate system (see also below figure): the values of the first (or only) dimension of `intensityDistribution` are uniformly mapped to γ in \[0–π\]; the first intensity value to 0, the last value to Ï€, thus at least two values need to be present. ![C-γ coordinate system for the mapping of `intensityDistribution` with photometric lights.](https://ospray.github.io/images/c-gamma_coords.png) If the array has a second dimension then the intensities are not rotational symmetric around the main direction (where angle γ is zero), but are accordingly mapped to the C-halfplanes in \[0–2Ï€\]; the first “row†of values to 0 and 2Ï€, the other rows such that they have uniform distance to its neighbors. The orientation of the C0-plane is specified via `c0`. | Type | Name | Description | |:----------|:----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| | 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 for photometric lights. When using an `intensityDistribution` then the default and only valid value for `intensityQuantity` is `OSP_INTENSITY_QUANTITY_SCALE`. The following light types are supported by most OSPRay renderers. ### Directional Light / Distant Light The distant light (or traditionally the directional light) is thought to be far away (outside of the scene), thus its light arrives (almost) as parallel rays. It is created by passing the type string “`distant`†to `ospNewLight`. The distant light supports `OSP_INTENSITY_QUANTITY_RADIANCE` and `OSP_INTENSITY_QUANTITY_IRRADIANCE` (default) as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) understood by all lights the distant light supports the following special parameters: | 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 soft shadows when the renderer uses stochastic sampling (like the [path tracer](#path-tracer)). For instance, the apparent size of the sun is about 0.53°. ### Point Light / Sphere Light The sphere light (or the special case point light) is a light emitting uniformly in all directions from the surface toward the outside. It does not emit any light toward the inside of the sphere. It is created by passing the type string “`sphere`†to `ospNewLight`. The point light supports only `OSP_INTENSITY_QUANTITY_SCALE` when `intensityDistribution` is set, or otherwise `OSP_INTENSITY_QUANTITY_POWER`, `OSP_INTENSITY_QUANTITY_INTENSITY` (then default) and `OSP_INTENSITY_QUANTITY_RADIANCE` as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) understood by all lights and the [photometric parameters](#photometric-lights) the sphere light supports the following special parameters: | Type | Name | Default | Description | |:------|:----------|------------:|:--------------------------------------------| | vec3f | position | $(0, 0, 0)$ | the center of the sphere light | | float | radius | 0 | the size of the sphere light | | vec3f | direction | $(0, 0, 1)$ | main orientation of `intensityDistribution` | Special parameters accepted by the sphere light. Setting the radius to a value greater than zero will result in soft shadows when the renderer uses stochastic sampling (like the [path tracer](#path-tracer)). ### Spotlight / Ring Light The spotlight is a light emitting into a cone of directions. It is created by passing the type string “`spot`†to `ospNewLight`. The spotlight supports only `OSP_INTENSITY_QUANTITY_SCALE` when `intensityDistribution` is set, or otherwise `OSP_INTENSITY_QUANTITY_POWER`, `OSP_INTENSITY_QUANTITY_INTENSITY` (then default) and `OSP_INTENSITY_QUANTITY_RADIANCE` as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) understood by all lights and the [photometric parameters](#photometric-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 | | 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 | Special parameters accepted by the spotlight. ![Angles used by the spotlight.](https://ospray.github.io/images/spot_light.png) Setting the radius to a value greater than zero will result in soft shadows when the renderer uses stochastic sampling (like the [path tracer](#path-tracer)). Additionally setting the inner radius will result in a ring instead of a disk emitting the light. ### Quad Light The quad[^4] light is a planar, procedural area light source emitting uniformly on one side into the half-space. It is created by passing the type string “`quad`†to `ospNewLight`. The quad light supports only `OSP_INTENSITY_QUANTITY_SCALE` when `intensityDistribution` is set, or otherwise `OSP_INTENSITY_QUANTITY_POWER`, `OSP_INTENSITY_QUANTITY_INTENSITY` and `OSP_INTENSITY_QUANTITY_RADIANCE` (then default) as `intensityQuantity` parameter. In addition to the [general parameters](#lights) understood by all lights and the [photometric parameters](#photometric-lights) the quad light supports the following special parameters: | 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.](https://ospray.github.io/images/quad_light.png) The emission side is determined by the cross product of `edge1`×`edge2`. which is also the main emission direction for `intensityDistribution`. Note that only renderers that use stochastic sampling (like the path 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 illuminating it from infinity. It is created by passing the type string “`hdri`†to `ospNewLight`. The values of the HDRI correspond to radiance and therefore the HDRI light only accepts `OSP_INTENSITY_QUANTITY_SCALE` as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) the HDRI light supports the following special parameters: | 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. ![Orientation and Mapping of an HDRI Light.](https://ospray.github.io/images/hdri_light.png) Note that the [SciVis renderer](#scivis-renderer) only shows the HDRI light in the background (like an environment map) without computing illumination of the scene. ### Ambient Light The ambient light surrounds the scene and illuminates it from infinity with constant radiance (determined by combining the [parameters `color` and `intensity`](#lights)). It is created by passing the type string “`ambient`†to `ospNewLight`. The ambient light supports `OSP_INTENSITY_QUANTITY_RADIANCE` and `OSP_INTENSITY_QUANTITY_IRRADIANCE` (default) as `intensityQuantity` parameter value. Note that the [SciVis renderer](#scivis-renderer) uses ambient lights to control the color and intensity of the computed ambient occlusion (AO). ### Sun-Sky Light The sun-sky light is a combination of a `distant` light for the sun and a procedural `hdri` light for the sky. It is created by passing the type string “`sunSky`†to `ospNewLight`. The sun-sky light surrounds the scene and illuminates it from infinity and can be used for rendering outdoor scenes. The radiance values are calculated using the HoÅ¡ek-Wilkie sky model and solar radiance function. The underlying model of the sun-sky light returns radiance values and therefore the light only accepts `OSP_INTENSITY_QUANTITY_SCALE` as `intensityQuantity` parameter value. To rescale the returned radiance of the sky model the 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 | | 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. The lowest elevation for the sun is restricted to the horizon. Note that the [SciVis renderer](#scivis-renderer) only computes illumination from the sun (yet the sky is still shown in the background, like an environment map). ### Emissive Objects The [path tracer](#path-tracer) will consider illumination by [geometries](#geometries) which have a light emitting material assigned (for example the [Luminous](#luminous) or [Principled](#principled) material). Materials --------- Materials describe how light interacts with surfaces, they give objects their distinctive look. To create a new material of given type `type` call ``` cpp OSPMaterial ospNewMaterial(const char *material_type); ``` The returned handle can then be used to assign the material to a given geometry with ``` cpp void ospSetObject(OSPGeometricModel, "material", OSPMaterial); ``` ### OBJ Material The OBJ material is the workhorse material supported by both the [SciVis renderer](#scivis-renderer) and the [path tracer](#path-tracer) (the [Ambient Occlusion renderer](#ambient-occlusion-renderer) only uses the `kd` and `d` parameter). It offers widely used common properties like diffuse and specular reflection and is based on the [MTL material 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 | Main parameters of the OBJ material. In particular when using the path tracer it is important to adhere to the principle of energy conservation, i.e., that the amount of light reflected by a surface is not larger than the light arriving. Therefore the path tracer issues a warning and renormalizes the color parameters if the sum of `kd`, `ks`, and `tf` is larger than one in any color channel. Similarly important to mention is that almost all materials of the real world reflect at most only about 80% of the incoming light. So even for a white sheet of paper or white wall paint do better not set `kd` larger than 0.8; otherwise rendering times are unnecessary long and the contrast in the final images is low (for example, the corners of a white room would hardly be discernible, as can be seen in the figure below).
Comparison of diffuse rooms with 100% reflecting white paint (left) and realistic 80% reflecting white paint (right), which leads to higher overall contrast. Note that exposure has been adjusted to achieve similar brightness levels.
If present, the color component of [geometries](#geometries) is also used for the diffuse color `kd` and the alpha component is also used for 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)$[^5] 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.
Note that `tf` colored transparency is implemented in the SciVis and the path tracer but normal mapping with `map_bump` is currently supported in the path tracer only. All parameters (except `tf`) can be textured by passing a [texture](#texture) handle, prefixed with “`map_`â€. The fetched texels are multiplied by the respective parameter value. If only the texture is given (but not the corresponding parameter), only the texture is used (the default value of the parameter is *not* multiplied). The color textures `map_kd` and `map_ks` are typically in one of the sRGB gamma encoded formats, whereas textures `map_ns` and `map_d` are usually in a linear format (and only the first component is used). Additionally, all textures support [texture transformations](#texture-transformations).
Rendering of a OBJ material with wood textures.
### Principled The Principled material is the most complex material offered by the [path tracer](#path-tracer), which is capable of producing a wide variety of materials (e.g., plastic, metal, wood, glass) by combining multiple different layers and lobes. It uses the GGX microfacet distribution with approximate multiple scattering for dielectrics and metals, uses the Oren-Nayar model for diffuse reflection, and is energy conserving. To create a Principled material, pass the type string “`principled`†to `ospNewMaterial`. Its parameters are listed in the table below. | Type | Name | Default | Description | |:------|:------------------|----------:|:------------------------------------------------------------------------------------------------------------------------| | vec3f | baseColor | white 0.8 | base reflectivity (diffuse and/or metallic, linear RGB) | | vec3f | edgeColor | white | edge tint (metallic only, linear RGB) | | float | metallic | 0 | mix between dielectric (diffuse and/or specular) and metallic (specular only with complex IOR) in \[0–1\] | | float | diffuse | 1 | diffuse reflection weight in \[0–1\] | | float | specular | 1 | specular reflection/transmission weight in \[0–1\] | | float | ior | 1 | dielectric index of refraction | | float | transmission | 0 | specular transmission weight in \[0–1\] | | vec3f | transmissionColor | white | attenuated color due to transmission (Beer’s law, linear RGB) | | float | transmissionDepth | 1 | distance at which color attenuation is equal to transmissionColor | | float | roughness | 0 | diffuse and specular roughness in \[0–1\], 0 is perfectly smooth | | float | anisotropy | 0 | amount of specular anisotropy in \[0–1\] | | float | rotation | 0 | rotation of the direction of anisotropy in \[0–1\], 1 is going full circle | | float | normal | 1 | default normal map/scale for all layers | | float | baseNormal | 1 | base normal map/scale (overrides default normal) | | bool | thin | false | flag specifying whether the material is thin or solid | | float | thickness | 1 | thickness of the material (thin only), affects the amount of color attenuation due to specular transmission | | float | backlight | 0 | amount of diffuse transmission (thin only) in \[0–2\], 1 is 50% reflection and 50% transmission, 2 is transmission only | | float | coat | 0 | clear coat layer weight in \[0–1\] | | float | coatIor | 1.5 | clear coat index of refraction | | vec3f | coatColor | white | clear coat color tint (linear RGB) | | float | coatThickness | 1 | clear coat thickness, affects the amount of color attenuation | | float | coatRoughness | 0 | clear coat roughness in \[0–1\], 0 is perfectly smooth | | float | coatNormal | 1 | clear coat normal map/scale (overrides default normal) | | float | sheen | 0 | sheen layer weight in \[0–1\] | | vec3f | sheenColor | white | sheen color tint (linear RGB) | | float | sheenTint | 0 | how much sheen is tinted from sheenColor toward baseColor | | float | sheenRoughness | 0.2 | sheen roughness in \[0–1\], 0 is perfectly smooth | | float | opacity | 1 | cut-out opacity/transparency, 1 is fully opaque | | vec3f | emissiveColor | black | color (and intensity) of the emitted light | Parameters of the Principled material. All parameters can be textured by passing a [texture](#texture) handle, prefixed with “`map_`†(e.g., “`map_baseColor`â€). [texture transformations](#texture-transformations) are supported as well.
Rendering of a Principled coated brushed metal material with textured anisotropic rotation and a dust layer (sheen) on top.
### CarPaint The CarPaint material is a specialized version of the Principled material for rendering different types of car paints. To create a CarPaint material, pass the type string “`carPaint`†to `ospNewMaterial`. Its parameters are listed in the table below. | Type | Name | Default | Description | |:------|:----------------|----------:|:-----------------------------------------------------------------------------------------------------------------------| | vec3f | baseColor | white 0.8 | diffuse base reflectivity (linear RGB) | | float | roughness | 0 | diffuse roughness in \[0–1\], 0 is perfectly smooth | | float | normal | 1 | normal map/scale | | vec3f | flakeColor | Aluminium | color of metallic flakes (linear RGB) | | float | flakeDensity | 0 | density of metallic flakes in \[0–1\], 0 disables flakes, 1 fully covers the surface with flakes | | float | flakeScale | 100 | scale of the flake structure, higher values increase the amount of flakes | | float | flakeSpread | 0.3 | flake spread in \[0–1\] | | float | flakeJitter | 0.75 | flake randomness in \[0–1\] | | float | flakeRoughness | 0.3 | flake roughness in \[0–1\], 0 is perfectly smooth | | float | coat | 1 | clear coat layer weight in \[0–1\] | | float | coatIor | 1.5 | clear coat index of refraction | | vec3f | coatColor | white | clear coat color tint (linear RGB) | | float | coatThickness | 1 | clear coat thickness, affects the amount of color attenuation | | float | coatRoughness | 0 | clear coat roughness in \[0–1\], 0 is perfectly smooth | | float | coatNormal | 1 | clear coat normal map/scale | | vec3f | flipflopColor | white | reflectivity of coated flakes at grazing angle, used together with coatColor produces a pearlescent paint (linear RGB) | | float | flipflopFalloff | 1 | flip flop color falloff, 1 disables the flip flop effect | Parameters of the CarPaint material. All parameters can be textured by passing a [texture](#texture) handle, prefixed with “`map_`†(e.g., “`map_baseColor`â€). [texture transformations](#texture-transformations) are supported as well.
Rendering of a pearlescent CarPaint material.
### Metal The [path tracer](#path-tracer) offers a physical metal, supporting changing roughness and realistic color shifts at edges. To create a Metal material pass the type string “`metal`†to `ospNewMaterial`. Its parameters are | Type | Name | Default | Description | |:----------|:----------|----------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------| | vec3f\[\] | ior | Aluminium | [data](#data) array of spectral samples of complex refractive index, each entry in the form (wavelength, eta, k), ordered by wavelength (which is in nm) | | vec3f | eta | | RGB complex refractive index, real part | | vec3f | k | | RGB complex refractive index, imaginary part | | float | roughness | 0.1 | roughness in \[0–1\], 0 is perfect mirror | Parameters of the Metal material. The main appearance (mostly the color) of the Metal material is controlled by the physical parameters `eta` and `k`, the wavelength-dependent, complex index of refraction. These coefficients are quite counter-intuitive but can be found in [published measurements](https://refractiveindex.info/). For accuracy the index of refraction can be given as an array of spectral samples in `ior`, each sample a triplet of wavelength (in nm), eta, and k, ordered monotonically increasing by wavelength; OSPRay will then calculate the Fresnel in the spectral domain. Alternatively, `eta` and `k` can also be specified as approximated RGB coefficients; some examples are given in below table. | Metal | eta | k | |:--------------|:---------------------:|:---------------:| | Ag, Silver | (0.051, 0.043, 0.041) | (5.3, 3.6, 2.3) | | Al, Aluminium | (1.5, 0.98, 0.6) | (7.6, 6.6, 5.4) | | Au, Gold | (0.07, 0.37, 1.5) | (3.7, 2.3, 1.7) | | Cr, Chromium | (3.2, 3.1, 2.3) | (3.3, 3.3, 3.1) | | Cu, Copper | (0.1, 0.8, 1.1) | (3.5, 2.5, 2.4) | Index of refraction of selected metals as approximated RGB coefficients, based on data from https://refractiveindex.info/. The `roughness` parameter controls the variation of microfacets and thus how polished the metal will look. The roughness can be modified by a [texture](#texture) `map_roughness` ([texture transformations](#texture-transformations) are supported as well) to create notable edging effects.
Rendering of golden Metal material with textured roughness.
### Alloy The [path tracer](#path-tracer) offers an alloy material, which behaves similar to [Metal](#metal), but allows for more intuitive and flexible control of the color. To create an Alloy material pass the type string “`alloy`†to `ospNewMaterial`. Its parameters are | Type | Name | Default | Description | |:------|:----------|----------:|:--------------------------------------------------------| | vec3f | color | white 0.9 | reflectivity at normal incidence (0 degree, linear RGB) | | vec3f | edgeColor | white | reflectivity at grazing angle (90 degree, linear RGB) | | float | roughness | 0.1 | roughness, in \[0–1\], 0 is perfect mirror | Parameters of the Alloy material. The main appearance of the Alloy material is controlled by the parameter `color`, while `edgeColor` influences the tint of reflections when seen at grazing angles (for real metals this is always 100% white). If present, the color component of [geometries](#geometries) is also used for reflectivity at normal incidence `color`. As in [Metal](#metal) the `roughness` parameter controls the variation of microfacets and thus how polished the alloy will look. All parameters can be textured by passing a [texture](#texture) handle, prefixed with “`map_`â€; [texture transformations](#texture-transformations) are supported as well.
Rendering of a fictional Alloy material with textured color.
### Glass The [path tracer](#path-tracer) offers a realistic a glass material, supporting refraction and volumetric attenuation (i.e., the transparency color varies with the geometric thickness). To create a Glass material pass the type string “`glass`†to `ospNewMaterial`. Its parameters are | Type | Name | Default | Description | |:------|:--------------------|--------:|:------------------------------------------------| | float | eta | 1.5 | index of refraction | | vec3f | attenuationColor | white | resulting color due to attenuation (linear RGB) | | float | attenuationDistance | 1 | distance affecting attenuation | Parameters of the Glass material. For convenience, the rather counter-intuitive physical attenuation coefficients will be calculated from the user inputs in such a way, that the `attenuationColor` will be the result when white light traveled through a glass of thickness `attenuationDistance`.
Rendering of a Glass material with orange attenuation.
### ThinGlass The [path tracer](#path-tracer) offers a thin glass material useful for objects with just a single surface, most prominently windows. It models a thin, transparent slab, i.e., it behaves as if a second, virtual surface is parallel to the real geometric surface. The implementation accounts for multiple internal reflections between the interfaces (including attenuation), but neglects parallax effects due to its (virtual) thickness. To create a such a thin glass material pass the type string “`thinGlass`†to `ospNewMaterial`. Its parameters are | Type | Name | Default | Description | |:------|:--------------------|--------:|:------------------------------------------------| | float | eta | 1.5 | index of refraction | | vec3f | attenuationColor | white | resulting color due to attenuation (linear RGB) | | float | attenuationDistance | 1 | distance affecting attenuation | | float | thickness | 1 | virtual thickness | Parameters of the ThinGlass material. For convenience the attenuation is controlled the same way as with the [Glass](#glass) material. Additionally, the color due to attenuation can be modulated with a [texture](#texture) `map_attenuationColor` ([texture transformations](#texture-transformations) are supported as well). If present, the color component of [geometries](#geometries) is also used for the attenuation color. The `thickness` parameter sets the (virtual) thickness and allows for easy exchange of parameters with the (real) [Glass](#glass) material; internally just the ratio between `attenuationDistance` and `thickness` is used to calculate the resulting attenuation and thus the material appearance.
Rendering of a ThinGlass material with red attenuation.
Example image of a colored window made with textured attenuation of the ThinGlass material.
### MetallicPaint The [path tracer](#path-tracer) offers a metallic paint material, consisting of a base coat with optional flakes and a clear coat. To create a MetallicPaint material pass the type string “`metallicPaint`†to `ospNewMaterial`. Its parameters are listed in the table below. | Type | Name | Default | Description | |:------|:------------|----------:|:--------------------------------------| | vec3f | baseColor | white 0.8 | color of base coat (linear RGB) | | float | flakeAmount | 0.3 | amount of flakes, in \[0–1\] | | vec3f | flakeColor | Aluminium | color of metallic flakes (linear RGB) | | float | flakeSpread | 0.5 | spread of flakes, in \[0–1\] | | float | eta | 1.5 | index of refraction of clear coat | Parameters of the MetallicPaint material. The color of the base coat `baseColor` can be textured by a [texture](#texture) `map_baseColor`, which also supports [texture transformations](#texture-transformations). If present, the color component of [geometries](#geometries) is also used for the color of the base coat. Parameter `flakeAmount` controls the proportion of flakes in the base coat, so when setting it to 1 the `baseColor` will not be visible. The shininess of the metallic component is governed by `flakeSpread`, which controls the variation of the orientation of the flakes, similar to the `roughness` parameter of [Metal](#metal). Note that the effect of the metallic flakes is currently only computed on average, thus individual flakes are not visible.
Rendering of a MetallicPaint material.
### Luminous The [path tracer](#path-tracer) supports the Luminous material which emits light uniformly in all directions and which can thus be used to turn any geometric object into a light source. It is created by passing the type string “`luminous`†to `ospNewMaterial`. The amount of constant radiance that is emitted is determined by combining the general parameters of lights: [`color` and `intensity`](#lights) (which essentially means that parameter `intensityQuantity` is not needed because it is always `OSP_INTENSITY_QUANTITY_RADIANCE`). | Type | Name | Default | Description | |:------|:-------------|--------:|:----------------------------------------| | vec3f | color | white | color of the emitted light (linear RGB) | | float | intensity | 1 | intensity of the light (a factor) | | float | transparency | 0 | material transparency | Parameters accepted by the Luminous material. The emission can be textured by passing a `map_color` [texture](#texture) handle, [texture transformations](#texture-transformations) are supported as well.
Rendering of a yellow Luminous material.
Texture ------- OSPRay currently implements two texture types (`texture2d` and `volume`) and is open for extension to other types by applications. More types may be added in future releases. To create a new texture use ``` cpp OSPTexture ospNewTexture(const char *type); ``` ### Texture2D The `texture2d` texture type implements an image-based texture, where its parameters are as follows | Type | Name | Description | |:--------------|:---------|:------------------------------------------------------------------------------------| | uint | format | `OSPTextureFormat` for the texture | | uint | filter | default `OSP_TEXTURE_FILTER_LINEAR`, alternatively `OSP_TEXTURE_FILTER_NEAREST` | | OSPData | data | the actual texel 2D [data](#data) | | uint / vec2ui | wrapMode | `OSPTextureWrapMode` for the texture coordinates s and t; supported wrap modes are: | | | | `OSP_TEXTURE_WRAP_REPEAT` (default) | | | | `OSP_TEXTURE_WRAP_MIRRORED_REPEAT` | | | | `OSP_TEXTURE_WRAP_CLAMP_TO_EDGE` | 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_RGBA16F | 16 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_RGB16F | 16 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_RA32F | 32 bit float two component red, alpha | | OSP_TEXTURE_R32F | 32 bit float single component red | | OSP_TEXTURE_RA16F | 16 bit float two component red, alpha | | OSP_TEXTURE_R16F | 16 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`. The size of the texture is inferred from the size of the 2D array `data`, which also needs have a compatible type to `format`. The texel data in `data` starts with the texels in the lower left corner of the texture image, like in OpenGL. Per default a texture fetch is filtered by performing bi-linear interpolation of the nearest 2×2 texels; if instead fetching only the nearest texel is desired (i.e., no filtering) then pass the `OSP_TEXTURE_FILTER_NEAREST` flag. Texturing with `texture2d` image textures requires [geometries](#geometries) with texture coordinates, e.g., a [mesh](#mesh) with `vertex.texcoord` provided. ### Volume Texture The `volume` texture type implements texture lookups based on 3D object coordinates of the surface hit point on the associated geometry. If the given hit point is within the attached volume, the volume is sampled and classified with the transfer function attached to the volume. This implements the ability to visualize volume values (as colored by a transfer function) on arbitrary surfaces inside the volume (as opposed to an isosurface showing a particular value in the volume). Its parameters are as follows | Type | Name | Description | |:--------------------|:-----------------|:------------------------------------------------------------| | OSPVolume | volume | [Volume](#volumes) used to generate color lookups | | OSPTransferFunction | transferFunction | [transfer function](#transfer-function) applied to `volume` | Parameters of `volume` texture type. TextureVolume can be used for implementing slicing of volumes with any geometry type. It enables coloring of the slicing geometry with a different transfer function than that of the sliced volume. ### Texture Transformations 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.*`â€). | 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 | translation | move texture in positive direction (right/up) | Parameters to define 2D texture coordinate transformations. Above parameters are combined into a single `affine2d` transformation matrix and the transformations are applied in the given order. Rotation, scale and translation are interpreted “texture centricâ€, i.e., their effect seen by an user are relative to the texture (although the transformations are applied to the texture coordinates). | Type | Name | Description | |:---------|:----------|:---------------------------------------------------------| | affine3f | transform | linear transformation (rotation, scale) plus translation | Parameter to define 3D volume texture transformations. Similarly, volume texture placement can also be modified by an `affine3f` transformation matrix. Cameras ------- To create a new camera of given type `type` use ``` cpp OSPCamera ospNewCamera(const char *type); ``` All cameras accept these parameters: | 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\] | | uint | 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`, `direction` and `up`. Additionally, an extra transformation `transform` can be specified, which will only be applied to 3D vectors (i.e., `position`, `direction` and `up`), but does *not* affect any sizes (e.g., `nearClip`, `apertureRadius`, or `height`). The same holds for the array of transformations `motion.transform` to achieve camera motion blur (in combination with `time` and `shutter`). OSPRay uses a right-handed coordinate system. The region of the camera sensor that is rendered to the image can be specified in normalized screen-space coordinates with `imageStart` (lower left corner) and `imageEnd` (upper right corner). This can be used, for example, to crop the image, to achieve asymmetrical view frusta, or to horizontally flip the image to view scenes which are specified in a left-handed coordinate system. Note that values outside the default range of \[0–1\] are valid, which is useful to easily realize overscan or film gate, or to emulate a shifted sensor. ### Perspective Camera The perspective camera implements a simple thin lens camera for perspective rendering, supporting optionally depth of field and stereo rendering (with the [path tracer](#path-tracer)). It is created by passing the type 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 | 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 | | uint | 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. Note that when computing the `aspect` ratio a potentially set image region (using `imageStart` & `imageEnd`) needs to be regarded as well. In architectural photography it is often desired for aesthetic reasons to display the vertical edges of buildings or walls vertically in the image as well, regardless of how the camera is tilted. Enabling the `architectural` mode achieves this by internally leveling the camera parallel to the ground (based on the `up` direction) and then shifting the lens such that the objects in direction `dir` are centered in the image. If finer control of the lens shift is needed use `imageStart` & `imageEnd`. Because the camera is now effectively leveled its image plane and thus the plane of focus is oriented parallel to the front of buildings, the whole façade appears sharp, as can be seen in the example images below. The resolution of the [framebuffer](#framebuffer) is not altered by `imageStart`/`imageEnd`.
Example image created with the perspective camera, featuring depth of field.
Enabling the architectural flag corrects the perspective projection distortion, resulting in parallel vertical edges.
Example 3D stereo image using stereoMode = OSP_STEREO_SIDE_BY_SIDE.
### Orthographic Camera The orthographic camera implements a simple camera with orthographic projection, without support for depth. It is created by passing the type string “`orthographic`†to `ospNewCamera`. In addition to the [general parameters](#cameras) understood by all cameras the orthographic camera supports the following special parameters: | Type | Name | Description | |:------|:-------|:------------------------------------------------------------| | float | height | size of the camera’s image plane in y, in world coordinates | | float | aspect | ratio of width by height of the frame | Additional parameters accepted by the orthographic camera. For convenience the size of the camera sensor, and thus the extent of the scene that is captured in the image, can be controlled with the `height` parameter. The same effect can be achieved with `imageStart` and `imageEnd`, and both methods can be combined. In any case, the `aspect` ratio needs to be set accordingly to get an undistorted image.
Example image created with the orthographic camera.
### Panoramic Camera The panoramic camera implements a simple camera with support for stereo rendering. It captures the complete surrounding with a latitude / longitude mapping and thus the rendered images should best have a ratio of 2:1. A panoramic camera is created by passing the type string “`panoramic`†to `ospNewCamera`. It is placed and oriented in the scene by using the [general parameters](#cameras) understood by all cameras. | Type | Name | Description | |:------|:-----------------------|:---------------------------------------------------------------------------| | uint | 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 | Additional parameters accepted by the panoramic camera.
Latitude / longitude map created with the panoramic camera.
Scene Hierarchy --------------- ### Groups 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, 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 parameter will be used as clipping geometries. Any supported geometry can be used for clipping[^6], the only requirement is that it has to distinctly partition space into clipping and non-clipping one. The use of clipping geometry that is not closed or infinite could result in rendering artifacts. User can decide which part of space is clipped by changing shading normals orientation with the `invertNormals` flag of the [GeometricModel](#geometricmodels). All geometries and volumes assigned to `geometry` or `volume` will be clipped. All clipping 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 | | OSPLight\[\] | light | NULL | [data](#data) array of [lights](#lights) | | bool | dynamicScene | false | tell Embree to use faster BVH build (slower ray traversal), otherwise optimized for 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. ### Instances Instances in OSPRay represent a single group’s placement into the world via a transform. To create and instance call ``` cpp OSPInstance ospNewInstance(OSPGroup); ``` The passed group can be `NULL` as long as the group to be instanced is passed as a parameter. If both a group is specified on object creation and as a parameter, the parameter value is used. If the parameter value is later removed, the group object passed on object creation is again used. | Type | Name | Default | Description | |:-------------|:-------------------|---------:|:------------------------------------------------------------------------------------------------------------------------------------------------------| | OSPGroup | group | | optional [group](#groups) object to be instanced | | 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) | | uint32 | id | -1u | optional user ID, for [framebuffer](#framebuffer) channel `OSP_FB_ID_INSTANCE` | Parameters understood by instances. ### World Worlds are a container of scene data represented by [instances](#instances). To create an (empty) world call ``` cpp OSPWorld ospNewWorld(); ``` Objects are placed in the world through an array of instances. Similar to [groups](#groups), the array of instances is optional: there is no need to create empty arrays if there are no instances (though there will be nothing to render). Applications can query the world (axis-aligned) bounding box after the world has been committed. To get this information, call ``` cpp OSPBounds ospGetBounds(OSPObject); ``` The result is returned in the provided `OSPBounds`[^7] struct: ``` cpp typedef struct { float lower[3]; float upper[3]; } OSPBounds; ``` This call can also take `OSPGroup` and `OSPInstance` as well: all other 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 | tell Embree to use faster BVH build (slower ray traversal), otherwise optimized for 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. Renderers --------- A renderer is the central object for rendering in OSPRay. Different renderers implement different features and support different materials. To create a new renderer of given type `type` use ``` cpp OSPRenderer ospNewRenderer(const char *type); ``` General parameters of all renderers are | Type | Name | Default | Description | |:----------------------|:------------------|------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------| | int | pixelSamples | 1 | samples per pixel, best results when a power of 2 | | int | maxPathLength | 20 | maximum ray recursion depth | | 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`) | | OSPMaterial\[\] | material | | optional [data](#data) array of [materials](#materials) which can be indexed by a [GeometricModel](#geometricmodels)’s `material` parameter | | uint | pixelFilter | `OSP_PIXELFILTER_GAUSS` | `OSPPixelFilterType` to select the pixel filter used by the renderer for antialiasing. Possible pixel filters are listed below. | | float | mipMapBias | 0 | bias for texture MIP-mapping, balancing between sharpness/aliasing and blurriness due to prefiltering | Parameters understood by all renderers. OSPRay’s renderers support a feature called adaptive accumulation, which accelerates progressive [rendering](#rendering) by stopping the rendering and refinement of image regions that have an estimated variance below the `varianceThreshold`. This feature requires a [framebuffer](#framebuffer) with an `OSP_FB_VARIANCE` channel. Per default the background of the rendered image will be transparent black, i.e., the alpha channel holds the opacity of the rendered objects. This eases transparency-aware blending of the image with an arbitrary background image by the application (via $ospray.rgb + appBackground.rgb⋅(1-ospray.alpha)$). The parameter `backgroundColor` or `map_backplate` can be used to already blend with a constant background color or backplate texture, respectively, (and alpha) during rendering. OSPRay renderers support depth composition with images of other renderers, for example to incorporate help geometries of a 3D UI that were rendered with OpenGL. The screen-sized [texture](#texture) `map_maxDepth` must have format `OSP_TEXTURE_R32F` and flag `OSP_TEXTURE_FILTER_NEAREST`. The fetched values are used to limit the distance of primary rays, thus objects of other renderers can hide objects rendered by OSPRay. OSPRay supports antialiasing in image space by using pixel filters, which are aligned around the center of a pixel. The size $w×w$ of 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 $\sigma = 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. OSPRay also antialiases textures with prefiltering and MIP-mapping, which can be adjusted with parameter `mipMapBias`. For final frame rendering with a high number of `pixelSamples` or accumulated frames `mipMapBias` can be lowered (e.g., set to -0.5 or -2) to result in sharper textures which are essentially anisotropically filtered. Conversely, for preview rendering with just a single sample per pixel a higher `mipMapBias` of 1 or 2 can reduce texture aliasing and increase rendering speed. ### SciVis Renderer The SciVis renderer is a fast ray tracer for scientific visualization which supports volume rendering and ambient occlusion (AO). It is created by passing the type string “`scivis`†to `ospNewRenderer`. In addition to the [general parameters](#renderer) understood by all renderers, the SciVis renderer supports the following parameters: | Type | Name | Default | Description | |:------|:-------------------|----------------:|:------------------------------------------------------------------------------------------------------------------------| | bool | shadows | false | whether to compute (hard) shadows | | int | aoSamples | 0 | number of rays per sample to compute ambient occlusion | | float | aoDistance | 1020 | maximum distance to consider for ambient occlusion | | float | volumeSamplingRate | 1 | sampling rate for volumes | | bool | visibleLights | false | whether light sources are potentially visible (as in the [path tracer](#path-tracer), regarding each light’s `visible`) | Special parameters understood by the SciVis renderer. Note that the intensity (and color) of AO is deduced from an [ambient light](#ambient-light) in the `lights` array.[^8] If `aoSamples` is zero (the default) then ambient lights cause ambient illumination (without occlusion). ### Ambient Occlusion Renderer This renderer supports only a subset of the features of the [SciVis renderer](#scivis-renderer) to gain performance. As the name suggest its main shading method is ambient occlusion (AO), [lights](#lights) are *not* considered at all. Volume rendering is supported. The Ambient Occlusion renderer is created by passing the type string “`ao`†to `ospNewRenderer`. In addition to the [general parameters](#renderer) understood by all renderers the following parameters are supported as well: | Type | Name | Default | Description | |:------|:-------------------|----------------:|:-------------------------------------------------------| | int | aoSamples | 1 | number of rays per sample to compute ambient occlusion | | float | aoDistance | 1020 | maximum distance to consider for ambient occlusion | | float | aoIntensity | 1 | ambient occlusion strength | | float | volumeSamplingRate | 1 | sampling rate for volumes | Special parameters understood by the Ambient Occlusion renderer. ### Path Tracer The path tracer supports soft shadows, indirect illumination and realistic materials. This renderer is created by passing the type string “`pathtracer`†to `ospNewRenderer`. In addition to the [general parameters](#renderer) understood by all renderers the path tracer supports the following special parameters: | Type | Name | Default | Description | |:------|:--------------------------|--------:|:------------------------------------------------------------------------------------------------------------------------------------------| | int | lightSamples | all | number of random light samples per path vertex, best results when a power of 2; per default all light sources are sampled | | bool | limitIndirectLightSamples | true | after the first non-specular (i.e., diffuse and glossy) path vertex take (at most) a single light sample (instead of `lightSamples` many) | | int | roulettePathLength | 5 | ray recursion depth at which to start Russian roulette termination | | int | maxScatteringEvents | 20 | maximum number of non-specular (i.e., diffuse and glossy) bounces | | float | maxContribution | ∞ | samples are clamped to this value before they are accumulated into the framebuffer | | bool | backgroundRefraction | false | allow for alpha blending even if background is seen through refractive objects like glass | Special parameters understood by the path tracer. The path tracer requires that [materials](#materials) are assigned to [geometries](#geometries), otherwise surfaces are treated as completely black. The path tracer supports [volumes](#volumes) with multiple scattering. The scattering albedo can be specified using the [transfer function](#transfer-function). Extinction is assumed to be spectrally constant. Framebuffer ----------- The framebuffer holds the rendered 2D image (and optionally auxiliary information associated with pixels). To create a new framebuffer object of given size `size` (in pixels), color format, and channels use ``` cpp OSPFrameBuffer ospNewFrameBuffer(int size_x, int size_y, OSPFrameBufferFormat format = OSP_FB_SRGBA, uint32_t frameBufferChannels = OSP_FB_COLOR); ``` 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 | Supported color formats of the framebuffer that can be passed to `ospNewFrameBuffer`, i.e., valid constants of type `OSPFrameBufferFormat`. 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 non-specular hit, as vec3f | | OSP_FB_ID_PRIMITIVE | primitive index of the first hit, as uint32 | | OSP_FB_ID_OBJECT | geometric/volumetric model `id`, if specified, or index in [group](#groups) of first hit, as uint32 | | OSP_FB_ID_INSTANCE | user defined [instance](#instances) `id`, if specified, or instance index of first hit, as uint32 | Framebuffer channels constants (of type `OSPFrameBufferChannel`), naming optional information the framebuffer can store. These values can be combined by bitwise OR when passed to `ospNewFrameBuffer`. If a certain channel value is *not* specified, the given buffer channel will not be present. Note that OSPRay makes a clear distinction between the *external* format of the framebuffer and the internal one: The external format is the format the user specifies in the `format` parameter; it specifies what color format OSPRay will eventually *return* the framebuffer to the application (when calling `ospMapFrameBuffer`): no matter what OSPRay uses internally, it will simply return a 2D array of pixels of that format, with possibly all kinds of reformatting, compression/decompression, etc., going on in-between the generation of the *internal* framebuffer and the mapping of the externally visible one. In particular, `OSP_FB_NONE` is a perfectly valid pixel format for a framebuffer that an application will never map. For example, an application driving a display wall may well generate an intermediate framebuffer and eventually transfer its pixel to the individual displays using an `OSPImageOperation` [image operation](#image-operation). The application can map the given channel of a framebuffer – and thus access the stored pixel information – via ``` cpp const void *ospMapFrameBuffer(OSPFrameBuffer, OSPFrameBufferChannel = OSP_FB_COLOR); ``` Note that `OSP_FB_ACCUM` or `OSP_FB_VARIANCE` cannot be mapped. The origin of the screen coordinate system in OSPRay is the lower left corner (as in OpenGL), thus the first pixel addressed by the returned pointer is the lower left pixel of the image. A previously mapped channel of a framebuffer can be unmapped by passing the received pointer `mapped` to ``` cpp void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer); ``` The individual channels of a framebuffer can be cleared with ``` cpp void ospResetAccumulation(OSPFrameBuffer); ``` This function will clear *all* accumulating buffers (`OSP_FB_VARIANCE`, `OSP_FB_NORMAL`, and `OSP_FB_ALBEDO`, if present) and resets the accumulation counter `accumID`. It is unspecified if the existing color and depth buffers are physically cleared when `ospResetAccumulation` is called. If `OSP_FB_VARIANCE` is specified, an estimate of the variance of the last accumulated frame can be queried with ``` cpp float ospGetVariance(OSPFrameBuffer); ``` Note this value is only updated after synchronizing with `OSP_FRAME_FINISHED`, as further described in [asynchronous rendering](#asynchronous-rendering). The estimated variance can be used by the application as a quality indicator and thus to decide whether to stop or to continue progressive rendering. The framebuffer takes a list of pixel operations to be applied to the image in sequence as an `OSPData`. The pixel operations will be run in the order they are in the array. | Type | Name | Description | |:----------------------|:---------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | OSPImageOperation\[\] | imageOperation | ordered sequence of image operations | | int | targetFrames | anticipated number of frames that will be accumulated for progressive refinement, used renderers to generate a blue noise sampling pattern; should be a power of 2, is always 1 without `OSP_FB_ACCUM`; default 0 (disabled) | Parameters accepted by the framebuffer. If the total number of frames to be accumulated is known, then `targetFrames` should be set, because then renderers can generate more pleasing blue noise patterns. Accumulation stops when `targetFrames` is reached. ### Image Operation Image operations are functions that are applied to every pixel of a frame. Examples include post-processing, filtering, blending, tone mapping, or sending tiles to a display wall. To create a new pixel operation of given type `type` use ``` cpp OSPImageOperation ospNewImageOperation(const char *type); ``` #### Tone Mapper The tone mapper is a pixel operation which implements a generic filmic tone mapping operator. Using the default parameters it approximates the Academy 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 | Filmic | Description | |:------|:----------|--------:|-------:|:-------------------------------------------------------------------------| | float | exposure | 1.0 | 1.0 | amount of light per unit area | | float | contrast | 1.6773 | 1.1759 | contrast (toe of the curve); typically is in \[1–2\] | | float | shoulder | 0.9714 | 0.9746 | highlight compression (shoulder of the curve); typically is in \[0.9–1\] | | float | midIn | 0.18 | 0.18 | mid-level anchor input; default is 18% gray | | float | midOut | 0.18 | 0.18 | mid-level anchor output; default is 18% gray | | float | hdrMax | 11.0785 | 6.3704 | maximum HDR input that is not clipped | | bool | acesColor | true | false | apply the ACES color transforms | Parameters accepted by the tone mapper. The column “Filmic†lists alternative values for the popular “Uncharted 2†tone mapping curve (note that that curve includes an exposure bias to match 18% middle gray). #### Denoiser OSPRay comes with a module that adds support for Intel® Open Image Denoise (OIDN). This is provided as an optional module as it creates an additional project dependency at compile time. The module implements a “`denoiser`†frame operation, which denoises the entire frame before the frame is completed. OIDN will automatically select the fastest device, using a GPU when available. The device selection be overridden by the environment variable `OIDN_DEFAULT_DEVICE`, possible values are `cpu`, `sycl`, `cuda`, `hip`, or a physical device ID | Type | Name | Description | |:-----|:-------------|:-------------------------------------------------------------------------------------------------------------------| | uint | quality | `OSPDenoiserQuality` for denoiser quality, default is | | | | `OSP_DENOISER_QUALITY_MEDIUM`: balanced quality/performance for interactive/real-time rendering; also allowed are: | | | | `OSP_DENOISER_QUALITY_LOW`: high performance, for interactive/real-time preview rendering | | | | `OSP_DENOISER_QUALITY_HIGH`: high quality, for final frame rendering | | bool | denoiseAlpha | whether to denoise the alpha channel as well, default false | Parameters accepted by the denoiser. Rendering --------- ### Asynchronous Rendering Rendering is by default asynchronous (non-blocking), and is done by combining a framebuffer, renderer, camera, and world. What to render and how to render it depends on the renderer’s parameters. If the framebuffer supports accumulation (i.e., it was created with `OSP_FB_ACCUM`) then successive calls to `ospRenderFrame` will progressively refine the rendered image (until `targetFrames` is reached). To start an render task, use ``` cpp OSPFuture ospRenderFrame(OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); ``` This returns an `OSPFuture` handle, which can be used to synchronize with the application, cancel, or query for progress of the running task. When `ospRenderFrame` is called, there is no guarantee when the associated task will begin execution. Progress of a running frame can be queried with the following API function ``` cpp float ospGetProgress(OSPFuture); ``` This returns the approximated progress of the task in \[0-1\]. Applications can cancel a currently running asynchronous operation via ``` cpp void ospCancel(OSPFuture); ``` Applications can wait on the result of an asynchronous operation, or choose to only synchronize with a specific event. To synchronize with an `OSPFuture` use ``` cpp 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 | Supported events that can be passed to `ospWait`. Currently only rendering can be invoked asynchronously. However, future releases of OSPRay may add more asynchronous versions of API calls (and thus return `OSPFuture`). Applications can query whether particular events are complete with ``` cpp int ospIsReady(OSPFuture, OSPSyncEvent = OSP_TASK_FINISHED); ``` As the given running task runs (as tracked by the `OSPFuture`), applications can query a boolean \[0, 1\] result if the passed event has been completed. Applications can query how long an async task ran with ``` cpp float ospGetTaskDuration(OSPFuture); ``` This returns the wall clock execution time of the task in seconds. If the task is still running, this will block until the task is completed. This is useful for applications to query exactly how long an asynchronous task executed without the overhead of measuring both task execution + synchronization by the calling application. ### Synchronous Rendering For convenience in certain use cases, `ospray_util.h` provides a synchronous version of `ospRenderFrame`: ``` cpp float ospRenderFrameBlocking(OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); ``` This version is the equivalent of: ``` cpp ospRenderFrame ospWait(f, OSP_TASK_FINISHED) return ospGetVariance(fb) ``` This version is closest to `ospRenderFrame` from OSPRay v1.x. ### Rendering and ospCommit The use of either `ospRenderFrame` or `ospRenderFrameBlocking` requires that all objects in the scene being rendered have been committed before rendering occurs. If a call to `ospCommit` happens while a frame is rendered, the result is undefined behavior and should be avoided. ### Picking To get the world-space position of the geometry (if any) seen at \[0–1\] normalized screen-space pixel coordinates `screenPos_x` and `screenPos_y` use ``` cpp void ospPick(OSPPickResult *, OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, float screenPos_x, float screenPos_y); ``` The result is returned in the provided `OSPPickResult` struct: ``` cpp typedef struct { int hasHit; float worldPosition[3]; OSPInstance instance; OSPGeometricModel model; uint32_t primID; } OSPPickResult; ``` Note that `ospPick` considers exactly the same camera of the given renderer that is used to render an image, thus matching results can be expected. If the camera supports depth of field then the center of the lens and thus the center of the circle of confusion is used for picking. Note that the caller needs to `ospRelease` the `instance` and `model` handles of `OSPPickResult` once the information is not needed anymore. Modules and Devices =================== CPU --- The CPU module is implicitly loaded and the `cpu` device is automatically used if no other options are specified. GPU (Beta) ---------- To use the GPU for rendering load the `gpu` module and select the `gpu` device: ``` sh ./ospExamples --osp:load-modules=gpu --osp:device=gpu ``` or via explicit device creation by the application: ``` cpp ospLoadModule("gpu"); OSPDevice dev = ospNewDevice("gpu"); ospDeviceCommit(dev); ospSetCurrentDevice(dev); ``` | Type | Name | Description | |:--------|:------------|:-------------| | void \* | syclContext | SYCL context | | void \* | syclDevice | SYCL device | Parameters specific to the `gpu` device. Applications can set their SYCL context and device to share device memory with OSPRay or to control which device should be used (e.g., in case multiple GPUs are present). If neither parameter is set, the `gpu` device will automatically create a context internally and select a GPU (that selection can be influenced via environment variable `ONEAPI_DEVICE_SELECTOR`, see [Intel oneAPI DPC++ Compiler documentation](https://intel.github.io/llvm-docs/EnvironmentVariables.html#oneapi-device-selector)). Compile times for just in time compilation (JIT compilation) can be large. To resolve this issue we recommend enabling persistent JIT compilation caching inside your application before the SYCL device is created, by setting environment variables `SYCL_CACHE_PERSISTENT=1` (and optionally `SYCL_CACHE_DIR=` to some proper directory where the JIT cache should get stored). To reduce GPU memory allocation overhead when rendering scenes with many objects (geometries, instances, etc.), memory pooling should be enabled by setting the environment variable `SYCL_PI_LEVEL_ZERO_USM_ALLOCATOR="1;0;shared:1M,0,2M"`. See [Intel oneAPI DPC++ Compiler documentation](https://intel.github.io/llvm-docs/EnvironmentVariables.html#debugging-variables-for-level-zero-plugin) for more details. ### Known Issues The following features are not implemented yet or are not working correctly on the GPU device: - Multiple volumes in the scene - Clipping - Motion blur - Subdivision surfaces - Progress reporting via `ospGetProgress` or canceling the frame via `ospCancel` - Picking via `ospPick` - Adaptive accumulation via `OSP_FB_VARIANCE` and `varianceThreshold` - Framebuffer channels `OSP_FB_ID_*` (id buffers) - Experimental support for shared device-only data, works only for `structuredRegular` volume There will be some delay on start-up as the kernel code is JIT compiled for the device, and similar pauses when changing the scene configuration, because the kernel specialized and re-compiled. For some combination of compiler, GPU driver and scene the rendered images might show artifacts (e.g., vertical lines or small blocks). Distributed Rendering with MPI ------------------------------ The purpose of OSPRay’s MPI modules is to provide distributed rendering capabilities for OSPRay. The modules enables image- and data-parallel rendering across HPC clusters using MPI, allowing applications to transparently distribute rendering work, or to render data sets which are too large to fit in memory on a single machine. OSPRay provides multiple MPI modules that expose different distributed rendering capabilities. The `mpi_offload` module provides image-parallel rendering through the `mpiOffload` device; it enables OSPRay applications written for local rendering to be replicated across multiple nodes to distribute the rendering work without code changes. And the `mpi_distributed_cpu` and `mpi_distributed_gpu` modules provides data-parallel rendering through the `mpiDistributed` device, which allows MPI distributed applications to use OSPRay for distributed rendering. Each rank using the `mpiDistributed` device can render an independent piece of a global data set, or perform hybrid rendering where ranks partially or completely share data. The `mpiDistributed` device’s image-parallel rendering support can be used to accelerate data loading for image-parallel applications, where all ranks load the same data from a shared disk and then perform image-parallel rendering on the replicated data, as if the `mpiOffload` device where being used. ### MPI Offload Rendering The `mpiOffload` device can be used to distribute image rendering tasks across a cluster without requiring modifications to the application itself. Existing applications using OSPRay for local rendering simply be passed command line arguments to load the module and indicate that the `mpiOffload` device should be used for image-parallel rendering. To load the module, pass `--osp:load-modules=mpi_offload`, to select the MPIOffloadDevice, pass `--osp:device=mpiOffload`. For example, the `ospExamples` application can be run as: ``` sh mpirun -n ./ospExamples --osp:load-modules=mpi_offload --osp:device=mpiOffload ``` and will automatically distribute the image rendering tasks among the corresponding `N` nodes. Note that in this configuration rank 0 will act as a master/application rank, and will run the user application code but not perform rendering locally. Thus, a minimum of 2 ranks are required, one master to run the application and one worker to perform the rendering. Running with 3 ranks for example would now distribute half the image rendering work to rank 1 and half to rank 2. If more control is required over the placement of ranks to nodes, or you want to run a worker rank on the master node as well you can run the application and the `ospray_mpi_worker` program through MPI’s MPMD mode. The `ospray_mpi_worker` will load the MPI module and select the offload device by default. ``` sh mpirun -n 1 ./ospExamples --osp:load-modules=mpi_offload --osp:device=mpiOffload \ : -n ./ospray_mpi_worker ``` If initializing the `mpiOffload` device manually, or passing parameters through the command line, the following parameters can be set: | Type | Name | Default | Description | |:-------|:------------------------|--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | string | mpiMode | mpi | The mode to communicate with the worker ranks. `mpi` will assume you are launching the application and workers in the same mpi command (or split launch command). `mpi` is the only supported mode | | uint | maxCommandBufferEntries | 8192 | Set the max number of commands to buffer before submitting the command buffer to the workers | | uint | commandBufferSize | 512 MiB | Set the max command buffer size to allow. Units are in MiB. Max size is 1.8 GiB | | uint | maxInlineDataSize | 32 MiB | Set the max size of an OSPData which can be inline’d into the command buffer instead of being sent separately. Max size is half the commandBufferSize. Units are in MiB | Parameters specific to the `mpiOffload` device. The `maxCommandBufferEntries`, `commandBufferSize`, and `maxInlineDataSize` can also be set via the environment variables: `OSPRAY_MPI_MAX_COMMAND_BUFFER_ENTRIES`, `OSPRAY_MPI_COMMAND_BUFFER_SIZE`, and `OSPRAY_MPI_MAX_INLINE_DATA_SIZE`, respectively. The `mpiOffload` device uses a dynamic load balancer by default. If you wish to use a static load balancer you can do so by setting the `OSPRAY_STATIC_BALANCER` environment variable to 1. For the worker ranks to create GPU devices instead of the default CPU devices set the environment variable `OSPRAY_MPI_DISTRIBUTED_GPU`, e.g., ``` sh export OSPRAY_MPI_DISTRIBUTED_GPU=1 ``` or ``` sh mpiexec -genv OSPRAY_MPI_DISTRIBUTED_GPU 1 \ -n 1 ./ospExamples --osp:load-modules=mpi_offload --osp:device=mpiOffload \ : -n 2 ./ospray_mpi_worker ``` The `mpiOffload` device does not support multiple init/shutdown cycles. Thus, to run `ospBenchmark` for this device make sure to exclude the init/shutdown test by passing `--benchmark_filter=-ospInit_ospShutdown` through the command line. ### MPI Distributed Rendering While MPI Offload rendering is used to transparently distribute rendering work without requiring modification to the application, MPI Distributed rendering is targeted at use of OSPRay within MPI-parallel applications. The MPI distributed device can be selected by loading the `mpi_distributed_cpu` module for CPU rendering or `mpi_distributed_gpu` for GPU rendering, and manually creating and using an instance of the `mpiDistributed` device, for example: ``` cpp ospLoadModule("mpi_distributed_cpu"); OSPDevice mpiDevice = ospNewDevice("mpiDistributed"); ospDeviceCommit(mpiDevice); ospSetCurrentDevice(mpiDevice); ``` Your application can either initialize MPI before-hand, ensuring that `MPI_THREAD_SERIALIZED` or higher is supported, or allow the device to initialize MPI on commit. Thread multiple support is required if your application will make MPI calls while rendering asynchronously with OSPRay. When using the distributed device each rank can specify independent local data using the OSPRay API, as if rendering locally. However, when calling `ospRenderFrameAsync` the ranks will work collectively to render the data. The distributed device supports both image-parallel, where the data is replicated, and data-parallel, where the data is distributed, rendering modes. The `mpiDistributed` device will by default use each rank in `MPI_COMM_WORLD` as a render worker; 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 | Parameters specific to the `mpiDistributed` device. | Type | Name | Default | Description | |:----------|:-------|--------:|:-------------------------------------------------------------------------------------| | box3f\[\] | region | NULL | A list of bounding boxes which bound the owned local data to be rendered by the rank | Parameters specific to the distributed `OSPWorld`. | Type | Name | Default | Description | |:------|:-------------------|----------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | int | aoSamples | 0 | The number of AO samples to take per-pixel | | float | aoDistance | 1020 | The AO ray length to use. Note that if the AO ray would have crossed a rank boundary and ghost geometry is not available, there will be visible artifacts in the shading | | float | volumeSamplingRate | 1 | sampling rate for volumes | Parameters specific to the `mpiRaycast` renderer. #### Image Parallel Rendering in the MPI Distributed Device If all ranks specify exactly the same data, the distributed device can be used for image-parallel rendering. This works identical to the offload device, except that the MPI-aware application is able to load data in parallel on each rank rather than loading on the master and 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 [ospMPIDistribTutorialReplicated](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialReplicated.cpp) for an example. #### Data Parallel Rendering in the MPI Distributed Device The MPI Distributed device also supports data-parallel rendering with sort-last compositing. Each rank can specify a different piece of data, as long as the bounding boxes of each rank’s data are non-overlapping. The rest of the scene setup is similar to local rendering; however, for distributed rendering only the `mpiRaycast` renderer is supported. This renderer implements a subset of the `scivis` rendering features which are suitable for implementation in a distributed environment. By default the aggregate bounding box of the instances in the local world will be used as the bounds of that rank’s data. However, when using ghost zones for volume interpolation, geometry or ambient occlusion, each rank’s data can overlap. To clip these non-owned overlap 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 [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 rendering, where multiple ranks can share a single piece of data. For 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 [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 Calling `ospPick` in the distributed device will find and return the closest global object at the screen position on the rank that owns that object. The other ranks will report no hit. Picking in the distributed device takes into account data clipping applied through the `regions` parameter to avoid picking ghost data. ### Interaction with User Modules The MPI Offload rendering mode trivially supports user modules, with the caveat that attempting to share data directly with the application (e.g., passing a `void *` or other tricks to the module) will not work in a distributed environment. Instead, use the `ospNewSharedData` API to share data from the application with OSPRay, which will in turn be copied over the network to the workers. The MPI Distributed device also supports user modules, as all that is required for compositing the distributed data are the bounds of each rank’s local data. MultiDevice ----------- The multidevice module is an experimental OSPRay device type that renders images by delegating off pixel tiles to a number of internal delegate OSPRay devices. 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_cpu` extension and create a multidevice for rendering instead of the default CPU device. One example in a bash like shell is as follows: ``` sh OSPRAY_NUM_SUBDEVICES=6 ./ospTutorial --osp:load-modules=multidevice_cpu --osp:device=multidevice ``` Note that the multidevice currently does not support `OSPImageOperation`s for denoising nor tone mapping. Tutorials ========= ospTutorial ----------- A minimal working example demonstrating how to use OSPRay can be found at [`apps/tutorials/ospTutorial.c`](https://github.com/ospray/ospray/blob/master/apps/ospTutorial/ospTutorial.c)[^9]. An example of building `ospTutorial.c` with CMake can be found in [`apps/tutorials/ospTutorialFindospray/`](https://github.com/ospray/ospray/tree/master/apps/ospTutorial/ospTutorialFindospray). To build the tutorial on Linux, build it in a build directory with ``` sh gcc -std=c99 ../apps/ospTutorial/ospTutorial.c \ -I ../ospray/include -L . -lospray -Wl,-rpath,. -o ospTutorial ``` On Windows build it can be build manually in a “build_directory\\\$Configuration†directory with ``` sh cl ..\..\apps\ospTutorial\ospTutorial.c -I ..\..\ospray\include -I ..\.. ospray.lib ``` Running `ospTutorial` will create two images of two triangles, rendered with the Scientific Visualization renderer with full Ambient Occlusion. The first image `firstFrame.ppm` shows the result after one call to `ospRenderFrame` – jagged edges and noise in the shadow can be seen. Calling `ospRenderFrame` multiple times enables progressive refinement, resulting in antialiased edges and converged shadows, shown after ten frames in the second image `accumulatedFrames.ppm`. ![First frame.](https://ospray.github.io/images/tutorial_firstframe.png) ![After accumulating ten frames.](https://ospray.github.io/images/tutorial_accumulatedframe.png) ospExamples ----------- Apart from tutorials, `OSPRay` comes with a C++ app called [`ospExamples`](https://github.com/ospray/ospray/tree/master/apps/ospExamples) which is an elaborate easy-to-use tutorial, with a single interface to try various `OSPRay` features. It is aimed at providing users with multiple simple scenes composed of basic geometry types, lights, volumes etc. to get started with OSPRay quickly. `ospExamples` app runs a `GLFWOSPRayWindow` instance that manages instances of the camera, framebuffer, renderer and other OSPRay objects necessary to render an interactive scene. The scene is rendered on a `GLFW` window with an `imgui` GUI controls panel for the user to manipulate the scene at runtime. The application is located in [`apps/ospExamples/`](https://github.com/ospray/ospray/tree/master/apps/ospExamples) directory and can be built with CMake. It can be run from the build directory via: ./ospExamples The command line parameter is optional however.
ospExamples application with default boxes scene.
### Scenes Different scenes can be selected from the `scenes` dropdown and each scene corresponds to an instance of a special `detail::Builder` struct. Example builders are located in [`apps/common/ospray_testing/builders/`](https://github.com/ospray/ospray/tree/master/apps/common/ospray_testing/builders). These builders provide a usage guide for the OSPRay scene hierarchy and OSPRay API in the form of `cpp` wrappers. They instantiate and manage objects for the specific scene like `cpp::Geometry`, `cpp::Volume`, `cpp::Light` etc. The `detail::Builder` base struct is mostly responsible for setting up OSPRay `world` and objects common in all scenes (for example lighting and ground plane), which can be conveniently overridden in the derived builders. ### Renderer This app comes with four [renderer](#renderers) options: `scivis`, `pathtracer`, `ao` and `debug`. The app provides some common rendering controls like `pixelSamples` and other more specific to the renderer type like `aoSamples` for the `scivis` and `ao` renderer or `maxPathLength` for the `pathtracer`. The sun-sky lighting can be used in a sample scene by enabling the `renderSunSky` option of the `pathtracer` renderer. It allows the user to change `turbidity` and `sunDirection`.
Rendering an evening sky with the renderSunSky option.
ospMPIDistribTutorial --------------------- A minimal working example demonstrating how to use OSPRay for rendering distributed data can be found at [`modules/mpi/tutorials/ospMPIDistribTutorial.c`](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorial.c)[^10]. The compilation process via CMake is the similar to [`apps/tutorials/ospTutorialFindospray/`](https://github.com/ospray/ospray/tree/master/apps/ospTutorial/ospTutorialFindospray), with the addition of finding and linking MPI. To build the tutorial on Linux, build it in a build directory with ``` sh mpicc -std=c99 ../modules/mpi/tutorials/ospMPIDistribTutorial.c \ -I ../ospray/include -L . -lospray -Wl,-rpath,. -o ospMPIDistribTutorial ``` On Windows build it can be build manually in a “build_directory\\\$Configuration†directory with ``` sh cl ..\..\modules\mpi\tutorials\ospMPIDistribTutorial.c -I ..\..\ospray\include -I ..\.. ospray.lib ``` The MPI module does not need to be linked explicitly, as it is loaded as a module at runtime.
The first frame output by the ospMPIDistribTutorial or C++ tutorial with 4 ranks.
The accumulated frame output by the ospMPIDistribTutorial or C++ tutorial with 4 ranks.
ospMPIDistribTutorialSpheres and ospMPIDistribTutorialVolume ------------------------------------------------------------ The spheres and volume distributed tutorials are built as part of the MPI tutorials when building OSPRay with the MPI module and tutorials enabled. These tutorials demonstrate using OSPRay to render distributed data sets where each rank owns some subregion of the data, and displaying the output in an interactive window. The domain is distributed in a grid among the processes, each of which will generate a subset of the data corresponding to its subdomain. In `ospMPIDistribTutorialSpheres`, each process generates a set of spheres within its assigned domain. The spheres are colored from dark to light blue, where lighter colors correspond to higher ranks.
Running ospMPIDistribTutorialSpheres on 4 ranks.
In `ospMPIDistribTutorialVolume`, each process generates a subbrick of volume data, which is colored by its rank.
Running ospMPIDistribTutorialVolume on 4 ranks.
ospMPIDistribTutorialPartialRepl -------------------------------- The partially replicated MPI tutorial demonstrates how to use OSPRay’s distributed rendering capabilities to render data sets that are partially replicated among the processes. Each pair of ranks generates the same volume brick, allowing them to subdivide the rendering workload between themselves. For example, when run with two ranks, each will generate the same brick and be responsible for rendering half of the image tiles it projects to. When run with four ranks, the pairs of ranks 0,1 and 2,3 will generate the same data and divide the rendering workload for that data among themselves. The image work subdivision happens automatically, based on which ranks specify the same bounding box for their data, as demonstrated in the tutorial. The partially replicated distribution is useful to support load-balanced rendering of data sets that are too large to be fully replicated among the processes, but are small enough to be partially replicated among them. ospMPIDistribTutorialReplicated ------------------------------- The replicated MPI tutorial demonstrates how OSPRay’s distributed rendering capabilities can be used to render data sets that are fully replicated among the ranks with advanced illumination effects. In this case, although the processes are run MPI parallel, each rank specifies the exact same data. OSPRay’s MPI parallel renderer will detect that the data is replicated in this case and use the same image-parallel rendering algorithms employed in the MPI offload rendering configuration to render the data. This image-parallel rendering algorithm supports all rendering configurations that are used in local rendering, e.g., path tracing, to provide high-quality images. The replicated MPI tutorial supports the same scenes and parameters as the [`ospExamples`](#ospexamples) app described above. This mode can be useful when high-quality rendering is desired and it is possible to copy the entire data set on to each rank, or to accelerate loading of a large model by leveraging a parallel file system. [^1]: This file is usually in `${install_location}/[lib|lib64]/cmake/ospray-${version}/`. If CMake does not find it automatically, then specify its location in variable `ospray_DIR` (either an environment variable or CMake variable). [^2]: The number of items to be copied is defined by the size of the source array. [^3]: For consecutive memory addresses the x-index of the corresponding voxel changes the quickest. [^4]: actually a parallelogram [^5]: respectively $(127, 127, 255)$ for 8 bit textures and $(32767, 32767, 65535)$ for 16 bit textures [^6]: including spheres, boxes, infinite planes, closed meshes, closed subdivisions and curves [^7]: `OSPBounds` has essentially the same layout as the `OSP_BOX3F` [`OSPDataType`](#data). [^8]: If there are multiple ambient lights then their contribution is added. [^9]: A C++ version that uses the C++ convenience wrappers of OSPRay’s C99 API via [`include/ospray/ospray_cpp.h`](https://github.com/ospray/ospray/blob/master/ospray/include/ospray/ospray_cpp.h) is available at [`apps/tutorials/ospTutorial.cpp`](https://github.com/ospray/ospray/blob/master/apps/ospTutorial/ospTutorial.cpp). [^10]: A C++ version that uses the C++ convenience wrappers of OSPRay’s C99 API via [`include/ospray/ospray_cpp.h`](https://github.com/ospray/ospray/blob/master/ospray/include/ospray/ospray_cpp.h) is available at [`modules/mpi/tutorials/ospMPIDistribTutorial.cpp`](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorial.cpp). RenderKit-ospray-85af292/SECURITY.md000066400000000000000000000010101464752671100170540ustar00rootroot00000000000000Security Policy =============== Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. Reporting a Vulnerability ------------------------- Please [report any security vulnerabilities][guidelines] in this project utilizing the [guidelines here][guidelines]. [guidelines]: https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html "Vulnerability Handling Guidelines" RenderKit-ospray-85af292/STYLEGUIDE.md000066400000000000000000000160001464752671100172700ustar00rootroot00000000000000OSPRay Style Guide ================== This document discusses the project's expectations on C++ and ISPC style. In general, the items discussed are meant to be a guide and not be overly strict. However, deviations from this document should be supported with technical reasoning. This document is relatively simple and meant as a "quick overview" of expectations for OSPRay. A more complete set of guidelines for all of C++ can be found in the [ISO C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md). Documentation ------------- In general, comments in code should describe "why" not "what". Code documentation should be in terms of C++ style single-line comments or multi-line C style comments. Avoid Doxygen-style code documentation, this is deprecated. When adding or updating public API definitions, update the corresponding `doc/api.md` documentation as part of your merge request. This keeps our documentation always current, and minimizes the need for audits at release time. Markdown files (`.md`) should use a 72 column limit for running text, exceptions are URLs or example code (i.e. preformatted sections in backticks). General Code Goals ------------------ In all code, the overall goal is to make interfaces "easy to use correctly" and "difficult to use incorrectly". Some characteristics that make code better are: - Keep reasoning as local as possible - Descriptive names - Short functions - Single functions/abstractions for repetitive concepts (less copy/paste) - Compile errors over runtime errors We have a number of small, single-purpose abstractions in `rkcommon` that aide in the above goals. It is expected for contributions to first try and use those constructs before implementing their own. Lastly, it is expected that code is formatted using the provided `.clang-format` config found in the root of the repository, e.g. by running `git-clang-format` (which also avoids changes which are only due to formatting). Consider to pre-format very long strings using C++11 raw string literals. NOTE: Both C++ and ISPC files can be formatted with clang-format. Naming conventions for public API --------------------------------- - Prefer enums over string parameters. - Parameter and object names are camelCase (e.g. `metallicPaint`) - Parameter names are singular, even if it is an array (e.g. `index`, `material`) - Data belonging together like the members of an array of structs, which are passed as struct of arrays, have a common prefix. For example `vertex.color` and `vertex.normals` - Switches (bools) name just what they switch, e.g. `shadows` (not `shadowsEnabled` nor `enableShadows`, nor `useShadows`) C++ Usage Guidelines -------------------- C++ is a big language, so the following are things that we prefer to see in OSPRay: ### Memory Management, Object Lifetimes, and Pointers - For collections, prefer STL containers over C arrays, specifically `std::vector` and `rkcommon::containers::AlignedVector`. - Prefer smart pointers to manage memory over raw `new` and `delete`. - Prefer the usage of `std::unique_ptr` to manage heap objects, until memory lifetimes must be managed by more than one observer. - Prefer constructing smart pointers with `rkcommon::make_unique<>` and `std::make_shared<>` over using `new`. - Avoid globals and `std::shared_ptr` that cross translation units. - Prefer global scope variables to be marked `static`. - Prefer functions to access global data in another translation unit over marking them as `extern`. - Keep raw pointer usage local, either in a function or in a single cpp file. - Prefer the usage of references over pointers for cases where `nullptr` is not a valid value. - Prefer using `rkcommon::utility::OnScopeExit` to robustly cleanup non-trivial objects in a function. - Avoid constructing `static` data that requires initialization ordering with other `static` data. ### Designing Types (classes/structs) - Define empty default constructors with `= default;`, not with an empty `{}`. - Use the `virtual` keyword only to mark that child classes are expected to override, not that the function is overriding a parent method. - Always use the `override` keyword where appropriate. - Prefer to write `const` functions by default. - Prefer implementing inline member functions below the definition of the class or struct. This makes classes easier to read by avoiding unnecessary implementation details when reading the class interface. - Implement `begin()` and `end()` iterators for types which abstract collections. - Consider whether the type should be move-only (ex: `std::unique_ptr`) or copyable. - Prefer `= delete;` syntax to delete constructors over marking them `private`. - Prefer giving all applicable member values inlined default values. - Only populate values in constructor initialization if the value is different than the default or is being set by a constructor parameter. - Only mark methods as `virtual` if the class is intended to be in an inheritance hierarchy. - Always implement a `virtual` destructor, even if it's `= default;`. ### Loops, STL Algorithms, and Threading - Prefer the usage of an algorithm call over implementing a raw loop. - Prefer making multi-STL algorithm functions their own function with a name. - Prefer using `rkcommon::tasking` constructs instead of raw threads. - Prefer range-based for loops over indexing for loops where possible. - Avoid shared mutable state in parallel code (requires synchronization). - Capture type preference for lambda functions should be `[]` → `[&]` → `[=]`. ### Templates - Prefer to constrain template types to only relevant types using `static_assert()` and type traits. - Use `std::forward` when passing universal references (`T&&`) to other templates. - Only use SFINAE when necessary, and try to keep its usage as simple as possible. ISPC Usage ---------- The following are concerns specific to ISPC: - Prefer using `uniform` variables. The point of ISPC is to have varying data, but uniform values are more efficient than replicated varying values. - Avoid writing unnecessary `uniform` and `varying` keywords. Examples: ``` {.cpp} varying float f; // 'varying' is redundant, variables are varying by default uniform float *p; // 'uniform' is redundant, pointers point to uniform by default ``` - Prefer omitting `uniform`/`varying` qualifiers for structs. Only apply them if they need to be consistently the same for both `uniform` and `varying` instances of the struct. ### OSPRay ISPCDevice Specific Design Choices - Prefer to use Embree C API bindings over ISPC where possible. - Prefer to throw exceptions when an object is found to be invalid during `commit()`. - Prefer setting ISPC-side values in a single `set()` call over many single value setting functions. - Minimize the number of alias names given to both object types and parameters. RenderKit-ospray-85af292/apps/000077500000000000000000000000001464752671100162365ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/CMakeLists.txt000066400000000000000000000012671464752671100210040ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_dependent_option( OSPRAY_APPS_ENABLE_GLM "Build ospray_cpp glm tests/tutorial" OFF "OSPRAY_ENABLE_APPS_TESTING OR OSPRAY_ENABLE_APPS_TUTORIALS" OFF ) # Find GLM here for both ospTutorialGLM and ospTestSuite if (OSPRAY_APPS_ENABLE_GLM) find_package(glm REQUIRED) if(TARGET glm::glm) set(GLM_TARGET glm::glm) else() set(GLM_TARGET glm) endif() endif() if (OSPRAY_ENABLE_APPS_EXAMPLES) # prefer libGL over libOpenGl for better compatibility with SWR set(OpenGL_GL_PREFERENCE "LEGACY") find_package(OpenGL 3 REQUIRED) find_package(glfw3 REQUIRED) endif() add_all_subdirectories() RenderKit-ospray-85af292/apps/common/000077500000000000000000000000001464752671100175265ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/CMakeLists.txt000066400000000000000000000003561464752671100222720ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 if (NOT OSPRAY_ENABLE_APPS_BENCHMARK AND NOT OSPRAY_ENABLE_APPS_EXAMPLES AND NOT OSPRAY_ENABLE_APPS_TESTING) return() endif() add_all_subdirectories() RenderKit-ospray-85af292/apps/common/arcball_camera/000077500000000000000000000000001464752671100224365ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/arcball_camera/ArcballCamera.cpp000066400000000000000000000061601464752671100256160ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ArcballCamera.h" ArcballCamera::ArcballCamera(const rkcommon::math::box3f &worldBounds, const rkcommon::math::vec2i &windowSize) : zoomSpeed(1), invWindowSize( rkcommon::math::vec2f(1.0) / rkcommon::math::vec2f(windowSize)), centerTranslation(rkcommon::math::one), translation(rkcommon::math::one), rotation(rkcommon::math::one) { rkcommon::math::vec3f diag = worldBounds.size(); zoomSpeed = rkcommon::math::max(length(diag) / 150.0, 0.001); diag = rkcommon::math::max(diag, rkcommon::math::vec3f(0.3f * length(diag))); centerTranslation = rkcommon::math::AffineSpace3f::translate(-worldBounds.center()); translation = rkcommon::math::AffineSpace3f::translate( rkcommon::math::vec3f(0, 0, length(diag))); updateCamera(); } void ArcballCamera::rotate( const rkcommon::math::vec2f &from, const rkcommon::math::vec2f &to) { rotation = screenToArcball(to) * screenToArcball(from) * rotation; updateCamera(); } void ArcballCamera::zoom(float amount) { amount *= zoomSpeed; translation = rkcommon::math::AffineSpace3f::translate( rkcommon::math::vec3f(0, 0, amount)) * translation; updateCamera(); } void ArcballCamera::pan(const rkcommon::math::vec2f &delta) { const rkcommon::math::vec3f t = rkcommon::math::vec3f( -delta.x * invWindowSize.x, delta.y * invWindowSize.y, 0); const rkcommon::math::vec3f worldt = translation.p.z * xfmVector(invCamera, t); centerTranslation = rkcommon::math::AffineSpace3f::translate(worldt) * centerTranslation; updateCamera(); } rkcommon::math::vec3f ArcballCamera::eyePos() const { return xfmPoint(invCamera, rkcommon::math::vec3f(0, 0, 1)); } rkcommon::math::vec3f ArcballCamera::center() const { return -centerTranslation.p; } rkcommon::math::vec3f ArcballCamera::lookDir() const { return xfmVector(invCamera, rkcommon::math::vec3f(0, 0, 1)); } rkcommon::math::vec3f ArcballCamera::upDir() const { return xfmVector(invCamera, rkcommon::math::vec3f(0, 1, 0)); } rkcommon::math::AffineSpace3f ArcballCamera::transform() const { return invCamera; } void ArcballCamera::updateCamera() { const rkcommon::math::AffineSpace3f rot = rkcommon::math::LinearSpace3f(rotation); const rkcommon::math::AffineSpace3f camera = translation * rot * centerTranslation; invCamera = rcp(camera); } void ArcballCamera::setRotation(rkcommon::math::quatf q) { rotation = q; updateCamera(); } void ArcballCamera::updateWindowSize(const rkcommon::math::vec2i &windowSize) { invWindowSize = rkcommon::math::vec2f(1) / rkcommon::math::vec2f(windowSize); } 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::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::quatf(0, unitDir.x, unitDir.y, 0); } } RenderKit-ospray-85af292/apps/common/arcball_camera/ArcballCamera.h000066400000000000000000000022421464752671100252600ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/AffineSpace.h" class ArcballCamera { public: ArcballCamera(const rkcommon::math::box3f &worldBounds, const rkcommon::math::vec2i &windowSize); // All mouse positions passed should be in [-1, 1] normalized screen coords void rotate( const rkcommon::math::vec2f &from, const rkcommon::math::vec2f &to); void zoom(float amount); void pan(const rkcommon::math::vec2f &delta); rkcommon::math::vec3f eyePos() const; rkcommon::math::vec3f center() const; rkcommon::math::vec3f lookDir() const; rkcommon::math::vec3f upDir() const; rkcommon::math::AffineSpace3f transform() const; void setRotation(rkcommon::math::quatf); void updateWindowSize(const rkcommon::math::vec2i &windowSize); protected: void updateCamera(); // Project the point in [-1, 1] screen space onto the arcball sphere rkcommon::math::quatf screenToArcball(const rkcommon::math::vec2f &p); float zoomSpeed; rkcommon::math::vec2f invWindowSize; rkcommon::math::AffineSpace3f centerTranslation, translation, invCamera; rkcommon::math::quatf rotation; }; RenderKit-ospray-85af292/apps/common/arcball_camera/CMakeLists.txt000066400000000000000000000004201464752671100251720ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 add_library(arcball_camera STATIC ArcballCamera.cpp) target_link_libraries(arcball_camera PUBLIC rkcommon::rkcommon) target_include_directories(arcball_camera INTERFACE ${CMAKE_CURRENT_LIST_DIR}) RenderKit-ospray-85af292/apps/common/external/000077500000000000000000000000001464752671100213505ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/external/CMakeLists.txt000066400000000000000000000003201464752671100241030ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ospray_disable_compiler_warnings() if (OSPRAY_ENABLE_APPS_EXAMPLES) add_subdirectory(imgui) endif() add_subdirectory(stb_image) RenderKit-ospray-85af292/apps/common/external/imgui/000077500000000000000000000000001464752671100224625ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/external/imgui/CMakeLists.txt000066400000000000000000000031101464752671100252150ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.14) include(FetchContent) set(FETCHCONTENT_QUIET ON) set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE NEVER) FetchContent_Declare( imgui GIT_REPOSITORY https://github.com/ocornut/imgui GIT_TAG ${OSPRAY_IMGUI_GIT_TAG} # `patch` is not available on all systems, so use `git apply` instead. # The patch command first resets the repository to a clean state. That # is because CMake wants to apply the patch again when CMake needs to # reconfigure, which fails. PATCH_COMMAND git reset --hard && git apply -v -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/imgui.patch ) FetchContent_MakeAvailable(imgui) mark_as_advanced(FETCHCONTENT_BASE_DIR) mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) mark_as_advanced(FETCHCONTENT_QUIET) mark_as_advanced(FETCHCONTENT_SOURCE_DIR_IMGUI) mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_IMGUI) ospray_disable_compiler_warnings() add_library(ospray_imgui SHARED ${imgui_SOURCE_DIR}/imgui.cpp ${imgui_SOURCE_DIR}/imgui_draw.cpp ${imgui_SOURCE_DIR}/imgui_tables.cpp ${imgui_SOURCE_DIR}/imgui_widgets.cpp ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp ) target_link_libraries(ospray_imgui PUBLIC glfw ${OPENGL_LIBRARIES} ) ospray_install_library(ospray_imgui apps) target_include_directories( ospray_imgui INTERFACE $ $ PRIVATE ${imgui_SOURCE_DIR} ) RenderKit-ospray-85af292/apps/common/external/imgui/imgui.patch000066400000000000000000000101451464752671100246160ustar00rootroot00000000000000--- a/imconfig.h +++ b/imconfig.h @@ -21,20 +21,29 @@ //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. +#ifdef _WIN32 +# ifdef ospray_imgui_EXPORTS +# define IMGUI_API __declspec(dllexport) +# else +# define IMGUI_API __declspec(dllimport) +# endif +#else +# define IMGUI_API +#endif // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. //#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllimport ) //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. -//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS +#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS. //---- Disable all of Dear ImGui or don't implement standard windows/tools. // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. -//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. -//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty. +#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. +#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty. //---- Don't implement some functions to reduce linkage requirements. //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) @@ -44,7 +53,7 @@ //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. -//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) +#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available RenderKit-ospray-85af292/apps/common/external/stb_image/000077500000000000000000000000001464752671100233025ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/external/stb_image/CMakeLists.txt000066400000000000000000000013721464752671100260450ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.14) include(FetchContent) set(FETCHCONTENT_QUIET ON) set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE NEVER) FetchContent_Declare( stb GIT_REPOSITORY https://github.com/nothings/stb GIT_TAG ${OSPRAY_STB_GIT_TAG} ) FetchContent_MakeAvailable(stb) mark_as_advanced(FETCHCONTENT_BASE_DIR) mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) mark_as_advanced(FETCHCONTENT_QUIET) mark_as_advanced(FETCHCONTENT_SOURCE_DIR_STB) mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_STB) add_library(stb_image INTERFACE) target_include_directories(stb_image INTERFACE $ ) RenderKit-ospray-85af292/apps/common/ospray_testing/000077500000000000000000000000001464752671100226005ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/ospray_testing/CMakeLists.txt000066400000000000000000000037371464752671100253520ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 include(GenerateExportHeader) add_library(ospray_testing SHARED ${OSPRAY_RESOURCE} ospray_testing.cpp builders/Builder.cpp builders/Boxes.cpp builders/ClippingGeometries.cpp builders/CornellBox.cpp builders/Curves.cpp builders/Empty.cpp builders/GravitySpheresVolume.cpp builders/Instancing.cpp builders/Interpolation.cpp builders/MipMapTextures.cpp builders/Noise.cpp builders/ParticleVolume.cpp builders/PerlinNoiseVolumes.cpp builders/Planes.cpp builders/RandomSpheres.cpp builders/Streamlines.cpp builders/SubdivisionCube.cpp builders/Transparency.cpp builders/UnstructuredVolumeGen.cpp builders/UnstructuredVolumeSimple.cpp builders/VdbVolume.cpp # regression test scenes builders/test_pt_alloy_roughness.cpp builders/test_pt_carpaint.cpp builders/test_pt_glass.cpp builders/test_pt_luminous.cpp builders/test_pt_material_tex.cpp builders/test_pt_metal_roughness.cpp builders/test_pt_metallic_flakes.cpp builders/test_pt_mix_tex.cpp builders/test_pt_obj.cpp builders/test_pt_plastic.cpp builders/test_pt_principled.cpp builders/test_pt_principled_tex.cpp builders/test_pt_thinglass.cpp builders/test_pt_velvet.cpp ) generate_export_header(ospray_testing) target_link_libraries(ospray_testing PUBLIC ospray_sdk PRIVATE raw_to_amr ) target_include_directories(ospray_testing PUBLIC $ $ $ ) ## Install library/headers ## ospray_install_library(ospray_testing apps) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray COMPONENT devel FILES_MATCHING PATTERN *.h PATTERN *.inl ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ospray_testing_export.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/ospray_testing COMPONENT devel ) RenderKit-ospray-85af292/apps/common/ospray_testing/builders/000077500000000000000000000000001464752671100244115ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Boxes.cpp000066400000000000000000000046211464752671100262000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct Boxes : public detail::Builder { Boxes(bool lights = false) : useLights(lights) {} ~Boxes() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: vec3i dimensions{4}; bool useLights{false}; }; // Inlined definitions //////////////////////////////////////////////////// void Boxes::commit() { Builder::commit(); dimensions = getParam("dimensions", vec3i(4)); addPlane = false; } cpp::Group Boxes::buildGroup() const { cpp::Geometry boxGeometry("box"); index_sequence_3D numBoxes(dimensions); std::vector boxes; std::vector color; auto dim = reduce_max(dimensions); for (auto i : numBoxes) { auto i_f = static_cast(i); auto lower = i_f * 5.f; auto upper = lower + (0.75f * 5.f); boxes.emplace_back(lower, upper); auto box_color = (0.8f * i_f / dim) + 0.2f; color.emplace_back(box_color.x, box_color.y, box_color.z, 1.f); } boxGeometry.setParam("box", cpp::CopiedData(boxes)); boxGeometry.commit(); cpp::GeometricModel model(boxGeometry); model.setParam("color", cpp::CopiedData(color)); cpp::Material material("obj"); material.setParam("ks", vec3f(0.3f)); material.setParam("ns", 10.f); material.commit(); model.setParam("material", material); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } cpp::World Boxes::buildWorld() const { auto world = Builder::buildWorld(); if (!useLights) return world; cpp::Light light("distant"); light.setParam("color", vec3f(0.78f, 0.551f, 0.483f)); light.setParam("intensity", 3.14f); light.setParam("direction", vec3f(-0.8f, -0.6f, 0.3f)); light.commit(); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.35f); ambient.setParam("visible", false); ambient.commit(); std::vector lights{light, ambient}; world.setParam("light", cpp::CopiedData(lights)); return world; } OSP_REGISTER_TESTING_BUILDER(Boxes, boxes); OSP_REGISTER_TESTING_BUILDER(Boxes(true), boxes_lit); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Builder.cpp000066400000000000000000000146251464752671100265130ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" namespace ospray { namespace testing { namespace detail { std::unique_ptr Builder::factory; void Builder::commit() { rendererType = getParam("rendererType", "scivis"); tfColorMap = getParam("tf.colorMap", "jet"); tfOpacityMap = getParam("tf.opacityMap", "linear"); randomSeed = getParam("randomSeed", 0); } cpp::World Builder::buildWorld() const { return buildWorld({}); } cpp::World Builder::buildWorld( const std::vector &instances) const { cpp::World world; auto group = buildGroup(); cpp::Instance instance(group); instance.commit(); std::vector inst = instances; inst.push_back(instance); if (addPlane) inst.push_back(makeGroundPlane(group.getBounds())); world.setParam("instance", cpp::CopiedData(inst)); cpp::Light light("ambient"); light.setParam("visible", false); light.commit(); world.setParam("light", cpp::CopiedData(light)); return world; } cpp::TransferFunction Builder::makeTransferFunction( const range1f &valueRange) const { cpp::TransferFunction transferFunction("piecewiseLinear"); std::vector colors; std::vector opacities; if (tfColorMap == "jet") { colors.emplace_back(0, 0, 0.562493); colors.emplace_back(0, 0, 1); colors.emplace_back(0, 1, 1); colors.emplace_back(0.500008, 1, 0.500008); colors.emplace_back(1, 1, 0); colors.emplace_back(1, 0, 0); colors.emplace_back(0.500008, 0, 0); } else if (tfColorMap == "rgb") { colors.emplace_back(0, 0, 1); colors.emplace_back(0, 1, 0); colors.emplace_back(1, 0, 0); } else { colors.emplace_back(0.f, 0.f, 0.f); colors.emplace_back(1.f, 1.f, 1.f); } if (tfOpacityMap == "linear") { opacities.emplace_back(0.f); opacities.emplace_back(1.f); } else if (tfOpacityMap == "linearInv") { opacities.emplace_back(1.f); opacities.emplace_back(0.f); } else if (tfOpacityMap == "opaque") { opacities.emplace_back(1.f); } transferFunction.setParam("color", cpp::CopiedData(colors)); transferFunction.setParam("opacity", cpp::CopiedData(opacities)); transferFunction.setParam("value", valueRange); transferFunction.commit(); return transferFunction; } cpp::Instance Builder::makeGroundPlane(const box3f &bounds, const vec4f &planeColor, const vec4f &stripeColor) const { auto planeExtent = 0.8f * length(bounds.center() - bounds.lower); cpp::Geometry planeGeometry("mesh"); std::vector v_position; std::vector v_normal; std::vector v_color; std::vector indices; unsigned int startingIndex = 0; const vec3f up = vec3f{0.f, 1.f, 0.f}; v_position.emplace_back(-planeExtent, -1.f, -planeExtent); v_position.emplace_back(planeExtent, -1.f, -planeExtent); v_position.emplace_back(planeExtent, -1.f, planeExtent); v_position.emplace_back(-planeExtent, -1.f, planeExtent); v_normal.push_back(up); v_normal.push_back(up); v_normal.push_back(up); v_normal.push_back(up); v_color.push_back(planeColor); v_color.push_back(planeColor); v_color.push_back(planeColor); v_color.push_back(planeColor); indices.emplace_back( startingIndex, startingIndex + 1, startingIndex + 2, startingIndex + 3); // stripes on ground plane const float stripeWidth = 0.025f; const float paddedExtent = planeExtent + stripeWidth; const size_t numStripes = 10; for (size_t i = 0; i < numStripes; i++) { // the center coordinate of the stripe, either in the x or z // direction const float coord = -planeExtent + float(i) / float(numStripes - 1) * 2.f * planeExtent; // offset the stripes by an epsilon above the ground plane const float yLevel = -1.f + 1e-3f; // x-direction stripes startingIndex = v_position.size(); v_position.emplace_back(-paddedExtent, yLevel, coord - stripeWidth); v_position.emplace_back(paddedExtent, yLevel, coord - stripeWidth); v_position.emplace_back(paddedExtent, yLevel, coord + stripeWidth); v_position.emplace_back(-paddedExtent, yLevel, coord + stripeWidth); v_normal.push_back(up); v_normal.push_back(up); v_normal.push_back(up); v_normal.push_back(up); v_color.push_back(stripeColor); v_color.push_back(stripeColor); v_color.push_back(stripeColor); v_color.push_back(stripeColor); indices.emplace_back( startingIndex, startingIndex + 1, startingIndex + 2, startingIndex + 3); // z-direction stripes startingIndex = v_position.size(); // offset another epsilon to avoid z-figthing for primID AOV const float yLevel2 = yLevel + 1e-4f; v_position.emplace_back(coord - stripeWidth, yLevel2, -paddedExtent); v_position.emplace_back(coord + stripeWidth, yLevel2, -paddedExtent); v_position.emplace_back(coord + stripeWidth, yLevel2, paddedExtent); v_position.emplace_back(coord - stripeWidth, yLevel2, paddedExtent); v_normal.push_back(up); v_normal.push_back(up); v_normal.push_back(up); v_normal.push_back(up); v_color.push_back(stripeColor); v_color.push_back(stripeColor); v_color.push_back(stripeColor); v_color.push_back(stripeColor); indices.emplace_back( startingIndex, startingIndex + 1, startingIndex + 2, startingIndex + 3); } planeGeometry.setParam("vertex.position", cpp::CopiedData(v_position)); planeGeometry.setParam("vertex.normal", cpp::CopiedData(v_normal)); planeGeometry.setParam("vertex.color", cpp::CopiedData(v_color)); planeGeometry.setParam("index", cpp::CopiedData(indices)); planeGeometry.commit(); cpp::GeometricModel plane(planeGeometry); cpp::Material material("obj"); material.commit(); plane.setParam("material", material); plane.commit(); cpp::Group planeGroup; planeGroup.setParam("geometry", cpp::CopiedData(plane)); planeGroup.commit(); cpp::Instance planeInst(planeGroup); planeInst.commit(); return planeInst; } void Builder::registerBuilder(const std::string &name, BuilderFcn fcn) { if (factory.get() == nullptr) factory = make_unique(); (*factory)[name] = fcn; } Builder *Builder::createBuilder(const std::string &name) { if (factory.get() == nullptr) return nullptr; else { auto &fcn = (*factory)[name]; return fcn(); } } } // namespace detail } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Builder.h000066400000000000000000000044761464752671100261630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" // rkcommon #include "rkcommon/memory/IntrusivePtr.h" #include "rkcommon/utility/ParameterizedObject.h" // std #include #include #include "ospray_testing_export.h" namespace ospray { namespace testing { namespace detail { using namespace rkcommon; using namespace rkcommon::math; struct Builder : public memory::RefCountedObject, public utility::ParameterizedObject { using BuilderFcn = std::function; ~Builder() override = default; virtual void commit(); virtual cpp::Group buildGroup() const = 0; virtual cpp::World buildWorld() const; virtual cpp::World buildWorld( const std::vector &instances) const; static void registerBuilder(const std::string &name, BuilderFcn fcn); static Builder *createBuilder(const std::string &name); protected: cpp::TransferFunction makeTransferFunction(const range1f &valueRange) const; cpp::Instance makeGroundPlane(const box3f &bounds, const vec4f &planeColor = vec4f{0.9f, 0.9f, 0.9f, 0.75f}, const vec4f &stripeColor = vec4f{1.0f, 0.1f, 0.1f, 1.f}) const; // Data // std::string rendererType{"scivis"}; std::string tfColorMap{"jet"}; std::string tfOpacityMap{"linear"}; bool addPlane{true}; unsigned int randomSeed{0}; private: using BuilderFactory = std::map; static std::unique_ptr factory; }; } // namespace detail } // namespace testing } // namespace ospray #define OSP_REGISTER_TESTING_BUILDER(InternalClassName, Name) \ static bool init_builder_##Name() \ { \ using Builder = ospray::testing::detail::Builder; \ Builder::registerBuilder( \ TOSTRING(Name), [] { return new InternalClassName; }); \ return true; \ } \ static bool val_##Name##_initialized = init_builder_##Name(); RenderKit-ospray-85af292/apps/common/ospray_testing/builders/ClippingGeometries.cpp000066400000000000000000000177331464752671100307210ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct ClippingGeometries : public detail::Builder { ClippingGeometries( const std::string &geometryType, const std::string &geometrySubType = ""); ~ClippingGeometries() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: vec3i dimensions{19}; std::string geomType; std::string geomSubType; }; // Inlined definitions //////////////////////////////////////////////////// ClippingGeometries::ClippingGeometries( const std::string &geometryType, const std::string &geometrySubType) : geomType(geometryType), geomSubType(geometrySubType) {} void ClippingGeometries::commit() { Builder::commit(); dimensions = getParam("dimensions", dimensions); geomType = getParam("geometryType", geomType); geomSubType = getParam("geometrySubType", geomSubType); addPlane = false; } cpp::Group ClippingGeometries::buildGroup() const { cpp::Geometry spheresGeometry("sphere"); index_sequence_3D numSpheres(dimensions); std::vector positions; auto dim = reduce_max(dimensions) - 1; float size = 2.f; for (auto i : numSpheres) { vec3f i_f = static_cast(i); vec3f p = size * (i_f / dim - .5f); positions.emplace_back(p); } spheresGeometry.setParam("sphere.position", cpp::CopiedData(positions)); spheresGeometry.setParam("radius", size / dim / 2.f); spheresGeometry.commit(); cpp::GeometricModel model(spheresGeometry); cpp::Material material("obj"); material.setParam("kd", vec3f(.1f, .4f, .8f)); material.commit(); model.setParam("material", material); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } cpp::World ClippingGeometries::buildWorld() const { // Create selected geometry vec3f cPos; cpp::Geometry geometry(geomType); if (geomType == "curve") { static std::vector vertices = {{-1.f, +0.f, -1.f, 0.2f}, {+0.f, -1.f, +0.f, 0.2f}, {+1.f, +0.f, +1.f, 0.2f}, {-1.f, +0.f, +1.f, 0.2f}, {+0.f, +1.f, +0.f, 0.3f}, {+1.f, +0.f, -1.f, 0.2f}, {-1.f, +0.f, -1.f, 0.2f}, {+0.f, -1.f, +0.f, 0.2f}, {+1.f, +0.f, +1.f, 0.2f}}; if (geomSubType == "bspline") { geometry.setParam("vertex.position_radius", cpp::CopiedData(vertices)); geometry.setParam("basis", OSP_BSPLINE); cPos = vec3f(-.1f, 0.f, -.1f); } else if (geomSubType == "linear") { geometry.setParam("vertex.position", cpp::CopiedData((vec3f *)vertices.data(), vertices.size(), sizeof(vec4f))); geometry.setParam("radius", 0.2f); geometry.setParam("basis", OSP_LINEAR); cPos = vec3f(-.2f, 0.f, -.2f); } std::vector indices = {0, 1, 2, 3, 4, 5}; geometry.setParam("index", cpp::CopiedData(indices)); geometry.setParam("type", OSP_ROUND); geometry.commit(); } else if (geomType == "subdivision") { const float size = .9f; std::vector vertices = {{-size, -size, -size}, {+size, -size, -size}, {+size, -size, +size}, {-size, -size, +size}, {-size, +size, -size}, {+size, +size, -size}, {+size, +size, +size}, {-size, +size, +size}}; geometry.setParam("vertex.position", cpp::CopiedData(vertices)); std::vector faces = {4, 4, 4, 4, 4, 4}; geometry.setParam("face", cpp::CopiedData(faces)); std::vector indices = { 0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 0, 3, 7, 4, 4, 7, 6, 5, 0, 1, 2, 3, }; geometry.setParam("index", cpp::CopiedData(indices)); std::vector vertexCreaseIndices = {0, 1, 2, 3, 4, 5, 6, 7}; geometry.setParam("vertexCrease.index", cpp::CopiedData(vertexCreaseIndices)); std::vector vertexCreaseWeights = { 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f}; geometry.setParam("vertexCrease.weight", cpp::CopiedData(vertexCreaseWeights)); std::vector edgeCreaseIndices = {{0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}}; geometry.setParam("edgeCrease.index", cpp::CopiedData(edgeCreaseIndices)); std::vector edgeCreaseWeights = { 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f}; geometry.setParam("edgeCrease.weight", cpp::CopiedData(edgeCreaseWeights)); geometry.setParam("level", 10.f); geometry.commit(); cPos = vec3f(-.3f, .3f, -.3f); } else if (geomType == "mesh") { const vec3f pos = vec3f(0.f); const vec3f size = vec3f(1.1f); std::vector vertices = {{pos.x, pos.y - size.y, pos.z}, {pos.x - size.x, pos.y, pos.z - size.z}, {pos.x + size.x, pos.y, pos.z - size.z}, {pos.x + size.x, pos.y, pos.z + size.z}, {pos.x - size.x, pos.y, pos.z + size.z}, {pos.x, pos.y + size.y, pos.z}}; geometry.setParam("vertex.position", cpp::CopiedData(vertices)); std::vector indices = {{0, 1, 2}, {0, 2, 3}, {0, 3, 4}, {0, 4, 1}, {5, 2, 1}, {5, 3, 2}, {5, 4, 3}, {5, 1, 4}}; geometry.setParam("index", cpp::CopiedData(indices)); geometry.commit(); cPos = vec3f(-.3f, 0.f, -.3f); } else if (geomType == "plane") { std::vector coefficients = {vec4f(1.0f, 1.0f, 1.0f, 0.0f)}; geometry.setParam("plane.coefficients", cpp::CopiedData(coefficients)); geometry.commit(); cPos = vec3f(-.3f, .2f, -.3f); } else if (geomType == "box") { std::vector boxes = { box3f(vec3f(-.9f, -.9f, -.9f), vec3f(.9f, .9f, .9f))}; geometry.setParam("box", cpp::CopiedData(boxes)); geometry.commit(); cPos = vec3f(-.3f, .3f, -.3f); } else if (geomType == "sphere") { std::vector position = {vec3f(0.f, 0.f, 0.f)}; geometry.setParam("sphere.position", cpp::CopiedData(position)); geometry.setParam("radius", 1.f); geometry.commit(); cPos = vec3f(-.3f, .2f, -.3f); } else return Builder::buildWorld(); std::vector inst; // Create clipping instance with model that has inverted normals { cpp::GeometricModel model(geometry); model.setParam("invertNormals", true); model.commit(); cpp::Group group; group.setParam("clippingGeometry", cpp::CopiedData(model)); group.commit(); cpp::Instance instance(group); instance.commit(); inst.push_back(instance); } // Create second clipping instance but keep original normals { cpp::GeometricModel model(geometry); model.setParam("invertNormals", false); model.commit(); cpp::Group group; group.setParam("clippingGeometry", cpp::CopiedData(model)); group.commit(); cpp::Instance instance(group); instance.setParam("transform", affine3f::translate(cPos)); instance.commit(); inst.push_back(instance); } return Builder::buildWorld(inst); } OSP_REGISTER_TESTING_BUILDER(ClippingGeometries("sphere"), clip_with_spheres); OSP_REGISTER_TESTING_BUILDER(ClippingGeometries("box"), clip_with_boxes); OSP_REGISTER_TESTING_BUILDER(ClippingGeometries("plane"), clip_with_planes); OSP_REGISTER_TESTING_BUILDER(ClippingGeometries("mesh"), clip_with_meshes); OSP_REGISTER_TESTING_BUILDER( ClippingGeometries("subdivision"), clip_with_subdivisions); OSP_REGISTER_TESTING_BUILDER( ClippingGeometries("curve", "linear"), clip_with_linear_curves); OSP_REGISTER_TESTING_BUILDER( ClippingGeometries("curve", "bspline"), clip_with_bspline_curves); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/CornellBox.cpp000066400000000000000000000155021464752671100271670ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" // stl #include using namespace rkcommon::math; namespace ospray { namespace testing { struct CornellBox : public detail::Builder { CornellBox() = default; ~CornellBox() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; }; // quad mesh data static std::vector vertices = { // Floor {1.00f, -1.00f, -1.00f}, {-1.00f, -1.00f, -1.00f}, {-1.00f, -1.00f, 1.00f}, {1.00f, -1.00f, 1.00f}, // Ceiling {1.00f, 1.00f, -1.00f}, {1.00f, 1.00f, 1.00f}, {-1.00f, 1.00f, 1.00f}, {-1.00f, 1.00f, -1.00f}, // Backwall {1.00f, -1.00f, 1.00f}, {-1.00f, -1.00f, 1.00f}, {-1.00f, 1.00f, 1.00f}, {1.00f, 1.00f, 1.00f}, // RightWall {-1.00f, -1.00f, 1.00f}, {-1.00f, -1.00f, -1.00f}, {-1.00f, 1.00f, -1.00f}, {-1.00f, 1.00f, 1.00f}, // LeftWall {1.00f, -1.00f, -1.00f}, {1.00f, -1.00f, 1.00f}, {1.00f, 1.00f, 1.00f}, {1.00f, 1.00f, -1.00f}, // ShortBox Top Face {-0.53f, -0.40f, -0.75f}, {-0.70f, -0.40f, -0.17f}, {-0.13f, -0.40f, -0.00f}, {0.05f, -0.40f, -0.57f}, // ShortBox Left Face {0.05f, -1.00f, -0.57f}, {0.05f, -0.40f, -0.57f}, {-0.13f, -0.40f, -0.00f}, {-0.13f, -1.00f, -0.00f}, // ShortBox Front Face {-0.53f, -1.00f, -0.75f}, {-0.53f, -0.40f, -0.75f}, {0.05f, -0.40f, -0.57f}, {0.05f, -1.00f, -0.57f}, // ShortBox Right Face {-0.70f, -1.00f, -0.17f}, {-0.70f, -0.40f, -0.17f}, {-0.53f, -0.40f, -0.75f}, {-0.53f, -1.00f, -0.75f}, // ShortBox Back Face {-0.13f, -1.00f, -0.00f}, {-0.13f, -0.40f, -0.00f}, {-0.70f, -0.40f, -0.17f}, {-0.70f, -1.00f, -0.17f}, // ShortBox Bottom Face {-0.53f, -1.00f, -0.75f}, {-0.70f, -1.00f, -0.17f}, {-0.13f, -1.00f, -0.00f}, {0.05f, -1.00f, -0.57f}, // TallBox Top Face {0.53f, 0.20f, -0.09f}, {-0.04f, 0.20f, 0.09f}, {0.14f, 0.20f, 0.67f}, {0.71f, 0.20f, 0.49f}, // TallBox Left Face {0.53f, -1.00f, -0.09f}, {0.53f, 0.20f, -0.09f}, {0.71f, 0.20f, 0.49f}, {0.71f, -1.00f, 0.49f}, // TallBox Front Face {0.71f, -1.00f, 0.49f}, {0.71f, 0.20f, 0.49f}, {0.14f, 0.20f, 0.67f}, {0.14f, -1.00f, 0.67f}, // TallBox Right Face {0.14f, -1.00f, 0.67f}, {0.14f, 0.20f, 0.67f}, {-0.04f, 0.20f, 0.09f}, {-0.04f, -1.00f, 0.09f}, // TallBox Back Face {-0.04f, -1.00f, 0.09f}, {-0.04f, 0.20f, 0.09f}, {0.53f, 0.20f, -0.09f}, {0.53f, -1.00f, -0.09f}, // TallBox Bottom Face {0.53f, -1.00f, -0.09f}, {-0.04f, -1.00f, 0.09f}, {0.14f, -1.00f, 0.67f}, {0.71f, -1.00f, 0.49f}}; static std::vector colors = { // Floor {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // Ceiling {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // Backwall {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // RightWall {0.140f, 0.450f, 0.091f, 1.0f}, {0.140f, 0.450f, 0.091f, 1.0f}, {0.140f, 0.450f, 0.091f, 1.0f}, {0.140f, 0.450f, 0.091f, 1.0f}, // LeftWall {0.630f, 0.065f, 0.05f, 1.0f}, {0.630f, 0.065f, 0.05f, 1.0f}, {0.630f, 0.065f, 0.05f, 1.0f}, {0.630f, 0.065f, 0.05f, 1.0f}, // ShortBox Top Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // ShortBox Left Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // ShortBox Front Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // ShortBox Right Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // ShortBox Back Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // ShortBox Bottom Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // TallBox Top Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // TallBox Left Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // TallBox Front Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // TallBox Right Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // TallBox Back Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, // TallBox Bottom Face {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}, {0.725f, 0.710f, 0.68f, 1.0f}}; // Inlined definitions //////////////////////////////////////////////////// void CornellBox::commit() { Builder::commit(); addPlane = false; } cpp::Group CornellBox::buildGroup() const { cpp::Geometry quadMesh("mesh"); quadMesh.setParam("vertex.position", cpp::CopiedData(vertices)); quadMesh.setParam("vertex.color", cpp::CopiedData(colors)); quadMesh.setParam("quadSoup", true); quadMesh.commit(); cpp::GeometricModel model(quadMesh); cpp::Material quadMeshMaterial("obj"); quadMeshMaterial.commit(); model.setParam("material", quadMeshMaterial); // Put the mesh and material into a model model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } cpp::World CornellBox::buildWorld() const { auto world = Builder::buildWorld(); cpp::Light light("quad"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 47.f); light.setParam("position", vec3f(-0.23f, 0.98f, -0.16f)); light.setParam("edge1", vec3f(0.47f, 0.0f, 0.0f)); light.setParam("edge2", vec3f(0.0f, 0.0f, 0.38f)); light.commit(); world.setParam("light", cpp::CopiedData(light)); return world; } OSP_REGISTER_TESTING_BUILDER(CornellBox, cornell_box); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Curves.cpp000066400000000000000000000063521464752671100263720ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/random.h" // stl #include using namespace rkcommon::math; namespace ospray { namespace testing { struct Curves : public detail::Builder { Curves() = default; ~Curves() override = default; void commit() override; cpp::Group buildGroup() const override; std::string curveVariant; }; static std::vector points = {{-1.0f, 0.0f, -2.f, 0.2f}, {0.0f, -1.0f, 0.0f, 0.2f}, {1.0f, 0.0f, 2.f, 0.2f}, {-1.0f, 0.0f, 2.f, 0.2f}, {0.0f, 1.0f, 0.0f, 0.6f}, {1.0f, 0.0f, -2.f, 0.2f}, {-1.0f, 0.0f, -2.f, 0.2f}, {0.0f, -1.0f, 0.0f, 0.2f}, {1.0f, 0.0f, 2.f, 0.2f}}; static std::vector indices = {0, 1, 2, 3, 4, 5}; void Curves::commit() { Builder::commit(); curveVariant = getParam("curveVariant", "bspline"); } cpp::Group Curves::buildGroup() const { std::vector geometricModels; std::mt19937 gen(randomSeed); utility::uniform_real_distribution colorDistribution(0.1f, 1.0f); std::vector s_colors(points.size()); cpp::Geometry geom("curve"); // defaults, "linear" geom.setParam("type", OSP_ROUND); geom.setParam("basis", OSP_LINEAR); geom.setParam("vertex.position_radius", cpp::CopiedData(points)); if (curveVariant == "hermite") { geom.setParam("basis", OSP_HERMITE); std::vector tangents; for (auto iter = points.begin(); iter != points.end() - 1; ++iter) { const vec4f pointTangent = *(iter + 1) - *iter; tangents.push_back(pointTangent); } geom.setParam("vertex.tangent", cpp::CopiedData(tangents)); } else if (curveVariant == "catmull-rom") { geom.setParam("basis", OSP_CATMULL_ROM); } else if (curveVariant == "cones") { geom.setParam("type", OSP_DISJOINT); } else if (curveVariant == "linear_deprecated") { geom.removeParam("vertex.position_radius"); geom.setParam("radius", 0.1f); geom.setParam("vertex.position", cpp::CopiedData((vec3f *)points.data(), points.size(), sizeof(vec4f))); } else if (curveVariant == "bspline") { geom.setParam("basis", OSP_BSPLINE); } else if (curveVariant == "bezier") { geom.setParam("basis", OSP_BEZIER); } for (auto &c : s_colors) { c.x = colorDistribution(gen); c.y = colorDistribution(gen); c.z = colorDistribution(gen); c.w = colorDistribution(gen); } geom.setParam("vertex.color", cpp::CopiedData(s_colors)); geom.setParam("index", cpp::CopiedData(indices)); geom.commit(); cpp::GeometricModel model(geom); if (rendererType == "pathtracer") { // create glass material and assign to geometry cpp::Material glassMaterial("thinGlass"); glassMaterial.setParam("attenuationDistance", 1.f); glassMaterial.commit(); model.setParam("material", glassMaterial); } else { cpp::Material glassMaterial("obj"); glassMaterial.commit(); model.setParam("material", glassMaterial); } model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } OSP_REGISTER_TESTING_BUILDER(Curves, curves); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Empty.cpp000066400000000000000000000020401464752671100262070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct Empty : public detail::Builder { Empty(bool plane = false) { addPlane = plane; } ~Empty() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; }; // Inlined definitions //////////////////////////////////////////////////// void Empty::commit() { Builder::commit(); } cpp::Group Empty::buildGroup() const { cpp::Group group; group.commit(); return group; } cpp::World Empty::buildWorld() const { cpp::World world; if (addPlane) { std::vector inst; inst.push_back(makeGroundPlane(box3f(zero, one))); world.setParam("instance", cpp::CopiedData(inst)); } return world; } OSP_REGISTER_TESTING_BUILDER(Empty, empty); OSP_REGISTER_TESTING_BUILDER(Empty(true), nolight); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/GravitySpheresVolume.cpp000066400000000000000000000207761464752671100313000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/utility/random.h" // stl #include #include // raw_to_amr #include "rawToAMR.h" using namespace rkcommon; using namespace rkcommon::math; namespace ospray { namespace testing { using VoxelArray = std::vector; struct GravitySpheres : public detail::Builder { GravitySpheres(bool addVolume = true, bool asAMR = false, bool addIsosurface = false, bool clip = false, bool multipleIsosurfaces = false); ~GravitySpheres() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: VoxelArray generateVoxels() const; cpp::Volume createStructuredVolume(const VoxelArray &voxels) const; cpp::Volume createAMRVolume(const VoxelArray &voxels) const; // Data // vec3i volumeDimensions{128}; int numPoints{10}; bool withVolume{true}; bool createAsAMR{false}; bool withIsosurface{false}; float isovalue{2.5f}; bool withClipping{false}; bool multipleIsosurfaces{false}; }; // Inlined definitions //////////////////////////////////////////////////// GravitySpheres::GravitySpheres(bool addVolume, bool asAMR, bool addIsosurface, bool clip, bool multipleIsosurfaces) : withVolume(addVolume), createAsAMR(asAMR), withIsosurface(addIsosurface), withClipping(clip), multipleIsosurfaces(multipleIsosurfaces) {} void GravitySpheres::commit() { Builder::commit(); volumeDimensions = getParam("volumeDimensions", vec3i(128)); numPoints = getParam("numPoints", 10); withVolume = getParam("withVolume", withVolume); createAsAMR = getParam("asAMR", createAsAMR); withIsosurface = getParam("withIsosurface", withIsosurface); isovalue = getParam("isovalue", 2.5f); withClipping = getParam("withClipping", withClipping); addPlane = false; } cpp::Group GravitySpheres::buildGroup() const { auto voxels = generateVoxels(); auto voxelRange = range1f(0.f, 10.f); cpp::Volume volume = createAsAMR ? createAMRVolume(voxels) : createStructuredVolume(voxels); cpp::VolumetricModel model(volume); model.setParam("transferFunction", makeTransferFunction(voxelRange)); model.commit(); cpp::Group group; if (withVolume) group.setParam("volume", cpp::CopiedData(model)); if (withIsosurface) { cpp::Geometry isoGeom("isosurface"); std::vector isovalues = {isovalue}; if (multipleIsosurfaces) { isovalues.push_back(isovalue + 1.f); } isoGeom.setParam("isovalue", cpp::CopiedData(isovalues)); isoGeom.setParam("volume", volume); isoGeom.commit(); cpp::GeometricModel isoModel(isoGeom); cpp::Material mat("obj"); mat.setParam("kd", vec3f(1.f)); mat.setParam("d", 0.5f); mat.setParam("ks", vec3f(0.2f)); mat.commit(); if (multipleIsosurfaces) { std::vector colors = { vec4f(0.2f, 0.2f, 0.8f, 1.f), vec4f(0.8f, 0.2f, 0.2f, 1.f)}; isoModel.setParam("color", cpp::CopiedData(colors)); } isoModel.setParam("material", mat); isoModel.commit(); group.setParam("geometry", cpp::CopiedData(isoModel)); } group.commit(); return group; } cpp::World GravitySpheres::buildWorld() const { // Skip clipping if not enabled std::vector instances; if (withClipping) { // Create clipping plane std::vector geometricModels; { cpp::Geometry planeGeometry("plane"); std::vector coefficients = {vec4f(1.f, -1.f, 1.f, 0.f)}; planeGeometry.setParam( "plane.coefficients", cpp::CopiedData(coefficients)); planeGeometry.commit(); cpp::GeometricModel model(planeGeometry); model.commit(); geometricModels.emplace_back(model); } // Create clipping sphere { cpp::Geometry sphereGeometry("sphere"); std::vector position = {vec3f(.2f, -.2f, .2f)}; sphereGeometry.setParam("sphere.position", cpp::CopiedData(position)); sphereGeometry.setParam("radius", .5f); sphereGeometry.commit(); cpp::GeometricModel model(sphereGeometry); model.commit(); geometricModels.emplace_back(model); } cpp::Group group; group.setParam("clippingGeometry", cpp::CopiedData(geometricModels)); group.commit(); cpp::Instance inst(group); inst.commit(); instances.push_back(inst); } return Builder::buildWorld(instances); } std::vector GravitySpheres::generateVoxels() const { struct Point { vec3f center; float weight; }; // create random number distributions for point center and weight std::mt19937 gen(randomSeed); utility::uniform_real_distribution centerDistribution(-1.f, 1.f); utility::uniform_real_distribution weightDistribution(0.1f, 0.3f); // populate the points std::vector points(numPoints); for (auto &p : points) { p.center.x = centerDistribution(gen); p.center.y = centerDistribution(gen); p.center.z = centerDistribution(gen); p.weight = weightDistribution(gen); } // get world coordinate in [-1.f, 1.f] from logical coordinates in [0, // volumeDimension) auto logicalToWorldCoordinates = [&](int i, int j, int k) { return vec3f(-1.f + float(i) / float(volumeDimensions.x - 1) * 2.f, -1.f + float(j) / float(volumeDimensions.y - 1) * 2.f, -1.f + float(k) / float(volumeDimensions.z - 1) * 2.f); }; // generate voxels std::vector voxels(volumeDimensions.long_product()); tasking::parallel_for(volumeDimensions.z, [&](int k) { for (int j = 0; j < volumeDimensions.y; j++) { for (int i = 0; i < volumeDimensions.x; i++) { // index in array size_t index = size_t(k) * volumeDimensions.z * volumeDimensions.y + size_t(j) * volumeDimensions.x + size_t(i); // compute volume value float value = 0.f; for (auto &p : points) { vec3f pointCoordinate = logicalToWorldCoordinates(i, j, k); const float distance = length(pointCoordinate - p.center); // contribution proportional to weighted inverse-square distance // (i.e. gravity) value += p.weight / (distance * distance); } voxels[index] = value; } } }); return voxels; } cpp::Volume GravitySpheres::createStructuredVolume( const VoxelArray &voxels) const { cpp::Volume volume("structuredRegular"); volume.setParam("gridOrigin", vec3f(-1.f)); volume.setParam("gridSpacing", vec3f(2.f / reduce_max(volumeDimensions))); volume.setParam("data", cpp::CopiedData(voxels.data(), volumeDimensions)); volume.commit(); return volume; } cpp::Volume GravitySpheres::createAMRVolume(const VoxelArray &voxels) const { const int numLevels = 2; const int blockSize = 16; const int refinementLevel = 4; const float threshold = 1.0; std::vector blockBounds; std::vector refinementLevels; std::vector cellWidths; std::vector> blockDataVectors; std::vector blockData; // convert the structured volume to AMR ospray::amr::makeAMR(voxels, volumeDimensions, numLevels, blockSize, refinementLevel, threshold, blockBounds, refinementLevels, cellWidths, blockDataVectors); for (const std::vector &bd : blockDataVectors) blockData.emplace_back(bd.data(), OSP_FLOAT, bd.size()); // create an AMR volume and assign attributes cpp::Volume volume("amr"); int toplevelVolDim = reduce_max(volumeDimensions) / std::pow(refinementLevel, numLevels - 1); volume.setParam("gridOrigin", vec3f(-1.f)); volume.setParam("gridSpacing", vec3f(2.f / toplevelVolDim)); volume.setParam("block.data", cpp::CopiedData(blockData)); volume.setParam("block.bounds", cpp::CopiedData(blockBounds)); volume.setParam("block.level", cpp::CopiedData(refinementLevels)); volume.setParam("cellWidth", cpp::CopiedData(cellWidths)); volume.commit(); return volume; } OSP_REGISTER_TESTING_BUILDER(GravitySpheres, gravity_spheres_volume); OSP_REGISTER_TESTING_BUILDER( GravitySpheres(true, true, false), gravity_spheres_amr); OSP_REGISTER_TESTING_BUILDER(GravitySpheres(false, false, true, false, true), gravity_spheres_isosurface); OSP_REGISTER_TESTING_BUILDER( GravitySpheres(true, false, false, true), clip_gravity_spheres_volume); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Instancing.cpp000066400000000000000000000150571464752671100272220ustar00rootroot00000000000000// Copyright 2009 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}; bool useIDs{false}; }; // 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 vec3f &kd, bool useIDs) { cpp::GeometricModel geometricModel(geo); cpp::Material objMaterial("obj"); objMaterial.setParam("kd", kd); objMaterial.commit(); geometricModel.setParam("material", objMaterial); if (useIDs) geometricModel.setParam("id", 44u); 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, bool useIDs) { 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("value", range1f(0.f, 10.f)); transferFunction.commit(); } vModel.setParam("transferFunction", transferFunction); vModel.setParam("densityScale", .5f); vModel.setParam("gradientShadingScale", 1.f); if (useIDs) vModel.setParam("id", 3u); vModel.commit(); } return vModel; } } // namespace // Instancing definitions // void Instancing::commit() { Builder::commit(); numInstances = getParam("numInstances", numInstances); useIDs = getParam("useIDs", useIDs); } cpp::Group Instancing::buildGroupA() const { cpp::Group group; cpp::Geometry box = makeBoxGeometry(box3f(vec3f(-1.f), vec3f(1.f))); cpp::GeometricModel geometricModel = makeGeometricModel(box, vec3f(.1f, .4f, .8f), useIDs); 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; std::vector models; cpp::Geometry box = makeBoxGeometry(box3f(vec3f(-1.f), vec3f(0.f, 1.f, 1.f))); models.emplace_back(makeGeometricModel(box, vec3f(.1f, .4f, .8f), useIDs)); box = makeBoxGeometry(box3f(vec3f(0.f, -1.f, -1.f), vec3f(1.f))); models.emplace_back(makeGeometricModel(box, vec3f(.1f, .4f, .8f), useIDs)); group.setParam("geometry", cpp::CopiedData(models)); 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("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)), useIDs))); 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]); if (useIDs) instance.setParam("id", i.y + 1); 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 RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Interpolation.cpp000066400000000000000000000120351464752671100277450ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" // stl #include using namespace rkcommon::math; namespace ospray { namespace testing { struct Interpolation : public detail::Builder { Interpolation( bool subd = false, unsigned int attrib = 0, unsigned int interp = 0) : useSubd(subd), attribute(attrib), interpolation(interp) {} ~Interpolation() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; // TODO: support triangles bool useSubd{false}; // otherwise Mesh unsigned int attribute; // color, texcoord, normal unsigned int interpolation; // face varying, vertex varying, uniform, constant }; // quad mesh data static std::vector vertices = { // Left {0.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {1.f, 1.f, 0.f}, {0.f, 1.f, 0.f}, // Right {2.f, 0.f, 0.f}, {2.f, 1.f, 0.f}}; static std::vector quad_indices = { {0, 1, 2, 3}, // Left {1, 4, 5, 2} // Right }; static std::vector subd_indices = {0, 1, 2, 3, 1, 4, 5, 2}; static std::vector texcoords = {{0.0f, 0.0f}, {0.1f, 0.0f}, {0.2f, 0.0f}, {0.3f, 0.0f}, {0.4f, 0.0f}, {0.5f, 0.0f}, {0.6f, 0.0f}, {0.7f, 0.0f}}; static std::vector colors = {{1.f, 0.f, 0.f, 1.f}, {0.f, 1.f, 0.f, 1.f}, {0.f, 0.f, 1.f, 1.f}, {1.f, 1.f, 0.f, 1.f}, {1.f, 0.f, 1.f, 1.f}, {1.f, 0.f, 1.f, 1.f}}; static std::vector colors_fv = {{1.f, 0.f, 0.f, 1.f}, {0.f, 1.f, 0.f, 1.f}, {0.f, 0.f, 1.f, 1.f}, {1.f, 1.f, 0.f, 1.f}, {1.f, 0.f, 1.f, 1.f}, {1.f, 0.f, 1.f, 1.f}, {1.f, 0.f, 1.f, 1.f}, {1.f, 0.f, 1.f, 1.f}}; static std::vector normals = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}, {1.f, 1.f, 0.f}, {1.f, 0.f, 1.f}, {1.f, 0.f, 1.f}, {1.f, 0.f, 1.f}, {1.f, 0.f, 1.f}}; // number of vertex indices per face static std::vector faces = {4, 4}; // Inlined definitions //////////////////////////////////////////////////// void Interpolation::commit() { Builder::commit(); useSubd = getParam("useSubd", useSubd); attribute = getParam("attribute", attribute); interpolation = getParam("interpolation", interpolation); addPlane = false; } cpp::Group Interpolation::buildGroup() const { cpp::Geometry mesh; std::vector colors_mod = colors; if (interpolation == 0) colors_mod = colors_fv; else if (interpolation == 2) colors_mod.resize(2); else if (interpolation == 3) colors_mod.resize(1); cpp::Texture tex("texture2d"); tex.setParam("format", OSP_TEXTURE_RGBA32F); tex.setParam( "data", cpp::CopiedData(colors_mod.data(), vec2ul(colors_mod.size(), 1))); tex.commit(); cpp::Material mat("obj"); if (attribute == 1) // texture mat.setParam("map_kd", tex); mat.commit(); if (useSubd) { mesh = cpp::Geometry("subdivision"); mesh.setParam("vertex.position", cpp::CopiedData(vertices)); mesh.setParam("face", cpp::CopiedData(faces)); mesh.setParam("level", 1.0f); // global level mesh.setParam("index", cpp::CopiedData(subd_indices)); mesh.setParam("mode", OSP_SUBDIVISION_PIN_CORNERS); } else { mesh = cpp::Geometry("mesh"); mesh.setParam("vertex.position", cpp::CopiedData(vertices)); mesh.setParam("index", cpp::CopiedData(quad_indices)); } if (interpolation == 0) { if (attribute == 1) mesh.setParam("texcoord", cpp::CopiedData(texcoords)); else if (attribute == 2) mesh.setParam("normal", cpp::CopiedData(normals)); else mesh.setParam("color", cpp::CopiedData(colors_mod)); } else if (interpolation == 1) { if (attribute == 1) mesh.setParam("vertex.texcoord", cpp::CopiedData(texcoords)); else if (attribute == 2) mesh.setParam("vertex.normal", cpp::CopiedData(normals)); else mesh.setParam("vertex.color", cpp::CopiedData(colors_mod)); } mesh.commit(); cpp::GeometricModel model(mesh); model.setParam("material", mat); if ((attribute == 0) && interpolation == 2) model.setParam("color", cpp::CopiedData(colors_mod)); else if ((attribute == 0) && interpolation == 3) model.setParam("color", colors_mod[0]); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } cpp::World Interpolation::buildWorld() const { auto world = Builder::buildWorld(); cpp::Light light("distant"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 3.14f); light.setParam("direction", vec3f(-0.8f, -0.6f, 0.3f)); light.commit(); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.35f); ambient.setParam("visible", false); ambient.commit(); std::vector lights{light, ambient}; world.setParam("light", cpp::CopiedData(lights)); return world; } OSP_REGISTER_TESTING_BUILDER(Interpolation, interpolation); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/MipMapTextures.cpp000066400000000000000000000052421464752671100300470ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct MipMapTextures : public detail::Builder { MipMapTextures() = default; ~MipMapTextures() override = default; void commit() override; cpp::Group buildGroup() const override; private: float scale{1.0f}; OSPTextureFilter filter{OSP_TEXTURE_FILTER_LINEAR}; }; // Inlined definitions //////////////////////////////////////////////////// void MipMapTextures::commit() { Builder::commit(); scale = getParam("tcScale", 1.0f); filter = static_cast( getParam("filter", OSP_TEXTURE_FILTER_LINEAR)); addPlane = false; } cpp::Group MipMapTextures::buildGroup() const { std::vector v_position = {{-2.5f, -1.5f, -4.f}, {2.5f, -1.5f, -4.f}, {2.5f, 1.5f, 0.f}, {-2.5f, 1.5f, 0.f}, {-1.25f, 1.5f, -2.f}, {1.25f, 1.5f, -2.f}, {1.25f, 3.5f, -0.5f}, {-1.25f, 3.5f, -0.5f}}; std::vector v_texcoord = {{0.f, 0.f}, {scale, 0.f}, {scale, scale}, {0.f, scale}, {0.f, 0.f}, {scale, 0.f}, {scale, scale}, {0.f, scale}}; cpp::Geometry planeGeometry("mesh"); planeGeometry.setParam("vertex.position", cpp::CopiedData(v_position)); planeGeometry.setParam("vertex.texcoord", cpp::CopiedData(v_texcoord)); planeGeometry.setParam("quadSoup", true); planeGeometry.commit(); vec2ul texSize(500, 500); std::vector texData(texSize.product()); uint8_t grayTexel{50}; uint8_t lightTexel{200}; for (size_t i = 0; i < texSize.x; i++) { const int sz = 1 + i * 4 / texSize.x; for (size_t j = 0; j < texSize.y; j++) { texData[j * texSize.x + i] = (i / sz + j / sz) % 2 ? lightTexel : grayTexel; } } cpp::Texture procTex("texture2d"); procTex.setParam("format", OSP_TEXTURE_L8); procTex.setParam("filter", filter); procTex.setParam("data", cpp::CopiedData(texData.data(), texSize)); procTex.commit(); cpp::GeometricModel plane(planeGeometry); cpp::Material material("obj"); material.setParam("map_kd", procTex); material.setParam("map_kd.scale", vec2f(scale)); material.setParam("map_kd.translation", vec2f(0.5f - 0.5f / scale)); material.commit(); plane.setParam("material", material); plane.commit(); cpp::Group planeGroup; planeGroup.setParam("geometry", cpp::CopiedData(plane)); planeGroup.commit(); return planeGroup; } OSP_REGISTER_TESTING_BUILDER(MipMapTextures, mip_map_textures); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Noise.cpp000066400000000000000000000062621464752671100262000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Noise.h" namespace ospray { namespace testing { // Heavily based on Perlin's Java reference implementation of the improved // perlin noise paper from Siggraph 2002 from here // https://mrl.nyu.edu/~perlin/noise/ PerlinNoise::PerlinNoiseData::PerlinNoiseData() { const int permutation[256] = {151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180}; for (int i = 0; i < 256; i++) p[256 + i] = p[i] = permutation[i]; } PerlinNoise::PerlinNoiseData PerlinNoise::p; } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Noise.h000066400000000000000000000061751464752671100256500ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray_testing.h" using namespace rkcommon::math; namespace ospray { namespace testing { /* * Our basic noise primitive. * Heavily based on Perlin's Java reference implementation of * the improved perlin noise paper from Siggraph 2002 from here * https://mrl.nyu.edu/~perlin/noise/ */ class PerlinNoise { struct PerlinNoiseData { PerlinNoiseData(); inline int operator[](size_t idx) const { return p[idx]; } int p[512]; }; static PerlinNoiseData p; static inline float smooth(float t) { return t * t * t * (t * (t * 6.f - 15.f) + 10.f); } static inline float grad(int hash, float x, float y, float z) { const int h = hash & 15; const float u = h < 8 ? x : y; const float v = h < 4 ? y : h == 12 || h == 14 ? x : z; return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); } public: static float noise(vec3f q, float frequency = 8.f) { float x = q.x * frequency; float y = q.y * frequency; float z = q.z * frequency; const int X = (int)floor(x) & 255; const int Y = (int)floor(y) & 255; const int Z = (int)floor(z) & 255; x -= floor(x); y -= floor(y); z -= floor(z); const float u = smooth(x); const float v = smooth(y); const float w = smooth(z); const int A = p[X] + Y; const int B = p[X + 1] + Y; const int AA = p[A] + Z; const int BA = p[B] + Z; const int BB = p[B + 1] + Z; const int AB = p[A + 1] + Z; return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z)), lerp(u, grad(p[AB], x, y - 1, z), grad(p[BB], x - 1, y - 1, z))), lerp(v, lerp(u, grad(p[AA + 1], x, y, z - 1), grad(p[BA + 1], x - 1, y, z - 1)), lerp(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1)))); } }; // ----------------------------------------------------------------------------- // Hypertexture helpers. // ----------------------------------------------------------------------------- /* * Turbulence - noise at various scales. */ inline float turbulence(const vec3f &p, float base_freqency, int octaves) { float value = 0.f; float scale = 1.f; for (int o = 0; o < octaves; ++o) { value += PerlinNoise::noise(scale * p, base_freqency) / scale; scale *= 2.f; } return value; }; /* * A torus indicator function. */ inline bool torus(vec3f X, float R, float r) { const float tmp = sqrtf(X.x * X.x + X.z * X.z) - R; return tmp * tmp + X.y * X.y - r * r < 0.f; } /* * Turbulent torus indicator function. * We use the turbulence() function to distort space. */ inline bool turbulentTorus(vec3f p, float R, float r) { const vec3f X = 2.f * p - vec3f(1.f); return torus((1.4f + 0.4 * turbulence(p, 12.f, 12)) * X, R, r); } /* * Turbulent sphere indicator function. */ inline bool turbulentSphere(vec3f p, float r) { vec3f X = 2.f * p - vec3f(1.f); return length((1.4f + 0.4 * turbulence(p, 12.f, 12)) * X) < r; } } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/ParticleVolume.cpp000066400000000000000000000163301464752671100300530ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" // stl #include #include // file IO #include #include #include #include // rkcommon #include "rkcommon/math/range.h" #include "rkcommon/math/vec.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/utility/random.h" using namespace rkcommon; using namespace rkcommon::math; namespace ospray { namespace testing { using VoxelArray = std::vector; struct ParticleVolume : public detail::Builder { ParticleVolume(int numParticles, bool withVolume, bool withIsosurface, bool withClipping, bool multipleIsosurfaces, bool provideWeights, float clampMaxCumulativeValue, float radiusSupportFactor); ~ParticleVolume() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: // Data // int numParticles{1000}; bool withVolume{true}; bool withIsosurface{false}; bool withClipping{false}; bool multipleIsosurfaces{false}; bool provideWeights{true}; float clampMaxCumulativeValue{0.f}; float radiusSupportFactor{4.f}; float isovalue{0.5f}; range1f valueRange{0, 1.5f}; box3f bounds{{0, 0, 0}, {10, 10, 10}}; }; // Inlined definitions //////////////////////////////////////////////////// ParticleVolume::ParticleVolume(int numParticles, bool withVolume, bool withIsosurface, bool withClipping, bool multipleIsosurfaces, bool provideWeights, float clampMaxCumulativeValue, float radiusSupportFactor) : numParticles(numParticles), withVolume(withVolume), withIsosurface(withIsosurface), withClipping(withClipping), multipleIsosurfaces(multipleIsosurfaces), provideWeights(provideWeights), clampMaxCumulativeValue(clampMaxCumulativeValue), radiusSupportFactor(radiusSupportFactor) {} void ParticleVolume::commit() { Builder::commit(); numParticles = getParam("numParticles", numParticles); withVolume = getParam("withVolume", withVolume); withIsosurface = getParam("withIsosurface", withIsosurface); isovalue = getParam("isovalue", 0.5f); withClipping = getParam("withClipping", withClipping); multipleIsosurfaces = getParam("multipleIsosurfaces", multipleIsosurfaces); clampMaxCumulativeValue = getParam("clampMaxCumulativeValue", clampMaxCumulativeValue); radiusSupportFactor = getParam("radiusSuportFactor", radiusSupportFactor); addPlane = false; } cpp::Group ParticleVolume::buildGroup() const { // AMK: Very similar to ProceduralParticleVolume.h in OpenVKL. Any way to // combine? std::vector particles(numParticles); std::vector radius(numParticles); std::vector weights(numParticles); int32_t randomSeed = 0; // create random number distributions for point center and weight std::mt19937 gen(randomSeed); range1f weightRange(0.5f, 1.5f); const float radiusScale = 1.f / powf(numParticles, 1.f / 3.f); utility::uniform_real_distribution centerDistribution_x( bounds.lower.x, bounds.upper.x); utility::uniform_real_distribution centerDistribution_y( bounds.lower.y, bounds.upper.y); utility::uniform_real_distribution centerDistribution_z( bounds.lower.z, bounds.upper.z); utility::uniform_real_distribution radiusDistribution( radiusScale, 2.f * radiusScale); utility::uniform_real_distribution weightDistribution( weightRange.lower, weightRange.upper); // populate the points for (int i = 0; i < numParticles; i++) { auto &p = particles[i]; p.x = centerDistribution_x(gen); p.y = centerDistribution_y(gen); p.z = centerDistribution_z(gen); radius[i] = radiusDistribution(gen); weights[i] = provideWeights ? weightDistribution(gen) : 1.f; } cpp::Volume volume("particle"); volume.setParam("particle.position", cpp::CopiedData(particles)); volume.setParam("particle.radius", cpp::CopiedData(radius)); volume.setParam("particle.weight", cpp::CopiedData(weights)); volume.setParam("clampMaxCumulativeValue", clampMaxCumulativeValue); volume.setParam("radiusSupportFactor", radiusSupportFactor); volume.commit(); cpp::VolumetricModel model(volume); // AMK: VKL will set the correct valueRange, but we don't have a good way to // get that to OSPRay yet. Use the weightRange instead. model.setParam("transferFunction", makeTransferFunction(range1f(0.f, weightRange.upper))); model.commit(); cpp::Group group; if (withVolume) group.setParam("volume", cpp::CopiedData(model)); if (withIsosurface) { cpp::Geometry isoGeom("isosurface"); std::vector isovalues = {isovalue}; if (multipleIsosurfaces) { isovalues.push_back(isovalue + .25f); } isoGeom.setParam("isovalue", cpp::CopiedData(isovalues)); isoGeom.setParam("volume", volume); isoGeom.commit(); cpp::GeometricModel isoModel(isoGeom); cpp::Material mat("obj"); mat.setParam("kd", vec3f(1.f)); mat.setParam("d", 0.5f); mat.setParam("ks", vec3f(0.2f)); mat.commit(); if (multipleIsosurfaces) { std::vector colors = { vec4f(0.2f, 0.2f, 0.8f, 1.f), vec4f(0.8f, 0.2f, 0.2f, 1.f)}; isoModel.setParam("color", cpp::CopiedData(colors)); } isoModel.setParam("material", mat); isoModel.commit(); group.setParam("geometry", cpp::CopiedData(isoModel)); } group.commit(); return group; } cpp::World ParticleVolume::buildWorld() const { // Skip clipping if not enabled std::vector instances; if (withClipping) { // Create clipping plane std::vector geometricModels; { cpp::Geometry planeGeometry("plane"); std::vector coefficients = {vec4f(1.f, -1.f, 1.f, 0.f)}; planeGeometry.setParam( "plane.coefficients", cpp::CopiedData(coefficients)); planeGeometry.commit(); cpp::GeometricModel model(planeGeometry); model.commit(); geometricModels.emplace_back(model); } // Create clipping sphere { cpp::Geometry sphereGeometry("sphere"); std::vector position = {vec3f(.2f, -.2f, .2f)}; sphereGeometry.setParam("sphere.position", cpp::CopiedData(position)); sphereGeometry.setParam("radius", .5f); sphereGeometry.commit(); cpp::GeometricModel model(sphereGeometry); model.commit(); geometricModels.emplace_back(model); } cpp::Group group; group.setParam("clippingGeometry", cpp::CopiedData(geometricModels)); group.commit(); cpp::Instance inst(group); inst.commit(); instances.push_back(inst); } auto world = Builder::buildWorld(instances); return world; } OSP_REGISTER_TESTING_BUILDER( ParticleVolume(1000, true, false, false, false, true, 0.f, 4.f), particle_volume); OSP_REGISTER_TESTING_BUILDER( ParticleVolume(1000, false, true, false, false, true, 0.f, 4.f), particle_volume_isosurface); OSP_REGISTER_TESTING_BUILDER( ParticleVolume(1000, true, false, true, false, true, 0.f, 4.f), clip_particle_volume); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/PerlinNoiseVolumes.cpp000066400000000000000000000231371464752671100307250ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "Noise.h" #include "ospray_testing.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/utility/multidim_index_sequence.h" #include "rkcommon/utility/random.h" // stl #include #include using namespace rkcommon::math; namespace ospray { namespace testing { struct PerlinNoiseVolumes : public detail::Builder { PerlinNoiseVolumes(bool clip = false, bool gradientShading = false); PerlinNoiseVolumes(const vec3ui &numVolumes, const vec3ul &volumeDimensions, float densityScale); ~PerlinNoiseVolumes() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: vec3ui numVolumes{1, 1, 1}; vec3ul volumeDimensions{128}; bool addSphereVolume{true}; bool addTorusVolume{true}; bool addBoxes{false}; bool addAreaLight{true}; bool addAmbientLight{true}; float densityScale{10.f}; float anisotropy{0.f}; float gradientShadingScale{0.f}; bool withClipping{false}; }; // Inlined definitions //////////////////////////////////////////////////// // Helper functions // cpp::Geometry makeBoxGeometry(const box3f &box) { cpp::Geometry ospGeometry("box"); ospGeometry.setParam("box", cpp::CopiedData(box)); ospGeometry.commit(); return ospGeometry; } cpp::VolumetricModel createProceduralVolumetricModel( std::function D, const std::vector &colors, const std::vector &opacities, const vec3ul &dims, float densityScale, float anisotropy, float gradientShadingScale) { const float spacing = 3.f / (reduce_max(dims) - 1); cpp::Volume volume("structuredRegular"); // generate volume data auto numVoxels = dims.product(); std::vector voxels(numVoxels, 0); tasking::parallel_for(dims.z, [&](uint64_t z) { for (uint64_t y = 0; y < dims.y; ++y) { for (uint64_t x = 0; x < dims.x; ++x) { vec3f p = vec3f(x + 0.5f, y + 0.5f, z + 0.5f) / dims; if (D(p)) voxels[dims.x * dims.y * z + dims.x * y + x] = 0.5f + 0.5f * PerlinNoise::noise(p, 12); } } }); // calculate voxel range range1f voxelRange; std::for_each(voxels.begin(), voxels.end(), [&](float &v) { if (!std::isnan(v)) voxelRange.extend(v); }); volume.setParam("data", cpp::CopiedData(voxels.data(), dims)); volume.setParam("gridOrigin", vec3f(-1.5f, -1.5f, -1.5f)); volume.setParam("gridSpacing", vec3f(spacing)); volume.commit(); cpp::TransferFunction tfn("piecewiseLinear"); tfn.setParam("value", voxelRange); tfn.setParam("color", cpp::CopiedData(colors)); tfn.setParam("opacity", cpp::CopiedData(opacities)); tfn.commit(); cpp::VolumetricModel volumeModel(volume); volumeModel.setParam("densityScale", densityScale); volumeModel.setParam("anisotropy", anisotropy); volumeModel.setParam("transferFunction", tfn); volumeModel.setParam("gradientShadingScale", gradientShadingScale); volumeModel.commit(); return volumeModel; } cpp::GeometricModel createGeometricModel(cpp::Geometry geo, const vec3f &kd) { cpp::GeometricModel geometricModel(geo); cpp::Material objMaterial("obj"); objMaterial.setParam("kd", kd); objMaterial.commit(); geometricModel.setParam("material", objMaterial); return geometricModel; } // PerlineNoiseVolumes definitions // PerlinNoiseVolumes::PerlinNoiseVolumes(bool clip, bool gradientShading) : gradientShadingScale(gradientShading), withClipping(clip) {} PerlinNoiseVolumes::PerlinNoiseVolumes(const vec3ui &numVolumes, const vec3ul &volumeDimensions, float densityScale) : numVolumes(numVolumes), volumeDimensions(volumeDimensions), addAreaLight(false), densityScale(densityScale) {} void PerlinNoiseVolumes::commit() { Builder::commit(); // Should be at least 2 volumeDimensions = getParam("volumeDimensions", volumeDimensions); addSphereVolume = getParam("addSphereVolume", addSphereVolume); addTorusVolume = getParam("addTorusVolume", addTorusVolume); addBoxes = getParam("addBoxes", addBoxes); addAreaLight = getParam("addAreaLight", addAreaLight); addAmbientLight = getParam("addAmbientLight", addAmbientLight); densityScale = getParam("densityScale", densityScale); anisotropy = getParam("anisotropy", anisotropy); gradientShadingScale = getParam("gradientShadingScale", gradientShadingScale); withClipping = getParam("withClipping", withClipping); } cpp::Group PerlinNoiseVolumes::buildGroup() const { cpp::Group group; std::vector volumetricModels; if (addSphereVolume) { volumetricModels.emplace_back(createProceduralVolumetricModel( [](const vec3f &p) { return turbulentSphere(p, 1.f); }, {vec3f(0.f, 0.0f, 0.f), vec3f(1.f, 0.f, 0.f), vec3f(0.f, 1.f, 1.f), vec3f(1.f, 1.f, 1.f)}, {0.f, 0.33f, 0.66f, 1.f}, volumeDimensions, densityScale, anisotropy, gradientShadingScale)); } if (addTorusVolume) { volumetricModels.emplace_back(createProceduralVolumetricModel( [](const vec3f &p) { return turbulentTorus(p, 1.f, 0.375f); }, {vec3f(0.0, 0.0, 0.0), vec3f(1.0, 0.65, 0.0), vec3f(0.12, 0.6, 1.0), vec3f(1.0, 1.0, 1.0)}, {0.f, 0.33f, 0.66f, 1.f}, volumeDimensions, densityScale, anisotropy, gradientShadingScale)); } for (auto &volumetricModel : volumetricModels) volumetricModel.commit(); std::vector geometricModels; if (addBoxes) { auto box1 = makeBoxGeometry( box3f(vec3f(-1.5f, -1.f, -0.75f), vec3f(-0.5f, 0.f, 0.25f))); auto box2 = makeBoxGeometry(box3f(vec3f(0.0f, -1.5f, 0.f), vec3f(2.f, 1.5f, 2.f))); geometricModels.emplace_back( createGeometricModel(box1, vec3f(0.2f, 0.2f, 0.2f))); geometricModels.emplace_back( createGeometricModel(box2, vec3f(0.2f, 0.2f, 0.2f))); } for (auto &geometricModel : geometricModels) geometricModel.commit(); if (!volumetricModels.empty()) group.setParam("volume", cpp::CopiedData(volumetricModels)); if (!geometricModels.empty()) group.setParam("geometry", cpp::CopiedData(geometricModels)); group.commit(); return group; } cpp::World PerlinNoiseVolumes::buildWorld() const { // Skip clipping if not enabled std::vector instances; if (withClipping) { // Create clipping sphere cpp::Geometry sphereGeometry("sphere"); std::vector position = {vec3f(-.5f, .2f, -.5f)}; sphereGeometry.setParam("sphere.position", cpp::CopiedData(position)); sphereGeometry.setParam("radius", 1.2f); sphereGeometry.commit(); cpp::GeometricModel model(sphereGeometry); model.commit(); cpp::Group group; group.setParam("clippingGeometry", cpp::CopiedData(model)); group.commit(); cpp::Instance inst(group); inst.commit(); instances.push_back(inst); } // Create a group with volumes auto group = buildGroup(); const box3f groupBounds = group.getBounds(); // Create instances std::mt19937 gen(randomSeed); utility::uniform_real_distribution dstrX( groupBounds.lower.x, groupBounds.upper.x); utility::uniform_real_distribution dstrY( groupBounds.lower.y, groupBounds.upper.y); utility::uniform_real_distribution dstrZ( groupBounds.lower.z, groupBounds.upper.z); const vec3f totalSize = groupBounds.size() * (numVolumes - 1); box3f sceneBounds; index_sequence_3D indexVolumes(numVolumes); for (const vec3ui i : indexVolumes) { vec3f rndT = vec3f(0.0f); if (i != vec3ui(0)) { rndT.x = dstrX(gen); rndT.y = dstrY(gen); rndT.z = dstrZ(gen); } const vec3f position = groupBounds.size() * vec3f(i.x, i.y, i.z) - 0.5f * vec3f(totalSize.x, 0.0f, totalSize.z) + rndT; cpp::Instance instance(group); instance.setParam("transform", affine3f::translate(position)); instance.commit(); instances.push_back(instance); sceneBounds.extend(groupBounds + position); } if (addPlane) instances.push_back(makeGroundPlane(sceneBounds)); cpp::World world; world.setParam("instance", cpp::CopiedData(instances)); std::vector lightHandles; cpp::Light quadLight("quad"); quadLight.setParam("position", vec3f(-4.0f, 3.0f, 1.0f)); quadLight.setParam("edge1", vec3f(0.f, 0.0f, -1.0f)); quadLight.setParam("edge2", vec3f(1.0f, 0.5, 0.0f)); quadLight.setParam("intensity", 50.0f); quadLight.setParam("color", vec3f(2.6f, 2.5f, 2.3f)); quadLight.commit(); cpp::Light ambientLight("ambient"); ambientLight.setParam("intensity", 0.4f); ambientLight.setParam("color", vec3f(1.f)); ambientLight.setParam("visible", false); ambientLight.commit(); if (addAreaLight) lightHandles.push_back(quadLight); if (addAmbientLight) lightHandles.push_back(ambientLight); if (lightHandles.empty()) world.removeParam("light"); else world.setParam("light", cpp::CopiedData(lightHandles)); return world; } OSP_REGISTER_TESTING_BUILDER(PerlinNoiseVolumes, perlin_noise_volumes); OSP_REGISTER_TESTING_BUILDER( PerlinNoiseVolumes({7, 7, 13}, {8}, .4f), perlin_noise_many_volumes); OSP_REGISTER_TESTING_BUILDER( PerlinNoiseVolumes(true), clip_perlin_noise_volumes); OSP_REGISTER_TESTING_BUILDER( PerlinNoiseVolumes(false, true), perlin_noise_volumes_gradient); OSP_REGISTER_TESTING_BUILDER( PerlinNoiseVolumes(true, true), clip_perlin_noise_volumes_gradient); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Planes.cpp000066400000000000000000000032341464752671100263410ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct Planes : public detail::Builder { Planes() = default; ~Planes() override = default; void commit() override; cpp::Group buildGroup() const override; }; // Inlined definitions //////////////////////////////////////////////////// void Planes::commit() { Builder::commit(); addPlane = false; } cpp::Group Planes::buildGroup() const { // Create plane geometry cpp::Geometry planeGeometry("plane"); std::vector coeffs; std::vector bounds; const box3f b = box3f(vec3f(-2.f, -2.f, -1.f), vec3f(2.f, 2.f, 1.f)); const uint32_t count = 28; for (uint32_t i = 0; i < count; i++) { affine3f rotate = affine3f::rotate( vec3f(.3f, 0.f, 1.f), (i / float(count)) * 2.0f * M_PI); vec3f p = xfmNormal(rotate, vec3f(1.f, 0.f, 0.f)); coeffs.push_back(vec4f(p.x, p.y, p.z, 0.f)); bounds.push_back(b); } planeGeometry.setParam("plane.coefficients", cpp::CopiedData(coeffs)); planeGeometry.setParam("plane.bounds", cpp::CopiedData(bounds)); planeGeometry.commit(); // Create geometric model cpp::GeometricModel model(planeGeometry); cpp::Material material("obj"); material.setParam("kd", vec3f(.1f, .4f, .8f)); material.commit(); model.setParam("material", material); model.commit(); // Create group cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); // Done return group; } OSP_REGISTER_TESTING_BUILDER(Planes, planes); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/RandomSpheres.cpp000066400000000000000000000057151464752671100276770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/random.h" // stl #include using namespace rkcommon::math; namespace ospray { namespace testing { struct Spheres : public detail::Builder { Spheres(OSPSphereType type); ~Spheres() override = default; void commit() override; cpp::Group buildGroup() const override; private: // Data // OSPSphereType sphereType; int numSpheres{100}; }; // Inlined definitions //////////////////////////////////////////////////// Spheres::Spheres(OSPSphereType type) : sphereType(type) {} void Spheres::commit() { Builder::commit(); numSpheres = getParam("numSpheres", 100); } cpp::Group Spheres::buildGroup() const { std::vector s_center(numSpheres); std::vector s_radius(numSpheres); std::vector s_colors(numSpheres); // create random number distributions for sphere center, radius, and color std::mt19937 gen(randomSeed); utility::uniform_real_distribution centerDistribution(-1.f, 1.f); utility::uniform_real_distribution radiusDistribution(0.05f, 0.15f); utility::uniform_real_distribution colorDistribution(0.5f, 1.f); // populate the spheres for (auto ¢er : s_center) { center.x = centerDistribution(gen); center.y = centerDistribution(gen); center.z = centerDistribution(gen); } for (auto &radius : s_radius) radius = radiusDistribution(gen); for (auto &c : s_colors) { c.x = colorDistribution(gen); c.y = colorDistribution(gen); c.z = colorDistribution(gen); c.w = colorDistribution(gen); } // create the sphere geometry, and assign attributes cpp::Geometry spheresGeometry("sphere"); spheresGeometry.setParam("type", sphereType); spheresGeometry.setParam("sphere.position", cpp::CopiedData(s_center)); if (sphereType == OSP_ORIENTED_DISC) { spheresGeometry.setParam("sphere.normal", cpp::CopiedData(s_center)); } spheresGeometry.setParam("sphere.radius", cpp::CopiedData(s_radius)); spheresGeometry.commit(); cpp::GeometricModel model(spheresGeometry); model.setParam("color", cpp::CopiedData(s_colors)); if (rendererType == "pathtracer") { // create glass material and assign to geometry cpp::Material glassMaterial("thinGlass"); glassMaterial.setParam("attenuationDistance", 0.2f); glassMaterial.commit(); model.setParam("material", glassMaterial); } else { cpp::Material glassMaterial("obj"); glassMaterial.commit(); model.setParam("material", glassMaterial); } model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } OSP_REGISTER_TESTING_BUILDER(Spheres(OSP_SPHERE), random_spheres); OSP_REGISTER_TESTING_BUILDER(Spheres(OSP_DISC), random_discs); OSP_REGISTER_TESTING_BUILDER(Spheres(OSP_ORIENTED_DISC), random_oriented_discs); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Streamlines.cpp000066400000000000000000000077021464752671100274110ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/random.h" // stl #include using namespace rkcommon::math; namespace ospray { namespace testing { struct Streamlines : public detail::Builder { Streamlines() = default; ~Streamlines() override = default; void commit() override; cpp::Group buildGroup() const override; }; // Inlined definitions //////////////////////////////////////////////////// void Streamlines::commit() { Builder::commit(); addPlane = false; } cpp::Group Streamlines::buildGroup() const { cpp::Geometry slGeom("curve"); std::vector points; std::vector indices; std::vector colors; std::mt19937 rng(randomSeed); utility::uniform_real_distribution radDist(0.5f, 1.5f); utility::uniform_real_distribution stepDist(0.001f, 0.1f); utility::uniform_real_distribution sDist(0, 360); utility::uniform_real_distribution dDist(360, 720); utility::uniform_real_distribution freqDist(0.5f, 1.5f); // create multiple lines int numLines = 100; for (int l = 0; l < numLines; l++) { int dStart = sDist(rng); int dEnd = dDist(rng); float radius = radDist(rng); float h = 0; float hStep = stepDist(rng); float f = freqDist(rng); float r = (720 - dEnd) / 360.f; vec4f c(r, 1 - r, 1 - r / 2, 1.f); // spiral up with changing radius of curvature for (int d = dStart; d < dStart + dEnd; d += 10, h += hStep) { vec3f p, q; float startRadius, endRadius; p.x = radius * std::sin(d * M_PI / 180.f); p.y = h - 2; p.z = radius * std::cos(d * M_PI / 180.f); startRadius = 0.015f * std::sin(f * d * M_PI / 180) + 0.02f; q.x = (radius - 0.05f) * std::sin((d + 10) * M_PI / 180.f); q.y = h + hStep - 2; q.z = (radius - 0.05f) * std::cos((d + 10) * M_PI / 180.f); endRadius = 0.015f * std::sin(f * (d + 10) * M_PI / 180) + 0.02f; if (d == dStart) { const vec3f rim = lerp(1.f + endRadius / length(q - p), q, p); const vec3f cap = lerp(1.f + startRadius / length(rim - p), p, rim); points.push_back(vec4f(cap, 0.f)); points.push_back(vec4f(rim, 0.f)); points.push_back(vec4f(p, startRadius)); points.push_back(vec4f(q, endRadius)); indices.push_back(points.size() - 4); colors.push_back(c); colors.push_back(c); } else if (d + 10 < dStart + dEnd && d + 20 > dStart + dEnd) { const vec3f rim = lerp(1.f + startRadius / length(p - q), p, q); const vec3f cap = lerp(1.f + endRadius / length(rim - q), q, rim); points.push_back(vec4f(p, startRadius)); points.push_back(vec4f(q, endRadius)); points.push_back(vec4f(rim, 0.f)); points.push_back(vec4f(cap, 0.f)); indices.push_back(points.size() - 7); indices.push_back(points.size() - 6); indices.push_back(points.size() - 5); indices.push_back(points.size() - 4); colors.push_back(c); colors.push_back(c); } else if ((d != dStart && d != dStart + 10) && d + 20 < dStart + dEnd) { points.push_back(vec4f(p, startRadius)); indices.push_back(points.size() - 4); } colors.push_back(c); radius -= 0.05f; } } slGeom.setParam("vertex.position_radius", cpp::CopiedData(points)); slGeom.setParam("index", cpp::CopiedData(indices)); slGeom.setParam("vertex.color", cpp::CopiedData(colors)); slGeom.setParam("type", OSP_ROUND); slGeom.setParam("basis", OSP_CATMULL_ROM); slGeom.commit(); cpp::GeometricModel model(slGeom); cpp::Material slMat("obj"); slMat.commit(); model.setParam("material", slMat); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } OSP_REGISTER_TESTING_BUILDER(Streamlines, streamlines); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/SubdivisionCube.cpp000066400000000000000000000062731464752671100302220ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct SubdivisionCube : public detail::Builder { SubdivisionCube() = default; ~SubdivisionCube() override = default; cpp::Group buildGroup() const override; }; // Inlined definitions //////////////////////////////////////////////////// cpp::Group SubdivisionCube::buildGroup() const { // vertices of a cube std::vector vertices = {{-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {-1.0f, 1.0f, -1.0f}, {1.0f, 1.0f, -1.0f}, {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, /*WA: pad for Embree*/ {0.0f}}; // color per vertex std::vector colors = {{0.0f, 0.0f, 0.0f, 1.f}, {1.0f, 0.0f, 0.0f, 1.f}, {1.0f, 0.0f, 1.0f, 1.f}, {0.0f, 0.0f, 1.0f, 1.f}, {0.0f, 1.0f, 0.0f, 1.f}, {1.0f, 1.0f, 0.0f, 1.f}, {1.0f, 1.0f, 1.0f, 1.f}, {0.0f, 1.0f, 1.0f, 1.f}}; // number of vertex indices per face std::vector faces = {4, 4, 4, 4, 4, 4}; // vertex indices for all faces std::vector indices = { 0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 0, 3, 7, 4, 4, 7, 6, 5, 0, 1, 2, 3, }; // vertex crease indices and weights std::vector vertexCreaseIndices = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vertexCreaseWeights = { 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f}; // edge crease indices and weights std::vector edgeCreaseIndices = {{0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}}; std::vector edgeCreaseWeights = { 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f}; // global level of tessellation float level = 5.f; // create the OSPRay geometry and set all parameters cpp::Geometry geometry("subdivision"); geometry.setParam("vertex.position", cpp::CopiedData(vertices)); geometry.setParam("vertex.color", cpp::CopiedData(colors)); geometry.setParam("face", cpp::CopiedData(faces)); geometry.setParam("index", cpp::CopiedData(indices)); geometry.setParam("vertexCrease.index", cpp::CopiedData(vertexCreaseIndices)); geometry.setParam("vertexCrease.weight", cpp::CopiedData(vertexCreaseWeights)); geometry.setParam("edgeCrease.index", cpp::CopiedData(edgeCreaseIndices)); geometry.setParam("edgeCrease.weight", cpp::CopiedData(edgeCreaseWeights)); geometry.setParam("level", level); geometry.setParam("mode", OSP_SUBDIVISION_PIN_CORNERS); geometry.commit(); cpp::GeometricModel model(geometry); cpp::Material material("obj"); material.commit(); model.setParam("material", material); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } OSP_REGISTER_TESTING_BUILDER(SubdivisionCube, subdivision_cube); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/Transparency.cpp000066400000000000000000000112271464752671100275710ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct Transparency : public detail::Builder { Transparency() = default; ~Transparency() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; }; // Inlined definitions //////////////////////////////////////////////////// void Transparency::commit() { Builder::commit(); addPlane = true; } cpp::Group Transparency::buildGroup() const { // Create plane geometry cpp::Geometry planeGeometry("plane"); { std::vector coeffs = {{0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 1.f, -.4f}, {0.f, 0.f, 1.f, -.45f}, {0.f, 0.f, 1.f, -.5f}}; std::vector bounds = {{{-2.f, 1.8f, -2.f}, {2.f, 2.f, 2.f}}, {{-2.f, 1.6f, -2.f}, {2.f, 1.8f, 2.f}}, {{-2.f, 1.4f, -2.f}, {2.f, 1.6f, 2.f}}, {{-2.f, 0.2f, -2.f}, {2.f, 1.4f, 2.f}}, {{-1.7f, 1.f, -1.f}, {-.3f, 2.f, 1.f}}, {{-.7f, 1.f, -1.f}, {.7f, 2.f, 1.f}}, {{.3f, 1.f, -1.f}, {1.7f, 2.f, 1.f}}}; planeGeometry.setParam("plane.coefficients", cpp::CopiedData(coeffs)); planeGeometry.setParam("plane.bounds", cpp::CopiedData(bounds)); planeGeometry.commit(); } // Create geometric model cpp::GeometricModel gModel(planeGeometry); { std::vector colors = {{.8f, 0.f, 0.f}, {0.f, .8f, 0.f}, {0.f, 0.f, .8f}, {.8f, .8f, .8f}, {.5f, 0.f, 0.f}, {0.f, .5f, 0.f}, {0.f, 0.f, .5f}}; std::vector transmissions = {{0.f, 0.f, 0.f}, {0.f, 0.f, 0.f}, {0.f, 0.f, 0.f}, {0.f, 0.f, 0.f}, {.8f, 0.f, 0.f}, {0.f, .8f, 0.f}, {0.f, 0.f, .8f}}; std::vector materials; for (uint32_t i = 0; i < std::min(colors.size(), transmissions.size()); i++) { materials.emplace_back(cpp::Material("obj")); materials[i].setParam("kd", colors[i]); materials[i].setParam("tf", transmissions[i]); materials[i].commit(); } gModel.setParam("material", cpp::CopiedData(materials)); gModel.commit(); } // Create volume object with values being shortest distance to surface for // gradient shading working correctly cpp::Volume volume("structuredRegular"); { volume.setParam("gridOrigin", vec3f(-2.f, -.7f, -.1f)); volume.setParam("gridSpacing", vec3f(.1f)); const vec3i volumeCells{41, 10, 5}; std::vector voxels(volumeCells.long_product()); index_sequence_3D numCell(volumeCells); for (vec3i i : numCell) { voxels[numCell.flatten(i)] = (float)std::min( {i.x < (volumeCells.x / 2) ? i.x : volumeCells.x - i.x - 1, i.y < (volumeCells.y / 2) ? i.y : volumeCells.y - i.y - 1, i.z < (volumeCells.z / 2) ? i.z : volumeCells.z - i.z - 1}); } volume.setParam("data", cpp::CopiedData(voxels.data(), volumeCells)); volume.commit(); } // Create volume model cpp::VolumetricModel vModel(volume); { // Create transfer function cpp::TransferFunction transferFunction("piecewiseLinear"); { std::vector colors = {{1.f, 1.f, 1.f}}; std::vector opacities = {1.f}; transferFunction.setParam("color", cpp::CopiedData(colors)); transferFunction.setParam("opacity", cpp::CopiedData(opacities)); transferFunction.setParam("value", range1f(0.f, 10.f)); transferFunction.commit(); } vModel.setParam("transferFunction", transferFunction); vModel.setParam("densityScale", 10.f); vModel.setParam("gradientShadingScale", 1.f); vModel.commit(); } // Create group cpp::Group group; group.setParam("geometry", cpp::CopiedData(gModel)); group.setParam("volume", cpp::CopiedData(vModel)); group.commit(); // Done return group; } cpp::World Transparency::buildWorld() const { auto world = Builder::buildWorld(); cpp::Light light("distant"); light.setParam("color", vec3f(0.78f, 0.551f, 0.483f)); light.setParam("intensity", 3.14f); light.setParam("direction", vec3f(0.f, -0.75f, 0.25f)); light.commit(); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.5f); ambient.setParam("visible", false); ambient.commit(); std::vector lights{light, ambient}; world.setParam("light", cpp::CopiedData(lights)); return world; } OSP_REGISTER_TESTING_BUILDER(Transparency, transparency); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/UnstructuredVolumeGen.cpp000066400000000000000000000241441464752671100314530ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace { // List degenerate tetrahedrons std::vector> tetraNotAllowed = {{0, 1, 2, 3}, {4, 5, 6, 7}, {0, 3, 4, 7}, {1, 2, 5, 6}, {0, 1, 4, 5}, {2, 3, 6, 7}}; // Allowed pyramid indices order std::vector> pyramidAllowed = {{0, 1, 2, 3, 4}, {0, 1, 2, 3, 5}, {0, 1, 2, 3, 6}, {0, 1, 2, 3, 7}, {4, 5, 6, 7, 0}, {4, 5, 6, 7, 1}, {4, 5, 6, 7, 2}, {4, 5, 6, 7, 3}, {0, 4, 7, 3, 1}, {0, 4, 7, 3, 2}, {0, 4, 7, 3, 5}, {0, 4, 7, 3, 6}, {1, 5, 6, 2, 0}, {1, 5, 6, 2, 3}, {1, 5, 6, 2, 4}, {1, 5, 6, 2, 7}, {0, 1, 5, 4, 2}, {0, 1, 5, 4, 3}, {0, 1, 5, 4, 6}, {0, 1, 5, 4, 7}, {2, 6, 7, 3, 0}, {2, 6, 7, 3, 1}, {2, 6, 7, 3, 4}, {2, 6, 7, 3, 5}}; // Allowed wedge indices order std::vector> wedgeAllowed = {{0, 1, 2, 4, 5, 6}, {1, 2, 3, 5, 6, 7}, {0, 2, 3, 4, 6, 7}, {0, 1, 3, 4, 5, 7}, {0, 4, 3, 1, 5, 2}, {0, 4, 7, 1, 5, 6}, {4, 7, 3, 5, 6, 2}, {0, 7, 3, 1, 6, 2}, {0, 1, 5, 3, 2, 6}, {1, 5, 4, 2, 6, 7}, {5, 4, 0, 6, 7, 3}, {0, 1, 4, 3, 2, 7}}; // Allowed wedge+pyramid indices order std::vector> wedgePyramidAllowed = { {0, 1, 2, 4, 5, 6, 0, 2, 6, 4, 3}, {0, 1, 2, 4, 5, 6, 0, 2, 6, 4, 7}, {1, 2, 3, 5, 6, 7, 1, 5, 7, 3, 0}, {1, 2, 3, 5, 6, 7, 1, 5, 7, 3, 4}, {0, 2, 3, 4, 6, 7, 0, 2, 6, 4, 1}, {0, 2, 3, 4, 6, 7, 0, 2, 6, 4, 5}, {0, 1, 3, 4, 5, 7, 1, 5, 7, 3, 2}, {0, 1, 3, 4, 5, 7, 1, 5, 7, 3, 6}}; // Indices order of all allowed primitives, indexed with 8-vertices mask std::array, 256> primsAllowed; // Not allowed primitives indexed with 8-vertices mask std::array primsNotAllowed; void initializeFromArray(const std::vector> &array) { for (auto &order : array) { uint32_t mask = 0; for (uint32_t i : order) mask |= (1 << i); std::vector &ids = primsAllowed[mask]; ids.insert(ids.begin(), order.begin(), order.end()); } } void initializePrims() { // Initialize degenerate tetrahedrons for (auto &order : tetraNotAllowed) { uint32_t mask = 0; for (uint32_t i : order) mask |= (1 << i); primsNotAllowed[mask] = true; } // Initialize allowed primitives with its indices orders initializeFromArray(pyramidAllowed); initializeFromArray(wedgeAllowed); initializeFromArray(wedgePyramidAllowed); } float sphere(const vec3f &p, const vec3f ¢er, float radius) { vec3f t = p - center; return sqrt(t.x * t.x + t.y * t.y + t.z * t.z) - radius; } float ground(const vec3f &p, const vec3f ¢er) { vec3f t = p - center; return t.y + .1f * sin(10.f * t.x) + .1f * sin(10.f * t.z); } float sdf(const vec3f &p) { return std::min({ground(p, vec3f(0.f, -.7f, 0.f)), sphere(p, vec3f(0.f, .2f, 0.f), .6f), sphere(p, vec3f(.7f, 0.f, .7f), .3f), sphere(p, vec3f(-.6f, -.3f, -.6f), .25f)}); } } // namespace namespace ospray { namespace testing { struct UnstructuredVolumeGen : public detail::Builder { UnstructuredVolumeGen(bool transform = false, bool isosurface = false) : transform(transform), isosurface(isosurface) {} ~UnstructuredVolumeGen() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: bool showCells{false}; float densityScale{1.f}; bool transform{false}; bool isosurface{false}; }; // Inlined definitions //////////////////////////////////////////////////// void UnstructuredVolumeGen::commit() { Builder::commit(); showCells = getParam("showCells", false); densityScale = getParam("densityScale", showCells ? 100.f : 3.f); tfOpacityMap = getParam( "tf.opacityMap", showCells ? "opaque" : "linearInv"); addPlane = false; } cpp::Group UnstructuredVolumeGen::buildGroup() const { // Prepare 3D grid vec3i dimensions = vec3i(30, 30, 30); index_sequence_3D numVertices(dimensions); std::vector positions; std::vector values; float size = 2.f; positions.resize(numVertices.total_indices()); values.resize(numVertices.total_indices()); for (auto i : numVertices) { vec3f i_f = static_cast(i); vec3f p = size * (i_f / (dimensions - 1) - .5f); uint32_t id = numVertices.flatten(i); values[id] = sdf(p); if (transform) p.z *= 0.25f; positions[id] = p; } // Initialize primitive arrays initializePrims(); // Iterate through all cubic cells in the created grid // and build appropriate unstructured cells index_sequence_3D numHex(dimensions - 1); std::vector indices; std::vector cells; std::vector cellTypes; std::vector cellValues; for (auto i : numHex) { std::vector ids = { (uint32_t)numVertices.flatten(i + vec3i(1, 0, 0)), (uint32_t)numVertices.flatten(i + vec3i(0, 0, 0)), (uint32_t)numVertices.flatten(i + vec3i(0, 0, 1)), (uint32_t)numVertices.flatten(i + vec3i(1, 0, 1)), (uint32_t)numVertices.flatten(i + vec3i(1, 1, 0)), (uint32_t)numVertices.flatten(i + vec3i(0, 1, 0)), (uint32_t)numVertices.flatten(i + vec3i(0, 1, 1)), (uint32_t)numVertices.flatten(i + vec3i(1, 1, 1))}; // Calculate mask for cubic cell consisting of 8 vertices, uint32_t mask = 0; uint32_t count = 0; for (uint32_t i = 0; i < 8; i++) { uint32_t bit = 1 << i; if (values[ids[i]] < 0.f) { mask |= bit; count++; } } // Depending on number of bits set switch (count) { // Build tetrahedron case 4: { if (primsNotAllowed[mask]) break; cells.push_back(indices.size()); cellTypes.push_back(OSP_TETRAHEDRON); cellValues.push_back(0.8f); for (uint32_t i = 0; i < 8; i++) if ((mask >> i) & 1) indices.push_back(ids[i]); } break; // Build pyramid case 5: { std::vector &pa = primsAllowed[mask]; if (pa.empty()) break; cells.push_back(indices.size()); cellTypes.push_back(OSP_PYRAMID); for (uint32_t i : pa) indices.push_back(ids[i]); cellValues.push_back(0.6f); } break; // Build wedge case 6: { std::vector &pa = primsAllowed[mask]; if (pa.empty()) break; cells.push_back(indices.size()); cellTypes.push_back(OSP_WEDGE); for (uint32_t i : pa) indices.push_back(ids[i]); cellValues.push_back(0.4f); } break; // Build wedge and pyramid case 7: { std::vector &pa = primsAllowed[mask]; if (pa.empty()) break; cells.push_back(indices.size()); cells.push_back(indices.size() + 6); cellTypes.push_back(OSP_WEDGE); cellTypes.push_back(OSP_PYRAMID); for (uint32_t i : pa) indices.push_back(ids[i]); cellValues.push_back(0.4f); cellValues.push_back(0.6f); } break; // Build hexahedron case 8: { cells.push_back(indices.size()); cellTypes.push_back(OSP_HEXAHEDRON); indices.insert(indices.end(), ids.begin(), ids.end()); cellValues.push_back(0.2f); } break; } } // Create and configure volume object cpp::Volume volume("unstructured"); volume.setParam("vertex.position", cpp::CopiedData(positions)); if (showCells) volume.setParam("cell.data", cpp::CopiedData(cellValues)); else volume.setParam("vertex.data", cpp::CopiedData(values)); volume.setParam("index", cpp::CopiedData(indices)); volume.setParam("cell.index", cpp::CopiedData(cells)); volume.setParam("cell.type", cpp::CopiedData(cellTypes)); volume.setParam("hexIterative", true); volume.commit(); cpp::Group group; if (isosurface) { cpp::Geometry isoGeom("isosurface"); std::vector isovalues = {-0.2f}; isoGeom.setParam("isovalue", cpp::CopiedData(isovalues)); isoGeom.setParam("volume", volume); isoGeom.commit(); cpp::GeometricModel isoModel(isoGeom); cpp::Material mat("obj"); mat.setParam("kd", vec3f(0.8f)); mat.setParam("ks", vec3f(0.2f)); mat.commit(); isoModel.setParam("material", mat); isoModel.commit(); group.setParam("geometry", cpp::CopiedData(isoModel)); } else { cpp::VolumetricModel model(volume); model.setParam("transferFunction", makeTransferFunction( showCells ? range1f{0.f, 1.f} : range1f{-.4f, -.05f})); model.setParam("densityScale", densityScale); model.commit(); group.setParam("volume", cpp::CopiedData(model)); } group.commit(); return group; } cpp::World UnstructuredVolumeGen::buildWorld() const { if (!transform) return Builder::buildWorld(); auto group = buildGroup(); cpp::Instance instance(group); AffineSpace3f xform(LinearSpace3f::rotate(vec3f(2.2f, 1.0f, -0.35f), 0.4f) * LinearSpace3f::scale(vec3f(1.0f, 1.0f, 4.0f)), vec3f(0.1f, -0.3, 2.f)); instance.setParam("transform", xform); instance.commit(); std::vector inst; inst.push_back(instance); cpp::Light light("distant"); light.setParam("direction", vec3f(-0.8f, -0.6f, 0.3f)); light.setParam("color", vec3f(0.78f, 0.551f, 0.483f)); light.setParam("intensity", 3.14f); light.setParam("angularDiameter", 1.f); light.commit(); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.35f); ambient.setParam("visible", false); ambient.commit(); std::vector lights{light, ambient}; cpp::World world; world.setParam("instance", cpp::CopiedData(inst)); world.setParam("light", cpp::CopiedData(lights)); return world; } OSP_REGISTER_TESTING_BUILDER(UnstructuredVolumeGen, unstructured_volume); OSP_REGISTER_TESTING_BUILDER( UnstructuredVolumeGen(true), unstructured_volume_transformed); OSP_REGISTER_TESTING_BUILDER( UnstructuredVolumeGen(true, true), unstructured_volume_isosurface); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/UnstructuredVolumeSimple.cpp000066400000000000000000000113671464752671100321760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct UnstructuredVolumeSimple : public detail::Builder { UnstructuredVolumeSimple() = default; ~UnstructuredVolumeSimple() override = default; void commit() override; cpp::Group buildGroup() const override; private: bool sharedVertices{true}; bool valuesPerCell{false}; }; // Inlined definitions //////////////////////////////////////////////////// void UnstructuredVolumeSimple::commit() { Builder::commit(); sharedVertices = getParam("sharedVertices", true); valuesPerCell = getParam("cellCenteredValues", false); } cpp::Group UnstructuredVolumeSimple::buildGroup() const { // define hexahedron parameters const float hSize = .4f; const float hX = -.5f, hY = -.5f, hZ = 0.f; // define wedge parameters const float wSize = .4f; const float wX = .5f, wY = -.5f, wZ = 0.f; // define tetrahedron parameters const float tSize = .4f; const float tX = .5f, tY = .5f, tZ = 0.f; // define pyramid parameters const float pSize = .4f; const float pX = -.5f, pY = .5f, pZ = 0.f; // define vertex positions std::vector vertices = {// hexahedron {-hSize + hX, -hSize + hY, hSize + hZ}, // bottom quad {hSize + hX, -hSize + hY, hSize + hZ}, {hSize + hX, -hSize + hY, -hSize + hZ}, {-hSize + hX, -hSize + hY, -hSize + hZ}, {-hSize + hX, hSize + hY, hSize + hZ}, // top quad {hSize + hX, hSize + hY, hSize + hZ}, {hSize + hX, hSize + hY, -hSize + hZ}, {-hSize + hX, hSize + hY, -hSize + hZ}, // wedge {-wSize + wX, -wSize + wY, wSize + wZ}, // botom triangle {wSize + wX, -wSize + wY, 0.f + wZ}, {-wSize + wX, -wSize + wY, -wSize + wZ}, {-wSize + wX, wSize + wY, wSize + wZ}, // top triangle {wSize + wX, wSize + wY, 0.f + wZ}, {-wSize + wX, wSize + wY, -wSize + wZ}, // tetrahedron {-tSize + tX, -tSize + tY, tSize + tZ}, {tSize + tX, -tSize + tY, 0.f + tZ}, {-tSize + tX, -tSize + tY, -tSize + tZ}, {-tSize + tX, tSize + tY, 0.f + tZ}, // pyramid {-pSize + pX, -pSize + pY, pSize + pZ}, {pSize + pX, -pSize + pY, pSize + pZ}, {pSize + pX, -pSize + pY, -pSize + pZ}, {-pSize + pX, -pSize + pY, -pSize + pZ}, {pSize + pX, pSize + pY, 0.f + pZ}}; // define per-vertex values std::vector vertexValues = {// hexahedron 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, // wedge 0.f, 0.f, 0.f, 1.f, 0.f, 1.f, // tetrahedron 1.f, 0.f, 1.f, 0.f, // pyramid 0.f, 1.f, 1.f, 0.f, 0.f}; // define vertex indices for both shared and separate case std::vector indicesSharedVert = {// hexahedron 0, 1, 2, 3, 4, 5, 6, 7, // wedge 1, 9, 2, 5, 12, 6, // tetrahedron 5, 12, 6, 17, // pyramid 4, 5, 6, 7, 17}; std::vector indicesSeparateVert = {// hexahedron 0, 1, 2, 3, 4, 5, 6, 7, // wedge 8, 9, 10, 11, 12, 13, // tetrahedron 14, 15, 16, 17, // pyramid 18, 19, 20, 21, 22}; std::vector &indices = sharedVertices ? indicesSharedVert : indicesSeparateVert; // define cell offsets in indices array std::vector cells = {0, 8, 14, 18}; // define cell types std::vector cellTypes = { OSP_HEXAHEDRON, OSP_WEDGE, OSP_TETRAHEDRON, OSP_PYRAMID}; // define per-cell values std::vector cellValues = {0.1f, .3f, .7f, 1.f}; cpp::Volume volume("unstructured"); // set data objects for volume object volume.setParam("vertex.position", cpp::CopiedData(vertices)); if (valuesPerCell) volume.setParam("cell.data", cpp::CopiedData(cellValues)); else volume.setParam("vertex.data", cpp::CopiedData(vertexValues)); volume.setParam("index", cpp::CopiedData(indices)); volume.setParam("cell.index", cpp::CopiedData(cells)); volume.setParam("cell.type", cpp::CopiedData(cellTypes)); volume.commit(); cpp::VolumetricModel model(volume); model.setParam("transferFunction", makeTransferFunction({0.f, 1.f})); model.commit(); cpp::Group group; group.setParam("volume", cpp::CopiedData(model)); group.commit(); return group; } OSP_REGISTER_TESTING_BUILDER(UnstructuredVolumeSimple, unstructured_volume_simple); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/VdbVolume.cpp000066400000000000000000000115061464752671100270230ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "Noise.h" #include "ospray_testing.h" #include "rkcommon/math/AffineSpace.h" #include "rkcommon/tasking/parallel_for.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct VdbVolume : public detail::Builder { VdbVolume(bool packed = false) : packed(packed) {} ~VdbVolume() override = default; void commit() override; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; private: float densityScale{1.f}; float anisotropy{0.f}; bool packed{false}; static constexpr uint32_t domainRes = 128; }; // Inlined definitions //////////////////////////////////////////////////// void VdbVolume::commit() { Builder::commit(); densityScale = getParam("densityScale", 20.f); anisotropy = getParam("anisotropy", 0.f); } cpp::Group VdbVolume::buildGroup() const { cpp::Volume volume("vdb"); std::vector origin; std::vector data; std::vector dataPacked; constexpr uint32_t leafRes = 8; constexpr uint32_t N = domainRes / leafRes; constexpr size_t numLeaves = N * static_cast(N) * N; origin.reserve(numLeaves); if (!packed) data.reserve(numLeaves); std::vector leaf(leafRes * (size_t)leafRes * leafRes, 0.f); for (uint32_t z = 0; z < N; ++z) for (uint32_t y = 0; y < N; ++y) for (uint32_t x = 0; x < N; ++x) { std::vector leafValueRange(leafRes); tasking::parallel_for(leafRes, [&](uint32_t vz) { for (uint32_t vy = 0; vy < leafRes; ++vy) for (uint32_t vx = 0; vx < leafRes; ++vx) { float v = 0.f; const vec3f p((x * leafRes + vx + 0.5f) / (float)domainRes, (y * leafRes + vy + 0.5f) / (float)domainRes, (z * leafRes + vz + 0.5f) / (float)domainRes); if (turbulentTorus(p, 0.75f, 0.375f)) v = 0.5f + 0.5f * PerlinNoise::noise(p, 12); const size_t idx = vx * (size_t)leafRes * leafRes + vy * (size_t)leafRes + vz; leafValueRange[vz].extend(v); leaf.at(idx) = v; } }); // reduction for (auto &vr : leafValueRange) leafValueRange[0].extend(vr); if (leafValueRange[0].lower != 0.f || leafValueRange[0].upper != 0.f) { origin.push_back(vec3i(x * leafRes, y * leafRes, z * leafRes)); if (packed) std::copy(leaf.begin(), leaf.end(), std::back_inserter(dataPacked)); else data.emplace_back(cpp::CopiedData( leaf.data(), vec3ul(leafRes, leafRes, leafRes))); } } if (origin.empty()) throw std::runtime_error("vdb volume is empty."); volume.setParam("filter", OSP_VOLUME_FILTER_LINEAR); volume.setParam("gradientFilter", OSP_VOLUME_FILTER_LINEAR); volume.setParam( "node.level", cpp::CopiedData(std::vector(origin.size(), 3))); volume.setParam("node.origin", cpp::CopiedData(origin)); if (packed) { volume.setParam("nodesPackedDense", cpp::CopiedData(dataPacked)); volume.setParam("node.format", cpp::CopiedData(std::vector( origin.size(), OSP_VOLUME_FORMAT_DENSE_ZYX))); } else volume.setParam("node.data", cpp::CopiedData(data)); volume.commit(); cpp::VolumetricModel model(volume); model.setParam("transferFunction", makeTransferFunction({0.f, 1.f})); model.setParam("densityScale", densityScale); model.setParam("anisotropy", anisotropy); model.commit(); cpp::Group group; group.setParam("volume", cpp::CopiedData(model)); group.commit(); return group; } cpp::World VdbVolume::buildWorld() const { auto group = buildGroup(); cpp::Instance instance(group); rkcommon::math::AffineSpace3f xform( rkcommon::math::LinearSpace3f::scale(8.f / domainRes), vec3f(-4.f, 0, -4.f)); instance.setParam("transform", xform); instance.commit(); std::vector inst; inst.push_back(instance); if (addPlane) inst.push_back(makeGroundPlane(instance.getBounds())); cpp::Light quadLight("quad"); quadLight.setParam("position", vec3f(-4.f, 8.0f, 4.f)); quadLight.setParam("edge1", vec3f(0.f, 0.0f, -8.0f)); quadLight.setParam("edge2", vec3f(2.f, 1.0f, 0.0f)); quadLight.setParam("intensity", 5.0f); quadLight.setParam("color", vec3f(2.8f, 2.2f, 1.9f)); quadLight.commit(); std::vector lightHandles; lightHandles.push_back(quadLight); cpp::World world; world.setParam("instance", cpp::CopiedData(inst)); world.setParam("light", cpp::CopiedData(lightHandles)); return world; } OSP_REGISTER_TESTING_BUILDER(VdbVolume, vdb_volume); OSP_REGISTER_TESTING_BUILDER(VdbVolume(true), vdb_volume_packed); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_alloy_roughness.cpp000066400000000000000000000036301464752671100320760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtAlloyRoughness : public PtMaterial { PtAlloyRoughness() = default; ~PtAlloyRoughness() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeAlloyMaterial( vec3f color, vec3f edgeColor, float roughness) { cpp::Material mat("alloy"); mat.setParam("color", color); mat.setParam("edgeColor", edgeColor); mat.setParam("roughness", roughness); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtAlloyRoughness::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // Silver for (int i = 0; i < dimSize; ++i) { materials.push_back(makeAlloyMaterial(vec3f(.66f, .66f, .67f), vec3f(1.f, 1.f, 1.f), float(i) / (dimSize - 1))); } // Aluminium for (int i = 0; i < dimSize; ++i) { materials.push_back(makeAlloyMaterial(vec3f(.52f, .52f, .5f), vec3f(1.f, 1.f, 1.f), float(i) / (dimSize - 1))); } // Gold for (int i = 0; i < dimSize; ++i) { materials.push_back(makeAlloyMaterial(vec3f(.83f, .68f, .21f), vec3f(1.f, 1.f, 1.f), float(i) / (dimSize - 1))); } // Chromium for (int i = 0; i < dimSize; ++i) { materials.push_back(makeAlloyMaterial(vec3f(.65f, .66f, .67f), vec3f(1.f, 1.f, 1.f), float(i) / (dimSize - 1))); } // Copper for (int i = 0; i < dimSize; ++i) { materials.push_back(makeAlloyMaterial(vec3f(.72f, .45f, .2f), vec3f(1.f, 1.f, 1.f), float(i) / (dimSize - 1))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtAlloyRoughness, test_pt_alloy_roughness); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_carpaint.cpp000066400000000000000000000040551464752671100304640ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtCarPaint : public PtMaterial { PtCarPaint() = default; ~PtCarPaint() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeCarPaintMaterial( std::initializer_list> params) { cpp::Material mat("carPaint"); mat.setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); mat.setParam("flakeColor", vec3f(0.277f, 0.717f, 0.990f)); mat.setParam("flipflopColor", vec3f(0.252f, 0.0385f, 0.550f)); for (auto ¶m : params) mat.setParam(param.first, param.second); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtCarPaint::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // flakeDensity for (int i = 0; i < dimSize; i++) materials.push_back(makeCarPaintMaterial( {{"flakeDensity", float(i) / (dimSize - 1)}, {"flakeScale", 1000.f}})); // flipflopFalloff for (int i = 0; i < dimSize; i++) materials.push_back(makeCarPaintMaterial({{"flakeDensity", 1.f}, {"flakeScale", 1000.f}, {"flipflopFalloff", 1.f - float(i) / (dimSize - 1)}})); // flakeScale for (int i = 0; i < dimSize; i++) materials.push_back(makeCarPaintMaterial({{"flakeDensity", 1.f}, {"flakeScale", lerp(float(i) / (dimSize - 1), 1000.f, 100.f)}})); // flakeRoughness for (int i = 0; i < dimSize; i++) materials.push_back(makeCarPaintMaterial({{"flakeDensity", 1.f}, {"flakeScale", 1000.f}, {"flakeRoughness", float(i) / (dimSize - 1)}})); // coat for (int i = 0; i < dimSize; i++) materials.push_back( makeCarPaintMaterial({{"coat", float(i) / (dimSize - 1)}})); return materials; } OSP_REGISTER_TESTING_BUILDER(PtCarPaint, test_pt_carpaint); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_glass.cpp000066400000000000000000000022731464752671100277740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtGlass : public PtMaterial { PtGlass() = default; ~PtGlass() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeGlassMaterial( float eta, vec3f color, float attenuationDistance) { cpp::Material mat("glass"); mat.setParam("eta", eta); mat.setParam("attenuationColor", color); mat.setParam("attenuationDistance", attenuationDistance); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtGlass::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); for (auto i : numSpheres) { auto i_f = static_cast(i); materials.push_back(makeGlassMaterial(lerp(i_f.x / (dimSize - 1), 1.f, 2.f), vec3f(.1f, .5f, 1.f), lerp(1.f - i_f.y / (dimSize - 1), 0.5f, 5.f))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtGlass, test_pt_glass); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_luminous.cpp000066400000000000000000000021051464752671100305300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct PtLuminous : public PtMaterial { PtLuminous() = default; ~PtLuminous() override = default; std::vector buildMaterials() const override; }; // Inlined definitions //////////////////////////////////////////////////// std::vector PtLuminous::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); for (auto i : numSpheres) { auto i_f = static_cast(i); materials.push_back(cpp::Material("luminous")); materials.back().setParam("color", vec3f(0.7f, 0.7f, 1.f)); materials.back().setParam("intensity", i_f.x / (dimSize - 1)); materials.back().setParam("transparency", 1.f - i_f.y / (dimSize - 1)); materials.back().commit(); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtLuminous, test_pt_luminous); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_material.h000066400000000000000000000054711464752671100301310ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct PtMaterial : public detail::Builder { PtMaterial() = default; ~PtMaterial() override = default; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; virtual std::vector buildMaterials() const = 0; }; // Inlined definitions //////////////////////////////////////////////////// inline cpp::Group PtMaterial::buildGroup() const { cpp::Geometry sphereGeometry("sphere"); std::vector materials = buildMaterials(); const int dimCount = sqrtf(materials.size()); const int dimSize = dimCount - 1; index_sequence_2D numSpheres(dimCount); std::vector spheres; std::vector index; for (auto i : numSpheres) { auto i_f = static_cast(i); spheres.emplace_back(dimSize / 2.f - i_f.x, dimSize / 2.f - i_f.y, .6f); index.push_back(numSpheres.flatten(i)); } sphereGeometry.setParam("sphere.position", cpp::CopiedData(spheres)); sphereGeometry.setParam("radius", 0.4f); sphereGeometry.commit(); cpp::GeometricModel model(sphereGeometry); model.setParam("material", cpp::CopiedData(materials)); model.setParam("index", cpp::CopiedData(index)); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); return group; } inline cpp::World PtMaterial::buildWorld() const { cpp::World world; cpp::Group group = buildGroup(); cpp::Instance groupInstance(group); groupInstance.commit(); box3f bbox = group.getBounds(); bbox.lower -= .4f; bbox.upper += .4f; cpp::Instance planeInstance = makeGroundPlane( bbox, vec4f(.9f, .9f, .9f, 1.f), vec4f(.2f, .2f, .2f, 1.f)); planeInstance.setParam( "xfm", affine3f::rotate(vec3f(-1.f, 0.f, 0.f), half_pi)); planeInstance.commit(); std::vector instances; instances.push_back(groupInstance); instances.push_back(planeInstance); world.setParam("instance", cpp::CopiedData(instances)); // Lights { std::vector lightHandles; cpp::Light sphereLight("sphere"); sphereLight.setParam("intensity", 500.f); sphereLight.setParam("position", vec3f(-15.f, 15.f, -20.f)); sphereLight.setParam("radius", 5.f); sphereLight.commit(); cpp::Light ambientLight("ambient"); ambientLight.setParam("intensity", 0.4f); ambientLight.setParam("color", vec3f(1.f)); ambientLight.commit(); lightHandles.push_back(sphereLight); lightHandles.push_back(ambientLight); world.setParam("light", cpp::CopiedData(lightHandles)); } return world; } } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_material_tex.cpp000066400000000000000000000106261464752671100313420ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_tex.h" namespace ospray { namespace testing { struct PtMaterialTex : public PtTex { PtMaterialTex() = default; ~PtMaterialTex() override = default; std::vector buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const override; }; // Inlined definitions //////////////////////////////////////////////////// std::vector PtMaterialTex::buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const { std::vector materials; // carPaint { // roughness materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); setTexture(materials.back(), "roughness", texR); // flakeColor materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); materials.back().setParam("flakeScale", 2000.f); materials.back().setParam("flakeDensity", 1.f); setTexture(materials.back(), "flakeColor", texRGBA); // flakeDensity materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); materials.back().setParam("flakeColor", vec3f(0.277f, 0.717f, 0.990f)); materials.back().setParam("flakeScale", 2000.f); setTexture(materials.back(), "flakeDensity", texR); // flakeRoughness materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); materials.back().setParam("flakeDensity", 1.f); materials.back().setParam("flakeColor", vec3f(0.277f, 0.717f, 0.990f)); materials.back().setParam("flakeScale", 2000.f); setTexture(materials.back(), "flakeRoughness", texR); // flipflopFalloff materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); materials.back().setParam("flakeDensity", 1.f); materials.back().setParam("flakeColor", vec3f(0.277f, 0.717f, 0.990f)); materials.back().setParam("flakeScale", 1000.f); materials.back().setParam("flipflopColor", vec3f(0.252f, 0.0385f, 0.550f)); setTexture(materials.back(), "flipflopFalloff", texR); // coat materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); setTexture(materials.back(), "coat", texR); // coatColor materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); setTexture(materials.back(), "coatColor", texRGBA); // coatRoughness materials.push_back(cpp::Material("carPaint")); materials.back().setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); setTexture(materials.back(), "coatRoughness", texR); } // obj { // d materials.push_back(cpp::Material("obj")); setTexture(materials.back(), "d", texR); // Kd materials.push_back(cpp::Material("obj")); setTexture(materials.back(), "kd", texRGBA); // Ks materials.push_back(cpp::Material("obj")); setTexture(materials.back(), "ks", texRGBA); // Ns materials.push_back(cpp::Material("obj")); materials.back().setParam("ks", vec3f(1.f)); setTexture(materials.back(), "ns", texR); } // other { // metal roughness materials.push_back(cpp::Material("metal")); materials.back().setParam("eta", vec3f(0.051, 0.043, 0.041)); materials.back().setParam("k", vec3f(5.3f, 3.6f, 2.3f)); setTexture(materials.back(), "roughness", texR); // luminous emissive materials.push_back(cpp::Material("luminous")); setTexture(materials.back(), "color", texRGBA, vec3f(1.f, 0.8f, 0.7f)); // alloy roughness materials.push_back(cpp::Material("alloy")); materials.back().setParam("color", vec3f(.72f, .45f, .2f)); materials.back().setParam("edgeColor", vec3f(1.f, 1.f, 1.f)); setTexture(materials.back(), "roughness", texR); // thinglass attenuationColor materials.push_back(cpp::Material("thinGlass")); setTexture(materials.back(), "attenuationColor", texRGBA); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtMaterialTex, test_pt_material_tex); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_metal_roughness.cpp000066400000000000000000000036171464752671100320650ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtMetalRoughness : public PtMaterial { PtMetalRoughness() = default; ~PtMetalRoughness() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeMetalMaterial(vec3f eta, vec3f k, float roughness) { cpp::Material mat("metal"); mat.setParam("eta", eta); mat.setParam("k", k); mat.setParam("roughness", roughness); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtMetalRoughness::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // Silver for (int i = 0; i < dimSize; ++i) { materials.push_back(makeMetalMaterial(vec3f(0.051f, 0.043f, 0.041f), vec3f(5.3f, 3.6f, 2.3f), float(i) / (dimSize - 1))); } // Aluminium for (int i = 0; i < dimSize; ++i) { materials.push_back(makeMetalMaterial(vec3f(1.5f, 0.98f, 0.6f), vec3f(7.6f, 6.6f, 5.4f), float(i) / (dimSize - 1))); } // Gold for (int i = 0; i < dimSize; ++i) { materials.push_back(makeMetalMaterial(vec3f(0.07f, 0.37f, 1.5f), vec3f(3.7f, 2.3f, 1.7f), float(i) / (dimSize - 1))); } // Chromium for (int i = 0; i < dimSize; ++i) { materials.push_back(makeMetalMaterial(vec3f(3.2f, 3.1f, 2.3f), vec3f(3.3f, 3.3f, 3.1f), float(i) / (dimSize - 1))); } // Copper for (int i = 0; i < dimSize; ++i) { materials.push_back(makeMetalMaterial(vec3f(0.1f, 0.8f, 1.1f), vec3f(3.5f, 2.5f, 2.4f), float(i) / (dimSize - 1))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtMetalRoughness, test_pt_metal_roughness); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_metallic_flakes.cpp000066400000000000000000000023571464752671100320050ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtMetallicFlakes : public PtMaterial { PtMetallicFlakes() = default; ~PtMetallicFlakes() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeMetallicFlakesMaterial( float flakeAmount, float flakeSpread) { cpp::Material mat("metallicPaint"); mat.setParam("baseColor", vec3f(1.f, 0.f, 0.f)); mat.setParam("flakeAmount", flakeAmount); mat.setParam("flakeSpread", flakeSpread); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtMetallicFlakes::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); for (auto i : numSpheres) { auto i_f = static_cast(i); materials.push_back( makeMetallicFlakesMaterial(lerp(i_f.x / (dimSize - 1), 1.f, 0.f), lerp(i_f.y / (dimSize - 1), 0.f, 1.f))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtMetallicFlakes, test_pt_metallic_flakes); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_mix_tex.cpp000066400000000000000000000060301464752671100303330ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_tex.h" namespace ospray { namespace testing { struct PtMixTex : public PtTex { PtMixTex() = default; ~PtMixTex() override = default; std::vector buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const override; }; // Inlined definitions //////////////////////////////////////////////////// std::vector PtMixTex::buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const { std::vector materials; // obj & thinGlass { cpp::Material obj("obj"); obj.commit(); cpp::Material thinGlass("thinGlass"); thinGlass.commit(); cpp::Material mix("mix"); mix.setParam("material1", obj); mix.setParam("material2", thinGlass); materials.push_back(mix); setTexture(materials.back(), "factor", texR); } // plastic & metal { cpp::Material plastic("plastic"); plastic.setParam("pigmentColor", vec3f(.8f, 0.f, 0.f)); plastic.commit(); cpp::Material metal("metal"); metal.commit(); cpp::Material mix("mix"); mix.setParam("material1", plastic); mix.setParam("material2", metal); materials.push_back(mix); setTexture(materials.back(), "factor", texR); } // velvet & metallicPaint { cpp::Material velvet("velvet"); cpp::Material metallicPaint("metallicPaint"); cpp::Material mix("mix"); velvet.commit(); metallicPaint.commit(); mix.setParam("material1", velvet); mix.setParam("material2", metallicPaint); materials.push_back(mix); setTexture(materials.back(), "factor", texR); } // carPaint & principled { cpp::Material carPaint("carPaint"); carPaint.setParam("baseColor", vec3f(.5f)); carPaint.setParam("flakeColor", vec3f(.8f)); carPaint.setParam("flakeDensity", 1.f); carPaint.setParam("flakeScale", 1000.f); carPaint.commit(); cpp::Material principled("principled"); principled.setParam("baseColor", vec3f(0.0177f, 0.189f, 0.590f)); principled.commit(); cpp::Material mix("mix"); mix.setParam("material1", carPaint); mix.setParam("material2", principled); materials.push_back(mix); setTexture(materials.back(), "factor", texR); } // emission: principled & luminous { cpp::Material principled("principled"); setTexture(principled, "emissiveColor", texRGBA, vec3f(4.6f, 0.1f, 0.1f)); principled.setParam("map_emissiveColor.scale", vec2f(0.7f, 0.3f)); principled.commit(); cpp::Material luminous("luminous"); luminous.setParam("color", vec3f(0.1f, 0.6f, 0.1f)); luminous.setParam("intensity", 5.0f); luminous.commit(); cpp::Material mix("mix"); mix.setParam("material1", principled); mix.setParam("material2", luminous); materials.push_back(mix); setTexture(materials.back(), "factor", texR); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtMixTex, test_pt_mix_tex); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_obj.cpp000066400000000000000000000037151464752671100274370ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtObj : public PtMaterial { PtObj() = default; ~PtObj() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeObjMaterial( float d, vec3f Kd, vec3f Ks, float Ns, vec3f Tf) { cpp::Material mat("obj"); mat.setParam("d", d); mat.setParam("kd", Kd); mat.setParam("ks", Ks); mat.setParam("ns", Ns); mat.setParam("tf", Tf); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtObj::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // d for (int i = 0; i < dimSize; i++) materials.push_back(makeObjMaterial(1.f - float(i) / (dimSize - 1), vec3f(.8f, 0.f, 0.f), vec3f(0.f), 10.f, vec3f(0.f))); // Kd for (int i = 0; i < dimSize; i++) materials.push_back(makeObjMaterial(1.f, vec3f(1.f - float(i) / (dimSize - 1), 0.f, 0.f), vec3f(0.f), 10.f, vec3f(0.f))); // Ks for (int i = 0; i < dimSize; i++) materials.push_back(makeObjMaterial(1.f, vec3f(.8f, 0.f, 0.f), vec3f(float(i) / (dimSize - 1)), 1000.f, vec3f(0.f))); // Ns for (int i = 0; i < dimSize; i++) materials.push_back(makeObjMaterial(1.f, vec3f(.8f, 0.f, 0.f), vec3f(1.f), lerp(float(i) / (dimSize - 1), 10.f, 1000.f), vec3f(0.f))); // Tf for (int i = 0; i < dimSize; i++) materials.push_back(makeObjMaterial(1.f, vec3f(.2f, 0.f, 0.f), vec3f(.2f, 0.f, 0.f), 1000.f, (float(i) / (dimSize - 1)) * vec3f(1.f, .5f, .5f))); return materials; } OSP_REGISTER_TESTING_BUILDER(PtObj, test_pt_obj); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_plastic.cpp000066400000000000000000000022241464752671100303160ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtPlastic : public PtMaterial { PtPlastic() = default; ~PtPlastic() override = default; std::vector buildMaterials() const override; }; static cpp::Material makePlasticMaterial( vec3f color, float eta, float roughness) { cpp::Material mat("plastic"); mat.setParam("pigmentColor", color); mat.setParam("eta", eta); mat.setParam("roughness", roughness); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtPlastic::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); for (auto i : numSpheres) { auto i_f = static_cast(i); materials.push_back(makePlasticMaterial(vec3f(.8f, 0.f, 0.f), lerp(i_f.y / (dimSize - 1), 1.f, 2.f), i_f.x / (dimSize - 1))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtPlastic, test_pt_plastic); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_principled.cpp000066400000000000000000000165441464752671100310220ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtPrincipledMetal : public PtMaterial { PtPrincipledMetal() = default; ~PtPrincipledMetal() override = default; std::vector buildMaterials() const override; }; struct PtPrincipledPlastic : public PtMaterial { PtPrincipledPlastic() = default; ~PtPrincipledPlastic() override = default; std::vector buildMaterials() const override; }; struct PtPrincipledGlass : public PtMaterial { PtPrincipledGlass() = default; ~PtPrincipledGlass() override = default; std::vector buildMaterials() const override; }; static cpp::Material makePrincipledMetalMaterial(vec3f baseColor, float metallic, float roughness, float anisotropy, float coat, float coatRoughness) { cpp::Material mat("principled"); mat.setParam("baseColor", baseColor); mat.setParam("metallic", metallic); mat.setParam("roughness", roughness); mat.setParam("anisotropy", anisotropy); mat.setParam("coat", coat); mat.setParam("coatRoughness", coatRoughness); mat.commit(); return mat; } static cpp::Material makePrincipledPlasticMaterial(vec3f baseColor, float ior, float specular, float sheen, float sheenTint, float sheenRoughness, float opacity) { cpp::Material mat("principled"); mat.setParam("baseColor", baseColor); mat.setParam("ior", ior); mat.setParam("specular", specular); mat.setParam("sheen", sheen); mat.setParam("sheenTint", sheenTint); mat.setParam("sheenRoughness", sheenRoughness); mat.setParam("opacity", opacity); mat.commit(); return mat; } static cpp::Material makePrincipledGlassMaterial(vec3f baseColor, float transmission, float roughness, float ior, float transmissionDepth, bool thin, float thickness, float backlight) { cpp::Material mat("principled"); mat.setParam("baseColor", baseColor); mat.setParam("transmissionColor", baseColor); mat.setParam("transmission", transmission); mat.setParam("roughness", roughness); mat.setParam("ior", ior); mat.setParam("transmissionDepth", transmissionDepth); mat.setParam("thin", thin); mat.setParam("thickness", thickness); mat.setParam("backlight", backlight); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtPrincipledMetal::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // metallic for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledMetalMaterial(vec3f(0.0261f, 0.195f, 0.870f), float(i) / (dimSize - 1), 0.f, 0.f, 0.f, 0.f)); } // roughness for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledMetalMaterial(vec3f(0.0261f, 0.195f, 0.870f), 1.f, float(i) / (dimSize - 1), 0.f, 0.f, 0.f)); } // anisotropy for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledMetalMaterial(vec3f(0.0261f, 0.195f, 0.870f), 1.f, .5f, float(i) / (dimSize - 1), 0.f, 0.f)); } // coat for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledMetalMaterial(vec3f(0.860f, 0.0258f, 0.0536f), 1.f, .5f, 0.f, float(i) / (dimSize - 1), 0.f)); } // coatRoughness for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledMetalMaterial(vec3f(0.860f, 0.0258f, 0.0536f), 1.f, .5f, 0.f, 1.f, float(i) / (dimSize - 1))); } return materials; } std::vector PtPrincipledPlastic::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // specular for (int i = 0; i < dimSize; i++) { materials.push_back(makePrincipledPlasticMaterial(vec3f(0.770, 0.00, 0.00), 1.45f, float(i) / (dimSize - 1), 0.f, 0.f, 0.f, 1.f)); } // sheen for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledPlasticMaterial(vec3f(0.950f, 0.494f, 0.0380f), 1.f, 0.f, float(i) / (dimSize - 1), 0.f, .5f, 1.f)); } // sheenTint for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledPlasticMaterial(vec3f(0.950f, 0.494f, 0.0380f), 1.f, 0.f, 1.f, float(i) / (dimSize - 1), .5f, 1.f)); } // sheenRoughness for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledPlasticMaterial(vec3f(0.950f, 0.494f, 0.0380f), 1.f, 0.f, 1.f, 0.f, float(i) / (dimSize - 1), 1.f)); } // opacity for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledPlasticMaterial(vec3f(0.930f, 0.884f, 0.0186f), 1.45f, 1.f, 0.f, 0.f, 0.f, 1.f - float(i) / (dimSize - 1))); } return materials; } std::vector PtPrincipledGlass::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); // transmission for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledGlassMaterial(vec3f(0.0400f, 0.680f, 1.00f), float(i) / (dimSize - 1), 0.f, 1.1f, 1.f, false, 1.f, 0.f)); } // roughness for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledGlassMaterial(vec3f(0.0400f, 0.680f, 1.00f), 1.f, float(i) / (dimSize - 1), 1.5f, 1.f, false, 1.f, 0.f)); } // ior for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledGlassMaterial(vec3f(0.0400f, 0.680f, 1.00f), 1.f, 0.f, lerp(float(i) / (dimSize - 1), 1.f, 2.f), 1.f, false, 1.f, 0.f)); } // transmissionDepth for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledGlassMaterial(vec3f(0.0400f, 0.680f, 1.00f), 1.f, 0.f, 1.5f, lerp(float(i) / (dimSize - 1), 2.f, 0.f), false, 1.f, 0.f)); } // backlight for (int i = 0; i < dimSize; i++) { materials.push_back( makePrincipledGlassMaterial(vec3f(0.0400f, 0.200f, 1.00f), .3f, 0.f, 1.5f, 1.f, true, 1.f, lerp(float(i) / (dimSize - 1), 0.f, 2.f))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtPrincipledMetal, test_pt_principled_metal); OSP_REGISTER_TESTING_BUILDER(PtPrincipledPlastic, test_pt_principled_plastic); OSP_REGISTER_TESTING_BUILDER(PtPrincipledGlass, test_pt_principled_glass); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_principled_tex.cpp000066400000000000000000000141771464752671100317020ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_tex.h" namespace ospray { namespace testing { struct PtPrincipledTex : public PtTex { PtPrincipledTex() = default; ~PtPrincipledTex() override = default; std::vector buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const override; }; // Inlined definitions //////////////////////////////////////////////////// std::vector PtPrincipledTex::buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const { std::vector materials; // principled metal { // metallic materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0261f, 0.195f, 0.870f)); setTexture(materials.back(), "metallic", texR); // roughness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0261f, 0.195f, 0.870f)); materials.back().setParam("metallic", 1.f); setTexture(materials.back(), "roughness", texR); // anisotropy materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0261f, 0.195f, 0.870f)); materials.back().setParam("metallic", 1.f); materials.back().setParam("roughness", .5f); setTexture(materials.back(), "anisotropy", texR); // coat materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.860f, 0.0258f, 0.0536f)); materials.back().setParam("metallic", 1.f); materials.back().setParam("roughness", .5f); setTexture(materials.back(), "coat", texR); // coatRoughness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.860f, 0.0258f, 0.0536f)); materials.back().setParam("metallic", 1.f); materials.back().setParam("roughness", .5f); materials.back().setParam("coat", 1.f); setTexture(materials.back(), "coatRoughness", texR); } // principled plastic { // roughness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.770f, 0.00f, 0.00f)); setTexture(materials.back(), "roughness", texR); // specular materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.770f, 0.00f, 0.00f)); materials.back().setParam("ior", 1.45f); setTexture(materials.back(), "specular", texR); // sheen materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.950f, 0.494f, 0.0380f)); materials.back().setParam("sheenRoughness", .5f); setTexture(materials.back(), "sheen", texR); // sheenTint materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.950f, 0.494f, 0.0380f)); materials.back().setParam("sheen", 1.f); materials.back().setParam("sheenRoughness", .5f); setTexture(materials.back(), "sheenTint", texR); // sheenRoughness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.950f, 0.494f, 0.0380f)); materials.back().setParam("sheen", 1.f); setTexture(materials.back(), "sheenRoughness", texR); } // principled glass { // transmission materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam( "transmissionColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam("ior", 1.1f); setTexture(materials.back(), "transmission", texR); // roughness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam( "transmissionColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam("transmission", 1.f); materials.back().setParam("ior", 1.5f); setTexture(materials.back(), "roughness", texR); // thickness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam( "transmissionColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam("transmission", 1.f); materials.back().setParam("ior", 1.5f); materials.back().setParam("thin", true); setTexture(materials.back(), "thickness", texR); // thin roughness materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam( "transmissionColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam("transmission", 1.f); materials.back().setParam("ior", 1.5f); materials.back().setParam("thin", true); setTexture(materials.back(), "roughness", texR); // thin backlight materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam( "transmissionColor", vec3f(0.0400f, 0.680f, 1.00f)); materials.back().setParam("transmission", .3f); materials.back().setParam("ior", 1.5f); materials.back().setParam("thin", true); setTexture(materials.back(), "backlight", texR, 2.f); } { // emissive materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(1.f, 0.8f, 0.7f)); setTexture(materials.back(), "emissiveColor", texRGBA); // transparency materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.860f, 0.0258f, 0.0536f)); setTexture(materials.back(), "baseColor", texRGBA); // opacity materials.push_back(cpp::Material("principled")); materials.back().setParam("baseColor", vec3f(0.860f, 0.0258f, 0.0536f)); setTexture(materials.back(), "opacity", texR); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtPrincipledTex, test_pt_principled_tex); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_tex.h000066400000000000000000000202611464752671100271250ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Builder.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" using namespace rkcommon::math; namespace ospray { namespace testing { struct PtTex : public detail::Builder { PtTex() = default; ~PtTex() override = default; cpp::Group buildGroup() const override; cpp::World buildWorld() const override; virtual std::vector buildMaterials( const cpp::Texture &texR, const cpp::Texture &texRGBA) const = 0; }; // Inlined definitions //////////////////////////////////////////////////// static cpp::Texture makeCheckerboardTextureR8() { // Prepare pixel data constexpr uint32_t width = 16; constexpr uint32_t height = 16; std::array dbyte; index_sequence_2D idx(vec2i(width, height)); for (auto i : idx) dbyte[idx.flatten(i)] = ((i.x & 2) ^ (i.y & 2)) * 255; // Create texture object cpp::Texture tex("texture2d"); tex.setParam("format", OSP_TEXTURE_R8); tex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); tex.setParam("data", cpp::CopiedData(dbyte.data(), vec2ul(width, height))); tex.commit(); // Ready return tex; } static cpp::Texture makeCheckerboardTextureRGBA8() { // Prepare pixel data constexpr uint32_t width = 16; constexpr uint32_t height = 16; std::array dbyte; index_sequence_2D idx(vec2i(width, height)); for (auto i : idx) { uint8_t v = ((i.x & 2) ^ (i.y & 2)) * 255; dbyte[idx.flatten(i)] = vec4uc(v, v, v, 128 + v / 2); } // Create texture object cpp::Texture tex("texture2d"); tex.setParam("format", OSP_TEXTURE_RGBA8); tex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); tex.setParam("data", cpp::CopiedData(dbyte.data(), vec2ul(width, height))); tex.commit(); // Ready return tex; } static std::vector makeSphereVertices( uint32_t latitudeCount, uint32_t longitudeCount, float radius) { // Calculate latitude and longitude angular steps (in radians) std::vector vPos; const float latAngleStep = float(pi) / float(latitudeCount); const float longAngleStep = (2.0f * float(pi)) / float(longitudeCount); // Iterate through latitude segments for (uint32_t latitudeId = 0; latitudeId <= latitudeCount; latitudeId++) { // Calculate longitude radius at current latitude float longRadius = radius * sin(latAngleStep * latitudeId); // Determine segment level float y = radius * cos(latAngleStep * latitudeId); // Iterate through longitude segments for (uint32_t longitudeId = 0; longitudeId <= longitudeCount; longitudeId++) { // Calculate vertex position float x = longRadius * cos(longAngleStep * longitudeId); float z = longRadius * sin(longAngleStep * longitudeId); vPos.push_back(vec3f(x, y, z)); } } // Ready return vPos; } static std::vector makeSphereTexCoords(uint32_t latitudeCount, uint32_t longitudeCount, float tileLat, float tileLong) { // Iterate through latitude segments std::vector vTexCoord; for (uint32_t latitudeId = 0; latitudeId <= latitudeCount; latitudeId++) { // Iterate through longitude segments for (uint32_t longitudeId = 0; longitudeId <= longitudeCount; longitudeId++) { // Calculate texture coordinates vTexCoord.push_back(vec2f(tileLong * longitudeId / float(longitudeCount), tileLat * (latitudeId - 1) / float(latitudeCount))); } } // Ready return vTexCoord; } static std::vector makeSphereIndices( uint32_t latitudeCount, uint32_t longitudeCount, bool outside) { // Iterate through latitude segments std::vector indices; for (uint32_t latitudeId = 0; latitudeId < latitudeCount; latitudeId++) { // Calculate indices of segment left-most vertices uint32_t firstVertex1 = latitudeId * (longitudeCount + 1); uint32_t firstVertex2 = (latitudeId + 1) * (longitudeCount + 1); // Iterate through longitude segments for (uint32_t longitudeId = 0; longitudeId < longitudeCount; longitudeId++) { // Setup first triangle indices uint32_t i2 = firstVertex2 + longitudeId + 1; uint32_t i3 = firstVertex2 + longitudeId; indices.push_back(vec3ui(firstVertex1 + longitudeId, (outside) ? i2 : i3, (outside) ? i3 : i2)); // Setup second triangle indices i2 = firstVertex1 + longitudeId + 1; i3 = firstVertex2 + longitudeId + 1; indices.push_back(vec3ui(firstVertex1 + longitudeId, (outside) ? i2 : i3, (outside) ? i3 : i2)); } } // Ready return indices; } static cpp::Geometry makeSphereMesh( uint32_t latitudeCount, uint32_t longitudeCount) { cpp::Geometry sphereMesh("mesh"); // Prepare mesh buffers std::vector vertices = makeSphereVertices(latitudeCount, longitudeCount, 1.f); std::vector texCoords = makeSphereTexCoords(latitudeCount, longitudeCount, 1.f, 2.f); std::vector indices = makeSphereIndices(latitudeCount, longitudeCount, false); // Set mesh parameters sphereMesh.setParam("vertex.position", cpp::CopiedData(vertices)); sphereMesh.setParam("vertex.normal", cpp::CopiedData(vertices)); sphereMesh.setParam("vertex.texcoord", cpp::CopiedData(texCoords)); sphereMesh.setParam("index", cpp::CopiedData(indices)); sphereMesh.commit(); // Ready return sphereMesh; } template void setTexture(cpp::Material &mat, const std::string &name, const cpp::Texture &tex, const T mul = T(1.f)) { mat.setParam(name, mul); mat.setParam("map_" + name, tex); mat.commit(); } inline cpp::Group PtTex::buildGroup() const { // Do nothing, needs per-instance materials feature to have single group return cpp::Group(); } inline cpp::World PtTex::buildWorld() const { cpp::World world; std::vector instances; cpp::Texture texR = makeCheckerboardTextureR8(); cpp::Texture texRGBA = makeCheckerboardTextureRGBA8(); std::vector materials = buildMaterials(texR, texRGBA); size_t dimCount = sqrtf(materials.size()); if (dimCount * dimCount < materials.size()) dimCount++; const size_t dimSize = dimCount - 1; cpp::Geometry sphereGeometry = makeSphereMesh(25, 50); // Note: this is a temporary implementation, per-instance materials feature // should be used here box3f bbox(empty); index_sequence_2D numSpheres(dimCount); for (auto i : numSpheres) { const auto idx = numSpheres.flatten(i); if (idx >= materials.size()) break; // Construct GeometricModel for each instance cpp::GeometricModel model(sphereGeometry); model.setParam("material", cpp::CopiedData(materials[idx])); model.commit(); // Construct Group for each instance cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); // Construct instance cpp::Instance instance(group); auto i_f = static_cast(i); instance.setParam("xfm", affine3f::translate( vec3f(dimSize / 2.f - i_f.x, dimSize / 2.f - i_f.y, .6f)) * affine3f::scale(.4f)); instance.commit(); instances.push_back(instance); bbox.extend(instance.getBounds()); } bbox.lower -= .4f; bbox.upper += .4f; cpp::Instance planeInstance = makeGroundPlane( bbox, vec4f(.9f, .9f, .9f, 1.f), vec4f(.2f, .2f, .2f, 1.f)); planeInstance.setParam( "xfm", affine3f::rotate(vec3f(-1.f, 0.f, 0.f), half_pi)); planeInstance.commit(); instances.push_back(planeInstance); world.setParam("instance", cpp::CopiedData(instances)); // Lights { std::vector lightHandles; cpp::Light sphereLight("sphere"); sphereLight.setParam("intensity", 500.f); sphereLight.setParam("position", vec3f(-15.f, 15.f, -20.f)); sphereLight.setParam("radius", 5.f); sphereLight.commit(); cpp::Light ambientLight("ambient"); ambientLight.setParam("intensity", 0.4f); ambientLight.setParam("color", vec3f(1.f)); ambientLight.commit(); lightHandles.push_back(sphereLight); lightHandles.push_back(ambientLight); world.setParam("light", cpp::CopiedData(lightHandles)); } return world; } } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_thinglass.cpp000066400000000000000000000023601464752671100306540ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtThinGlass : public PtMaterial { PtThinGlass() = default; ~PtThinGlass() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeThinGlassMaterial( float eta, vec3f color, float attenuationDistance) { cpp::Material mat("thinGlass"); mat.setParam("eta", eta); mat.setParam("attenuationColor", color); mat.setParam("attenuationDistance", attenuationDistance); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtThinGlass::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); for (auto i : numSpheres) { auto i_f = static_cast(i); materials.push_back( makeThinGlassMaterial(lerp(i_f.x / (dimSize - 1), 1.f, 2.f), vec3f(.1f, .5f, 1.f), lerp(1.f - i_f.y / (dimSize - 1), 0.5f, 5.f))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtThinGlass, test_pt_thinglass); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/builders/test_pt_velvet.cpp000066400000000000000000000022111464752671100301600ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_pt_material.h" namespace ospray { namespace testing { struct PtVelvet : public PtMaterial { PtVelvet() = default; ~PtVelvet() override = default; std::vector buildMaterials() const override; }; static cpp::Material makeVelvetMaterial( float backScattering, float horizonScatteringFallOff) { cpp::Material mat("velvet"); mat.setParam("backScattering", backScattering); mat.setParam("horizonScatteringFallOff", horizonScatteringFallOff); mat.commit(); return mat; } // Inlined definitions //////////////////////////////////////////////////// std::vector PtVelvet::buildMaterials() const { std::vector materials; constexpr int dimSize = 5; index_sequence_2D numSpheres(dimSize); for (auto i : numSpheres) { auto i_f = static_cast(i); materials.push_back(makeVelvetMaterial( i_f.x / (dimSize - 1), lerp(i_f.y / (dimSize - 1), 0.f, 20.f))); } return materials; } OSP_REGISTER_TESTING_BUILDER(PtVelvet, test_pt_velvet); } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/detail/000077500000000000000000000000001464752671100240425ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/ospray_testing/detail/ospray_testing.inl000066400000000000000000000005631464752671100276240ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../builders/Builder.h" namespace ospray { namespace testing { template inline void setParam( SceneBuilderHandle _b, const std::string &type, const T &val) { auto *b = (detail::Builder *)_b; b->setParam(type, val); } } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/ospray_testing.cpp000066400000000000000000000016351464752671100263630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray_testing #include "ospray_testing.h" // stl #include using namespace rkcommon; using namespace rkcommon::math; namespace ospray { namespace testing { SceneBuilderHandle newBuilder(const std::string &type) { auto *b = detail::Builder::createBuilder(type); if (b == nullptr) throw std::runtime_error("Unable to find '" + type + "' builder"); return (SceneBuilderHandle)b; } cpp::Group buildGroup(SceneBuilderHandle _b) { auto *b = (detail::Builder *)_b; return b->buildGroup(); } cpp::World buildWorld(SceneBuilderHandle _b) { auto *b = (detail::Builder *)_b; return b->buildWorld(); } void commit(SceneBuilderHandle _b) { auto *b = (detail::Builder *)_b; b->commit(); } void release(SceneBuilderHandle _b) { auto *b = (detail::Builder *)_b; b->refDec(); } } // namespace testing } // namespace ospray RenderKit-ospray-85af292/apps/common/ospray_testing/ospray_testing.h000066400000000000000000000015231464752671100260240ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ospray_testing_export.h" namespace ospray { namespace testing { using namespace rkcommon; using namespace rkcommon::math; using SceneBuilderHandle = void *; OSPRAY_TESTING_EXPORT SceneBuilderHandle newBuilder(const std::string &type); template void setParam(SceneBuilderHandle b, const std::string &type, const T &val); OSPRAY_TESTING_EXPORT cpp::Group buildGroup(SceneBuilderHandle b); OSPRAY_TESTING_EXPORT cpp::World buildWorld(SceneBuilderHandle b); OSPRAY_TESTING_EXPORT void commit(SceneBuilderHandle b); OSPRAY_TESTING_EXPORT void release(SceneBuilderHandle b); } // namespace testing } // namespace ospray #include "detail/ospray_testing.inl" RenderKit-ospray-85af292/apps/common/raw_to_amr/000077500000000000000000000000001464752671100216605ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/common/raw_to_amr/CMakeLists.txt000066400000000000000000000003771464752671100244270ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 add_library(raw_to_amr STATIC rawToAMR.cpp) target_link_libraries(raw_to_amr PUBLIC rkcommon::rkcommon) target_include_directories(raw_to_amr INTERFACE ${CMAKE_CURRENT_LIST_DIR}) RenderKit-ospray-85af292/apps/common/raw_to_amr/rawToAMR.cpp000066400000000000000000000144271464752671100240300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundefined-func-template" #include "rawToAMR.h" #include #include #include namespace ospray { namespace amr { void makeAMR(const std::vector &in, const vec3i inGridDims, const int numLevels, const int blockSize, const int refinementLevel, const float threshold, std::vector &blockBounds, std::vector &refinementLevels, std::vector &cellWidths, std::vector> &brickData) { int minWidth = blockSize; for (int i = 1; i < numLevels; i++) minWidth *= refinementLevel; if (minWidth >= refinementLevel * reduce_max(inGridDims)) { throw std::runtime_error( "too many levels, or too fine a refinement factor." "do not have a single brick at the root..."); } vec3i finestLevelSize = vec3i(minWidth); while (finestLevelSize.x < inGridDims.x) finestLevelSize.x += minWidth; while (finestLevelSize.y < inGridDims.y) finestLevelSize.y += minWidth; while (finestLevelSize.z < inGridDims.z) finestLevelSize.z += minWidth; // create container for current level so we don't use in std::vector ¤tLevel = const_cast &>(in); size_t numWritten = 0; size_t numRemoved = 0; std::mutex fileMutex; // create and write the bricks vec3i levelSize = finestLevelSize; for (int level = numLevels - 1; level >= 0; --level) { const vec3i nextLevelSize = levelSize / refinementLevel; // create container for next level down std::vector nextLevel = std::vector(nextLevelSize.product(), 0); const vec3i numBricks = levelSize / blockSize; rkcommon::tasking::parallel_for(numBricks.product(), [&](int brickIdx) { // dt == cellWidth in osp_amr_brick_info float dt = 1.f / powf(refinementLevel, level); // get 3D brick index from flat brickIdx const vec3i brickID(brickIdx % numBricks.x, (brickIdx / numBricks.x) % numBricks.y, brickIdx / (numBricks.x * numBricks.y)); // set upper and lower bounds of brick based on 3D index and // brick size in input data space box3i box; box.lower = brickID * blockSize; box.upper = box.lower + (blockSize - 1); // current brick data std::vector data(blockSize * blockSize * blockSize); size_t out = 0; range1f brickRange; // traverse the data by brick index for (int iz = box.lower.z; iz <= box.upper.z; iz++) { for (int iy = box.lower.y; iy <= box.upper.y; iy++) { for (int ix = box.lower.x; ix <= box.upper.x; ix++) { const size_t thisLevelCoord = ix + levelSize.y * (iy + iz * levelSize.z); const size_t nextLevelCoord = ix / refinementLevel + nextLevelSize.y * (iy / refinementLevel + iz / refinementLevel * nextLevelSize.z); // get the actual data at current coordinates const float v = currentLevel[thisLevelCoord]; // insert the data into the current brick data[out++] = v; nextLevel[nextLevelCoord] += v / (refinementLevel * refinementLevel * refinementLevel); // extend the value range of this brick (min/max) as needed brickRange.extend(v); } } } std::lock_guard lock(fileMutex); if ((level > 0) && ((brickRange.upper - brickRange.lower) <= threshold)) { numRemoved++; } else { blockBounds.push_back(box); refinementLevels.push_back(level); cellWidths.resize(std::max(cellWidths.size(), (size_t)level + 1)); cellWidths[level] = dt; brickData.push_back(data); numWritten++; } }); // end parallel for currentLevel = nextLevel; levelSize = nextLevelSize; numWritten = 0; numRemoved = 0; } // end for loop on levels } void outputAMR(const FileName outFileBase, const std::vector &blockBounds, const std::vector &refinementLevels, const std::vector &cellWidths, const std::vector> &brickData, const int blockSize) { // ALOK: .info is brick metadata FILE *infoOut = fopen(outFileBase.addExt(".info").c_str(), "wb"); if (!infoOut) { throw std::runtime_error("could not open info output file!"); } // ALOK: .data is actual data FILE *dataOut = fopen(outFileBase.addExt(".data").c_str(), "wb"); if (!dataOut) { throw std::runtime_error("could not open data output file!"); } std::ofstream osp(outFileBase + std::string(".osp")); osp << "" << std::endl; osp << "" << std::endl; osp << " " << rkcommon::FileName(outFileBase).base() << "" << std::endl; osp << " " << blockSize << "" << std::endl; osp << " 0 100000" << std::endl; osp << "" << std::endl; size_t numBlockBounds = blockBounds.size(), numRefinementLevels = refinementLevels.size(), numCellWidths = cellWidths.size(); fwrite(&numBlockBounds, sizeof(size_t), 1, infoOut); fwrite(blockBounds.data(), sizeof(box3i), blockBounds.size(), infoOut); fwrite(&numRefinementLevels, sizeof(size_t), 1, infoOut); fwrite( refinementLevels.data(), sizeof(int), refinementLevels.size(), infoOut); fwrite(&numCellWidths, sizeof(size_t), 1, infoOut); fwrite(cellWidths.data(), sizeof(float), cellWidths.size(), infoOut); for (auto &data : brickData) { fwrite(data.data(), sizeof(float), data.size(), dataOut); } fclose(infoOut); fclose(dataOut); } template std::vector loadRAW(const std::string &fileName, const vec3i &dims) { const size_t num = dims.product(); std::vector volume(num); FILE *file = fopen(fileName.c_str(), "rb"); if (!file) throw std::runtime_error( "ospray::amr::loadRaw(): could not open '" + fileName + "'"); size_t numRead = fread(volume.data(), sizeof(T), num, file); if (num != numRead) throw std::runtime_error( "ospray::amr::loadRaw(): read incomplete data ..."); fclose(file); return volume; } } // namespace amr } // namespace ospray #pragma clang diagnostic pop RenderKit-ospray-85af292/apps/common/raw_to_amr/rawToAMR.h000066400000000000000000000045441464752671100234740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "rkcommon/math/box.h" #include "rkcommon/os/FileName.h" #include "rkcommon/tasking/parallel_for.h" #include #include #ifdef _WIN32 #include #else #include #endif #include #include #include #include #include namespace ospray { namespace amr { using namespace rkcommon; using namespace rkcommon::math; void makeAMR(const std::vector &in, const vec3i inGridDims, const int numLevels, const int blockSize, const int refinementLevel, const float threshold, std::vector &blockBounds, std::vector &refinementLevels, std::vector &cellWidths, std::vector> &brickData); void outputAMR(const FileName outFileBase, const std::vector &blockBounds, const std::vector &refinementLevels, const std::vector &cellWidths, const std::vector> &brickData, const int blockSize); template std::vector loadRAW(const std::string &fileName, const vec3i &dims); template std::vector mmapRAW(const std::string &fileName, const vec3i &dims) { #ifdef _WIN32 throw std::runtime_error("Memory mapping not supported in Windows"); #else FILE *file = fopen(fileName.c_str(), "rb"); if (!file) throw std::runtime_error("Could not open file."); fseek(file, 0, SEEK_END); size_t actualFileSize = ftell(file); fclose(file); size_t fileSize = size_t(dims.x) * size_t(dims.y) * size_t(dims.z) * sizeof(T); if (actualFileSize != fileSize) { std::stringstream ss; ss << "Got file size " << prettyNumber(actualFileSize); ss << ", but expected " << prettyNumber(fileSize); ss << ". Common cause is wrong data type!"; throw std::runtime_error(ss.str()); } int fd = ::open(fileName.c_str(), O_RDONLY); if (fd == -1) throw std::runtime_error("Could not open file."); void *mem = mmap(nullptr, fileSize, PROT_READ, MAP_SHARED // |MAP_HUGETLB , fd, 0); ::close(fd); if (mem == MAP_FAILED) throw std::runtime_error("Could not mmap file."); std::vector volume; volume.assign((T *)mem, (T *)mem + dims.product()); return volume; #endif } } // namespace amr } // namespace ospray RenderKit-ospray-85af292/apps/ospBenchmark/000077500000000000000000000000001464752671100206525ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospBenchmark/BaseFixture.cpp000066400000000000000000000036171464752671100236060ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "BaseFixture.h" #include "rkcommon/utility/SaveImage.h" #include std::string BaseFixture::dumpFinalImageDir; BaseFixture::BaseFixture( const std::string &n, const std::string &s, const std::string &r) : name(n + "/" + r), scene(s), rendererType(r) { ::benchmark::Fixture::SetName(name.c_str()); } void BaseFixture::Init() { framebuffer = cpp::FrameBuffer(imgSize.x, imgSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM | OSP_FB_DEPTH); framebuffer.resetAccumulation(); auto builder = testing::newBuilder(scene); testing::setParam(builder, "rendererType", rendererType); SetBuilderParameters(builder); testing::commit(builder); world = testing::buildWorld(builder); testing::release(builder); world.commit(); auto worldBounds = world.getBounds(); ArcballCamera arcballCamera(worldBounds, imgSize); camera = cpp::Camera("perspective"); camera.setParam("aspect", imgSize.x / (float)imgSize.y); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); camera.commit(); renderer = cpp::Renderer(rendererType); SetRendererParameters(renderer); renderer.commit(); } void BaseFixture::Shutdown() { framebuffer = nullptr; renderer = nullptr; camera = nullptr; world = nullptr; } void BaseFixture::TearDown(::benchmark::State &) { if (!dumpFinalImageDir.empty() && !name.empty()) { std::string of = name; std::replace(of.begin(), of.end(), '/', '_'); framebuffer.resetAccumulation(); framebuffer.renderFrame(renderer, camera, world); auto *fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); utility::writePPM( dumpFinalImageDir + "/" + of + ".ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); } Shutdown(); }RenderKit-ospray-85af292/apps/ospBenchmark/BaseFixture.h000066400000000000000000000103441464752671100232460ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ArcballCamera.h" // ospray_testing #include "ospray_testing.h" // google benchmark #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wsuggest-override" #include "benchmark/benchmark.h" #pragma clang diagnostic pop using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; class BaseFixture : public ::benchmark::Fixture { public: BaseFixture(const std::string &n, const std::string &s, const std::string &r); void Init(); void Shutdown(); void SetUp(::benchmark::State &) override { Init(); } void TearDown(::benchmark::State &) override; virtual void SetBuilderParameters(testing::SceneBuilderHandle) {} virtual void SetRendererParameters(cpp::Renderer) {} static std::string dumpFinalImageDir; std::string name; protected: vec2i imgSize{1024, 768}; std::string scene; std::string rendererType; cpp::FrameBuffer framebuffer{nullptr}; cpp::Renderer renderer{nullptr}; cpp::Camera camera{nullptr}; cpp::World world{nullptr}; }; // Use line number to generate unique identifier // Must not use the same FixtureName across different compilation units (.cpp // files) or conflicts may appear #define CAT2(a, b) a##b #define CAT(a, b) CAT2(a, b) #define UNIQUE_NAME(name) CAT(name, __LINE__) #define OSPRAY_DEFINE_BENCHMARK(FixtureName, ...) \ class UNIQUE_NAME(FixtureName) : public FixtureName \ { \ public: \ UNIQUE_NAME(FixtureName)() : FixtureName("", __VA_ARGS__) {} \ \ protected: \ void BenchmarkCase(::benchmark::State &st) override \ { \ for (auto _ : st) { \ framebuffer.renderFrame(renderer, camera, world); \ } \ st.SetItemsProcessed(st.iterations()); \ } \ }; \ BENCHMARK_PRIVATE_REGISTER_F(UNIQUE_NAME(FixtureName)) \ ->Unit(benchmark::kMillisecond) \ ->UseRealTime(); #define UNIQUE_SETUP_NAME(name) CAT(CAT(name, Setup), __LINE__) #define OSPRAY_DEFINE_SETUP_BENCHMARK(FixtureName, ...) \ class UNIQUE_SETUP_NAME(FixtureName) : public FixtureName \ { \ public: \ UNIQUE_SETUP_NAME(FixtureName)() : FixtureName("setup/", __VA_ARGS__) {} \ \ protected: \ void BenchmarkCase(::benchmark::State &st) override \ { \ for (auto _ : st) { \ Shutdown(); \ Init(); \ } \ st.SetItemsProcessed(st.iterations()); \ } \ }; \ BENCHMARK_PRIVATE_REGISTER_F(UNIQUE_SETUP_NAME(FixtureName)) \ ->Unit(benchmark::kMillisecond) \ ->UseRealTime(); RenderKit-ospray-85af292/apps/ospBenchmark/CMakeLists.txt000066400000000000000000000012401464752671100234070ustar00rootroot00000000000000## Copyright 2018 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 if (NOT OSPRAY_ENABLE_APPS_BENCHMARK) return() endif() find_package(benchmark REQUIRED) add_executable(ospBenchmark ${OSPRAY_RESOURCE} ospBenchmark.cpp BaseFixture.cpp benchmarks/Simple.cpp benchmarks/BoxesAo.cpp benchmarks/CornellBoxSpp.cpp benchmarks/GravitySpheresVolume.cpp benchmarks/PerlinNoiseVolumes.cpp benchmarks/ClippingGeometries.cpp ) target_link_libraries(ospBenchmark PRIVATE arcball_camera benchmark::benchmark ospray_testing ) ospray_sign_target(ospBenchmark) install(TARGETS ospBenchmark DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/000077500000000000000000000000001464752671100227675ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/BoxesAo.cpp000066400000000000000000000016511464752671100250360ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../BaseFixture.h" class Boxes : public BaseFixture { public: Boxes( const std::string &n, const std::string &s, const std::string &r, int ao) : BaseFixture(n + s + "/ao_" + std::to_string(ao), s, r), aoSamples(ao) {} void SetRendererParameters(cpp::Renderer r) override { r.setParam("aoSamples", aoSamples); } private: int aoSamples; }; OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "ao", 0); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "ao", 1); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "ao", 16); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "ao", 256); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "scivis", 0); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "scivis", 1); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "scivis", 16); OSPRAY_DEFINE_BENCHMARK(Boxes, "boxes", "scivis", 256); OSPRAY_DEFINE_SETUP_BENCHMARK(Boxes, "boxes", "ao", 256); RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/ClippingGeometries.cpp000066400000000000000000000035011464752671100272630ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../BaseFixture.h" class ClippingGeometries : public BaseFixture { public: ClippingGeometries(const std::string &n, const std::string &s, const std::string &g, const std::string &r) : BaseFixture(n + "clip_geometries/with_" + g, s, r), geometry(g) {} private: std::string geometry; }; OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_spheres", "spheres", "ao"); OSPRAY_DEFINE_BENCHMARK(ClippingGeometries, "clip_with_boxes", "boxes", "ao"); OSPRAY_DEFINE_BENCHMARK(ClippingGeometries, "clip_with_planes", "planes", "ao"); OSPRAY_DEFINE_BENCHMARK(ClippingGeometries, "clip_with_meshes", "meshes", "ao"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_spheres", "spheres", "scivis"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_boxes", "boxes", "scivis"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_planes", "planes", "scivis"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_meshes", "meshes", "scivis"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_spheres", "spheres", "pathtracer"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_boxes", "boxes", "pathtracer"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_planes", "planes", "pathtracer"); OSPRAY_DEFINE_BENCHMARK( ClippingGeometries, "clip_with_meshes", "meshes", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( ClippingGeometries, "clip_with_spheres", "spheres", "scivis"); OSPRAY_DEFINE_SETUP_BENCHMARK( ClippingGeometries, "clip_with_boxes", "boxes", "scivis"); OSPRAY_DEFINE_SETUP_BENCHMARK( ClippingGeometries, "clip_with_planes", "planes", "scivis"); OSPRAY_DEFINE_SETUP_BENCHMARK( ClippingGeometries, "clip_with_meshes", "meshes", "scivis"); RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/CornellBoxSpp.cpp000066400000000000000000000022121464752671100262220ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../BaseFixture.h" class CornellBox : public BaseFixture { public: CornellBox( const std::string &n, const std::string &s, int spp, const std::string &r) : BaseFixture(n + s + "/spp_" + std::to_string(spp), s, r), pixelSamples(spp) {} void SetRendererParameters(cpp::Renderer r) override { r.setParam("pixelSamples", pixelSamples); } private: int pixelSamples; }; OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 1, "ao"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 16, "ao"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 256, "ao"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 1, "scivis"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 16, "scivis"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 256, "scivis"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 1, "pathtracer"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 16, "pathtracer"); OSPRAY_DEFINE_BENCHMARK(CornellBox, "cornell_box", 256, "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(CornellBox, "cornell_box", 256, "pathtracer"); RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/GravitySpheresVolume.cpp000066400000000000000000000025151464752671100276450ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../BaseFixture.h" class GravitySpheres : public BaseFixture { public: GravitySpheres( const std::string &n, const std::string &s, int d, const std::string &r) : BaseFixture(n + s + "/dim_" + std::to_string(d), s, r), dim(d) {} void SetBuilderParameters(testing::SceneBuilderHandle scene) override { testing::setParam(scene, "volumeDimensions", vec3i(dim)); } private: int dim; }; OSPRAY_DEFINE_BENCHMARK(GravitySpheres, "gravity_spheres_volume", 32, "ao"); OSPRAY_DEFINE_BENCHMARK(GravitySpheres, "gravity_spheres_volume", 128, "ao"); OSPRAY_DEFINE_BENCHMARK(GravitySpheres, "gravity_spheres_volume", 512, "ao"); OSPRAY_DEFINE_BENCHMARK(GravitySpheres, "gravity_spheres_volume", 32, "scivis"); OSPRAY_DEFINE_BENCHMARK( GravitySpheres, "gravity_spheres_volume", 128, "scivis"); OSPRAY_DEFINE_BENCHMARK( GravitySpheres, "gravity_spheres_volume", 512, "scivis"); OSPRAY_DEFINE_BENCHMARK( GravitySpheres, "gravity_spheres_volume", 32, "pathtracer"); OSPRAY_DEFINE_BENCHMARK( GravitySpheres, "gravity_spheres_volume", 128, "pathtracer"); OSPRAY_DEFINE_BENCHMARK( GravitySpheres, "gravity_spheres_volume", 512, "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( GravitySpheres, "gravity_spheres_volume", 128, "pathtracer"); RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/PerlinNoiseVolumes.cpp000066400000000000000000000022301464752671100272720ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../BaseFixture.h" class PerlinNoiseVolumes : public BaseFixture { public: PerlinNoiseVolumes( const std::string &n, const std::string &s, bool at, const std::string &r) : BaseFixture(n + s + (at ? "/both_volumes" : "/sphere_only"), s, r), addTorus(at) {} void SetBuilderParameters(testing::SceneBuilderHandle scene) override { testing::setParam(scene, "addTorusVolume", addTorus); } private: bool addTorus; }; OSPRAY_DEFINE_BENCHMARK( PerlinNoiseVolumes, "perlin_noise_volumes", false, "ao"); OSPRAY_DEFINE_BENCHMARK(PerlinNoiseVolumes, "perlin_noise_volumes", true, "ao"); OSPRAY_DEFINE_BENCHMARK( PerlinNoiseVolumes, "perlin_noise_volumes", false, "scivis"); OSPRAY_DEFINE_BENCHMARK( PerlinNoiseVolumes, "perlin_noise_volumes", true, "scivis"); OSPRAY_DEFINE_BENCHMARK( PerlinNoiseVolumes, "perlin_noise_volumes", false, "pathtracer"); OSPRAY_DEFINE_BENCHMARK( PerlinNoiseVolumes, "perlin_noise_volumes", true, "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( PerlinNoiseVolumes, "perlin_noise_volumes", true, "pathtracer"); RenderKit-ospray-85af292/apps/ospBenchmark/benchmarks/Simple.cpp000066400000000000000000000070231464752671100247260ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../BaseFixture.h" class Simple : public BaseFixture { public: Simple(const std::string &n, const std::string &s, const std::string &r) : BaseFixture(n + s, s, r) {} }; OSPRAY_DEFINE_BENCHMARK(Simple, "boxes", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "random_spheres", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "random_spheres", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "random_spheres", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "random_spheres", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "streamlines", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "streamlines", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "streamlines", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "streamlines", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "planes", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "planes", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "planes", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "planes", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_gravity_spheres_volume", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_gravity_spheres_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_gravity_spheres_volume", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( Simple, "clip_gravity_spheres_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_perlin_noise_volumes", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_perlin_noise_volumes", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_perlin_noise_volumes", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( Simple, "clip_perlin_noise_volumes", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_particle_volume", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_particle_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "clip_particle_volume", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "clip_particle_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "particle_volume", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "particle_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "particle_volume", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "particle_volume", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "particle_volume_isosurface", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "particle_volume_isosurface", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "particle_volume_isosurface", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( Simple, "particle_volume_isosurface", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "vdb_volume", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "vdb_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "vdb_volume", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "vdb_volume", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "unstructured_volume", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "unstructured_volume", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "unstructured_volume", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "unstructured_volume", "pathtracer"); OSPRAY_DEFINE_BENCHMARK(Simple, "unstructured_volume_isosurface", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "unstructured_volume_isosurface", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "unstructured_volume_isosurface", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK( Simple, "unstructured_volume_isosurface", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "gravity_spheres_amr", "ao"); OSPRAY_DEFINE_BENCHMARK(Simple, "gravity_spheres_amr", "scivis"); OSPRAY_DEFINE_BENCHMARK(Simple, "gravity_spheres_amr", "pathtracer"); OSPRAY_DEFINE_SETUP_BENCHMARK(Simple, "gravity_spheres_amr", "pathtracer"); RenderKit-ospray-85af292/apps/ospBenchmark/ospBenchmark.cpp000066400000000000000000000101321464752671100237670ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "BaseFixture.h" #include "rkcommon/utility/getEnvVar.h" #ifdef _WIN32 #ifndef NOMINMAX #define NOMINMAX #endif #include #include #endif #include #include namespace { std::vector cmdArg; } // end namespace // Test init/shutdown cycle time ////////////////////////////////////////////// static void ospInit_ospShutdown(benchmark::State &state) { ospShutdown(); for (auto _ : state) { // Those temp variable are needed because the call to ospInit changes the // number and order of arguments std::vector cmdArgCpy(cmdArg); int argc = cmdArgCpy.size(); ospInit(&argc, cmdArgCpy.data()); ospShutdown(); } state.SetItemsProcessed(state.iterations()); std::vector cmdArgCpy(cmdArg); int argc = cmdArgCpy.size(); ospInit(&argc, cmdArgCpy.data()); } BENCHMARK(ospInit_ospShutdown)->Unit(benchmark::kMillisecond); /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // based on BENCHMARK_MAIN() macro from benchmark.h int main(int argc, char **argv) { #ifdef _WIN32 bool waitForKey = false; CONSOLE_SCREEN_BUFFER_INFO csbi; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { // detect standalone console: cursor at (0,0)? waitForKey = csbi.dwCursorPosition.X == 0 && csbi.dwCursorPosition.Y == 0; } #endif // As there is no other way of customizing help output // we have to detect `--help` by ourselves for (int i = 1; i < argc; i++) { if (std::string(argv[i]) == "--help") { std::cout << "The ospBenchmark is a performance measurement tool that " "allows to assess the Intel OSPRay library performance on a target " "hardware. It consists of many workloads that can be listed with " "[--benchmark_list_tests=true] parameter and then selected for run " "with [--benchmark_filter=] parameter. All test assets like " "meshes or textures are generated procedurally during workload " "initialization phase. If a test renders a frame it is stored " "to an offscreen frame buffer." << std::endl << std::endl; std::cout << "After tests completion a results table is printed. Each " "table row corresponds to a single test or a single test " "repetition. Number of repetitions can be controlled with " "[--benchmark_repetitions=] parameter. Each " "repetition completely recreates frame buffer, world, renderer " "and camera. The table has the following columns:" << std::endl; std::cout << " 'Benchmark' - the name of a test" << std::endl; std::cout << " 'Time' - single iteration wall clock time" << std::endl; std::cout << " 'CPU' - single iteration CPU time spend by the main thread" << std::endl; std::cout << " 'Iterations' - number of rendered frames, determined adaptively " "to test for specified minimum time" << std::endl; std::cout << " 'UserCounters' - frames per second value" << std::endl << std::endl; std::cout << "The list of all supported parameters:" << std::endl; } } // save original cmdline args for multiple init/shutdown cycles for (int i = 0; i < argc; i++) cmdArg.push_back(argv[i]); ospInit(&argc, (const char **)argv); std::atexit(ospShutdown); auto DIR = utility::getEnvVar("OSPRAY_BENCHMARK_IMG_DIR"); BaseFixture::dumpFinalImageDir = DIR.value_or(""); ::benchmark::Initialize(&argc, argv); if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; ::benchmark::RunSpecifiedBenchmarks(); #ifdef _WIN32 if (waitForKey) { printf("\n\tpress any key to exit"); _getch(); } #endif return 0; } RenderKit-ospray-85af292/apps/ospExamples/000077500000000000000000000000001464752671100205365ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospExamples/CMakeLists.txt000066400000000000000000000007121464752671100232760ustar00rootroot00000000000000## Copyright 2018 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 if (NOT OSPRAY_ENABLE_APPS_EXAMPLES) return() endif() add_executable(ospExamples ${OSPRAY_RESOURCE} GLFWOSPRayWindow.cpp ospExample.cpp ) target_link_libraries(ospExamples PRIVATE arcball_camera ospray_testing ospray_imgui ${OPENGL_LIBRARIES} ) ospray_sign_target(ospExamples) install(TARGETS ospExamples DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) RenderKit-ospray-85af292/apps/ospExamples/GLFWOSPRayWindow.cpp000066400000000000000000001014611464752671100242320ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "GLFWOSPRayWindow.h" // ospray_testing #include "ospray_testing.h" #include "rkcommon/utility/random.h" // imgui #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" // std #include #include #include #include #include // on Windows often only GL 1.1 headers are present #ifndef GL_CLAMP_TO_BORDER #define GL_CLAMP_TO_BORDER 0x812D #endif #ifndef GL_FRAMEBUFFER_SRGB #define GL_FRAMEBUFFER_SRGB 0x8DB9 #endif #ifndef GL_RGBA32F #define GL_RGBA32F 0x8814 #endif #ifndef GL_RGB32F #define GL_RGB32F 0x8815 #endif static bool g_quitNextFrame = false; static const std::vector g_scenes = {"boxes_lit", "boxes", "cornell_box", "curves", "gravity_spheres_volume", "gravity_spheres_amr", "gravity_spheres_isosurface", "perlin_noise_volumes", "random_spheres", "random_discs", "random_oriented_discs", "streamlines", "subdivision_cube", "unstructured_volume", "unstructured_volume_isosurface", "planes", "clip_with_spheres", "clip_with_planes", "clip_gravity_spheres_volume", "clip_perlin_noise_volumes", "clip_particle_volume", "particle_volume", "particle_volume_isosurface", "vdb_volume", "vdb_volume_packed", "instancing", "test_pt_alloy_roughness", "test_pt_carpaint", "test_pt_glass", "test_pt_thinglass", "test_pt_luminous", "test_pt_material_tex", "test_pt_metal_roughness", "test_pt_metallic_flakes", "test_pt_mix_tex", "test_pt_obj", "test_pt_plastic", "test_pt_principled_metal", "test_pt_principled_plastic", "test_pt_principled_glass", "test_pt_principled_tex", "test_pt_velvet"}; static const std::vector g_curveVariant = { "bspline", "bezier", "hermite", "catmull-rom", "linear", "cones"}; static const std::vector g_renderers = { "scivis", "pathtracer", "ao", "debug"}; static const std::vector g_debugRendererTypes = {"eyeLight", "primID", "geomID", "instID", "Ng", "Ns", "backfacing_Ng", "backfacing_Ns", "texCoord", "dPds", "dPdt", "volume"}; static const std::vector g_pixelFilterTypes = { "point", "box", "gaussian", "mitchell", "blackmanHarris"}; static const std::vector g_AOVs = { "color", "depth", "albedo", "normal", "primID", "objID", "instID"}; static const std::vector g_denoiserQuality = { "low", "medium", "high"}; const char *vec_string_getter(void *vec_, int index) { auto v = (std::vector *)vec_; return v->at(index).c_str(); } // GLFWOSPRayWindow definitions /////////////////////////////////////////////// void error_callback(int error, const char *desc) { std::cerr << "GLFW error " << error << ": " << desc << std::endl; } GLFWOSPRayWindow *GLFWOSPRayWindow::activeWindow = nullptr; GLFWOSPRayWindow::GLFWOSPRayWindow( const vec2i &windowSize, bool denoiserAvail, bool denoiserGPUAvail) : denoiserAvailable(denoiserAvail) { if (activeWindow != nullptr) { throw std::runtime_error("Cannot create more than one GLFWOSPRayWindow!"); } if (denoiserAvailable) { denoiser = cpp::ImageOperation("denoiser"); denoiserEnabled = denoiserGPUAvail; updateFrameOpsNextFrame = denoiserEnabled; } activeWindow = this; glfwSetErrorCallback(error_callback); if (!glfwInit()) { throw std::runtime_error("Failed to initialize GLFW!"); } glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); #ifdef __APPLE_ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); const char *glslVersion = "#version 150"; #else glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); const char *glslVersion = "#version 130"; #endif glfwWindow = glfwCreateWindow( windowSize.x, windowSize.y, "OSPRay Examples", nullptr, nullptr); if (!glfwWindow) { glfwTerminate(); throw std::runtime_error("Failed to create GLFW window!"); } glfwMakeContextCurrent(glfwWindow); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO &io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; ImGui_ImplGlfw_InitForOpenGL(glfwWindow, false); // set GLFW callbacks glfwSetFramebufferSizeCallback( glfwWindow, [](GLFWwindow *, int newWidth, int newHeight) { activeWindow->reshape(vec2i{newWidth, newHeight}); }); glfwSetCursorPosCallback(glfwWindow, [](GLFWwindow *, double x, double y) { ImGuiIO &io = ImGui::GetIO(); if (!activeWindow->showUi || !io.WantCaptureMouse) { activeWindow->motion(vec2f{float(x), float(y)}); } }); glfwSetKeyCallback( glfwWindow, [](GLFWwindow *, int key, int, int action, int) { if (action == GLFW_PRESS) { switch (key) { case GLFW_KEY_G: activeWindow->showUi = !(activeWindow->showUi); break; case GLFW_KEY_Q: g_quitNextFrame = true; break; } } }); glfwSetMouseButtonCallback( glfwWindow, [](GLFWwindow *, int button, int action, int /*mods*/) { auto &w = *activeWindow; if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS) { auto mouse = activeWindow->previousMouse; auto windowSize = activeWindow->windowSize; const vec2f pos(mouse.x / static_cast(windowSize.x), 1.f - mouse.y / static_cast(windowSize.y)); auto res = w.framebuffer.pick(*w.renderer, w.camera, w.world, pos.x, pos.y); if (res.hasHit) { std::cout << "Picked geometry [inst: " << res.instance << ", model: " << res.model << ", prim: " << res.primID << "]" << std::endl; } } }); // will chain our callbacks above ImGui_ImplGlfw_InstallCallbacks(glfwWindow); ImGui_ImplOpenGL3_Init(glslVersion); // set initial OpenGL state glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); // create OpenGL frame buffer texture glGenTextures(1, &framebufferTexture); glBindTexture(GL_TEXTURE_2D, framebufferTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // OSPRay setup // // set up backplate texture std::vector backplate; backplate.push_back(vec4f(0.05f, 0.05f, 0.05f, 1.0f)); backplate.push_back(vec4f(0.05f, 0.05f, 0.05f, 1.0f)); backplate.push_back(vec4f(0.01f, 0.01f, 0.01f, 1.0f)); backplate.push_back(vec4f(0.01f, 0.01f, 0.01f, 1.0f)); backplateTex.setParam( "data", cpp::CopiedData(backplate.data(), vec2ul(2, 2))); backplateTex.setParam("format", OSP_TEXTURE_RGBA32F); addObjectToCommit(backplateTex.handle()); refreshScene(true); // trigger window reshape events with current window size glfwGetFramebufferSize(glfwWindow, &this->windowSize.x, &this->windowSize.y); reshape(this->windowSize); commitOutstandingHandles(); } GLFWOSPRayWindow::~GLFWOSPRayWindow() { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(glfwWindow); glfwTerminate(); } GLFWOSPRayWindow *GLFWOSPRayWindow::getActiveWindow() { return activeWindow; } void GLFWOSPRayWindow::mainLoop() { // continue until the user closes the window startNewOSPRayFrame(); while (!glfwWindowShouldClose(glfwWindow) && !g_quitNextFrame) { glfwPollEvents(); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); if (displayCallback) displayCallback(this); display(); if (showUi) buildUI(); glDisable(GL_FRAMEBUFFER_SRGB); // Disable SRGB conversion for UI ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(glfwWindow); } waitOnOSPRayFrame(); } void GLFWOSPRayWindow::reshape(const vec2i &newWindowSize) { windowSize = newWindowSize; // create new frame buffer auto buffers = OSP_FB_COLOR | OSP_FB_DEPTH | OSP_FB_ACCUM | OSP_FB_VARIANCE | OSP_FB_ALBEDO | OSP_FB_NORMAL | OSP_FB_ID_PRIMITIVE | OSP_FB_ID_OBJECT | OSP_FB_ID_INSTANCE; framebuffer = cpp::FrameBuffer(windowSize.x, windowSize.y, OSP_FB_RGBA32F, buffers); updateTargetFrames(false); refreshFrameOperations(); // reset OpenGL viewport and orthographic projection glViewport(0, 0, windowSize.x, windowSize.y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, windowSize.x, 0.0, windowSize.y, -1.0, 1.0); // update camera arcballCamera->updateWindowSize(windowSize); camera.setParam("aspect", windowSize.x / float(windowSize.y)); addObjectToCommit(camera.handle()); } 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"); std::vector xfms; xfms.push_back(lastXfm); 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"); camera.setParam("transform", xfm); camera.setParam("shutter", range1f(0.5f)); } addObjectToCommit(camera.handle()); } void GLFWOSPRayWindow::motion(const vec2f &position) { const vec2f mouse(position.x, position.y); if (previousMouse != vec2f(-1)) { const bool leftDown = glfwGetMouseButton(glfwWindow, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS; const bool rightDown = glfwGetMouseButton(glfwWindow, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS; const bool middleDown = glfwGetMouseButton(glfwWindow, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS; const vec2f prev = previousMouse; bool cameraChanged = leftDown || rightDown || middleDown; if (leftDown) { const vec2f mouseFrom(clamp(prev.x * 2.f / windowSize.x - 1.f, -1.f, 1.f), clamp(prev.y * 2.f / windowSize.y - 1.f, -1.f, 1.f)); const vec2f mouseTo(clamp(mouse.x * 2.f / windowSize.x - 1.f, -1.f, 1.f), clamp(mouse.y * 2.f / windowSize.y - 1.f, -1.f, 1.f)); arcballCamera->rotate(mouseFrom, mouseTo); } else if (rightDown) { arcballCamera->zoom(mouse.y - prev.y); } else if (middleDown) { arcballCamera->pan(vec2f(mouse.x - prev.x, prev.y - mouse.y)); } if (cameraChanged) { if (cancelFrameOnInteraction) { currentFrame.cancel(); waitOnOSPRayFrame(); } updateCamera(); } } previousMouse = mouse; } void GLFWOSPRayWindow::display() { static float totalRenderTime = 0.f; static auto displayStart = std::chrono::steady_clock::now(); static bool firstFrame = true; if (firstFrame || currentFrame.isReady()) { // display frame rate in window title const auto displayEnd = std::chrono::steady_clock::now(); const auto displayMilliseconds = std::chrono::duration_cast( displayEnd - displayStart); const auto renderTime = currentFrame.duration(); totalRenderTime += renderTime; // update fps every 10 frames or every second framesCounter++; if (framesCounter > 9 || totalRenderTime > 1.f || displayMilliseconds > std::chrono::seconds(1)) { displayFPS = 1000.f * float(framesCounter) / displayMilliseconds.count(); latestFPS = float(framesCounter) / totalRenderTime; displayStart = displayEnd; totalRenderTime = 0.f; framesCounter = 0; updateTitleBar(); } waitOnOSPRayFrame(); auto fbChannel = OSP_FB_COLOR; if (showDepth) fbChannel = OSP_FB_DEPTH; if (showAlbedo) fbChannel = OSP_FB_ALBEDO; if (showNormal) fbChannel = OSP_FB_NORMAL; if (showPrimID) fbChannel = OSP_FB_ID_PRIMITIVE; if (showGeomID) fbChannel = OSP_FB_ID_OBJECT; if (showInstID) fbChannel = OSP_FB_ID_INSTANCE; auto *fb = framebuffer.map(fbChannel); // Copy and normalize depth layer if showDepth is on float *depthFb = static_cast(fb); std::vector depthCopy; if (showDepth) { depthCopy.assign(depthFb, depthFb + (windowSize.x * windowSize.y)); depthFb = depthCopy.data(); float minDepth = rkcommon::math::inf; float maxDepth = rkcommon::math::neg_inf; for (int i = 0; i < windowSize.x * windowSize.y; i++) { if (std::isinf(depthFb[i])) continue; minDepth = std::min(minDepth, depthFb[i]); maxDepth = std::max(maxDepth, depthFb[i]); } const float rcpDepthRange = 1.f / (maxDepth - minDepth); for (int i = 0; i < windowSize.x * windowSize.y; i++) { depthFb[i] = (depthFb[i] - minDepth) * rcpDepthRange; } } unsigned int *ids = static_cast(fb); std::vector idFbArray(windowSize.x * windowSize.y); float *idFb = reinterpret_cast(idFbArray.data()); if (showPrimID || showGeomID || showInstID) { for (int i = 0; i < windowSize.x * windowSize.y; i++) { const unsigned int id = ids[i]; idFbArray[i] = id == -1u ? vec3f(0.f) : rkcommon::utility::makeRandomColor(id); } } if (showNormal) { float *nFb = static_cast(fb); float *iFb = reinterpret_cast(idFbArray.data()); for (int i = 0; i < windowSize.x * windowSize.y * 3; i++) iFb[i] = std::abs(nFb[i]); } glBindTexture(GL_TEXTURE_2D, framebufferTexture); glTexImage2D(GL_TEXTURE_2D, 0, showDepth ? GL_DEPTH_COMPONENT : ((showAlbedo || showNormal || showPrimID || showGeomID || showInstID) ? GL_RGB32F : GL_RGBA32F), windowSize.x, windowSize.y, 0, showDepth ? GL_DEPTH_COMPONENT : ((showAlbedo || showNormal || showPrimID || showGeomID || showInstID) ? GL_RGB : GL_RGBA), GL_FLOAT, showDepth ? depthFb : ((showNormal || showPrimID || showGeomID || showInstID) ? idFb : fb)); framebuffer.unmap(fb); commitOutstandingHandles(); startNewOSPRayFrame(); firstFrame = false; } glEnable(GL_FRAMEBUFFER_SRGB); // Turn on sRGB conversion for OSPRay frame glClear(GL_COLOR_BUFFER_BIT); // render textured quad with OSPRay frame buffer contents glBegin(GL_QUADS); glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f); glTexCoord2f(0.f, 1.f); glVertex2f(0.f, windowSize.y); glTexCoord2f(1.f, 1.f); glVertex2f(windowSize.x, windowSize.y); glTexCoord2f(1.f, 0.f); glVertex2f(windowSize.x, 0.f); glEnd(); } void GLFWOSPRayWindow::startNewOSPRayFrame() { if (updateFrameOpsNextFrame) refreshFrameOperations(); lastXfm = arcballCamera->transform(); if (updateFrameOpsNextFrame || accumLimit == 0 || frame < accumLimit) { currentFrame = framebuffer.renderFrame(*renderer, camera, world); // correctly count rendered frames: to run the PP (e.g. toggling the // denoiser) we need to start a renderFrame and cannot skip rendering via // targetFrames in case PT should *not* use blue noise if (accumLimit == 0 || frame < accumLimit || (rendererType == OSPRayRendererType::PATHTRACER && !blueNoise)) frame++; } updateFrameOpsNextFrame = false; if (renderCameraMotionBlur) { camera.removeParam("motion.transform"); camera.setParam("transform", lastXfm); addObjectToCommit(camera.handle()); renderCameraMotionBlur = false; } } void GLFWOSPRayWindow::waitOnOSPRayFrame() { currentFrame.wait(); } void GLFWOSPRayWindow::addObjectToCommit(OSPObject obj) { objectsToCommit.push_back(obj); } void GLFWOSPRayWindow::updateTitleBar() { std::stringstream windowTitle; windowTitle << "OSPRay frame: " << frame << (accumLimit && frame >= accumLimit ? " (limit reached), last" : ", ") << " render:" << std::fixed << std::setprecision(2) << std::setw(7) << latestFPS << " fps, app:" << std::setw(7) << displayFPS << " fps"; if (latestFPS > 0.f && latestFPS < 2.f) { float progress = currentFrame.progress(); windowTitle << " | "; int barWidth = 20; std::string progBar; progBar.resize(barWidth + 2); auto start = progBar.begin() + 1; auto end = start + progress * barWidth; std::fill(start, end, '='); std::fill(end, progBar.end(), '_'); *end = '>'; progBar.front() = '['; progBar.back() = ']'; windowTitle << progBar; } glfwSetWindowTitle(glfwWindow, windowTitle.str().c_str()); } void GLFWOSPRayWindow::buildUI() { ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize; ImGui::Begin("press 'g' to hide/show UI", nullptr, flags); static int whichScene = 2; if (ImGui::Combo("scene##whichScene", &whichScene, vec_string_getter, (void *)&g_scenes, g_scenes.size())) { scene = g_scenes[whichScene]; refreshScene(true); } if (scene == "curves") { static int whichCurveVariant = 0; if (ImGui::Combo("curveVariant##whichCurveVariant", &whichCurveVariant, vec_string_getter, (void *)&g_curveVariant, g_curveVariant.size())) { curveVariant = g_curveVariant[whichCurveVariant]; refreshScene(true); } } if (scene == "unstructured_volume") { if (ImGui::Checkbox("show cells", &showUnstructuredCells)) refreshScene(true); } static int whichRenderer = 1; static int whichDebuggerType = 0; if (ImGui::Combo("renderer##whichRenderer", &whichRenderer, vec_string_getter, (void *)&g_renderers, g_renderers.size())) { rendererTypeStr = g_renderers[whichRenderer]; if (rendererType == OSPRayRendererType::DEBUGGER) whichDebuggerType = 0; // reset UI if switching away from debug renderer if (rendererTypeStr == "scivis") rendererType = OSPRayRendererType::SCIVIS; else if (rendererTypeStr == "pathtracer") rendererType = OSPRayRendererType::PATHTRACER; else if (rendererTypeStr == "ao") rendererType = OSPRayRendererType::AO; else if (rendererTypeStr == "debug") rendererType = OSPRayRendererType::DEBUGGER; else rendererType = OSPRayRendererType::OTHER; refreshScene(); updateTargetFrames(); } if (rendererType == OSPRayRendererType::DEBUGGER) { if (ImGui::Combo("debug type##whichDebugType", &whichDebuggerType, vec_string_getter, (void *)&g_debugRendererTypes, g_debugRendererTypes.size())) { renderer->setParam("method", g_debugRendererTypes[whichDebuggerType]); addObjectToCommit(renderer->handle()); } } if (ImGui::SliderInt("accumulation limit", &accumLimit, 0, 64)) updateTargetFrames(); ImGui::Checkbox("cancel frame on interaction", &cancelFrameOnInteraction); static int whichAOV = 0; if (ImGui::Combo("AOV Display##whichAOV", &whichAOV, vec_string_getter, (void *)&g_AOVs, g_AOVs.size())) { const auto &aovStr = g_AOVs[whichAOV]; showDepth = showAlbedo = showNormal = showPrimID = showGeomID = showInstID = false; if (aovStr == "depth") showDepth = true; if (aovStr == "albedo") showAlbedo = true; if (aovStr == "normal") showNormal = true; if (aovStr == "primID") showPrimID = true; if (aovStr == "objID") showGeomID = true; if (aovStr == "instID") showInstID = true; } ImGui::Separator(); if (denoiserAvailable) { if (ImGui::Checkbox("denoiser", &denoiserEnabled)) updateFrameOpsNextFrame = true; static int whichQuality = 1; // medium if (denoiserEnabled && ImGui::Combo("quality##whichQuality", &whichQuality, vec_string_getter, (void *)&g_denoiserQuality, g_denoiserQuality.size())) { denoiser.setParam("quality", OSPDenoiserQuality::OSP_DENOISER_QUALITY_LOW + whichQuality); addObjectToCommit(denoiser.handle()); } } ImGui::Separator(); // the gaussian pixel filter is the default, // which is at position 2 in the list static int whichPixelFilter = 2; if (ImGui::Combo("pixelfilter##whichPixelFilter", &whichPixelFilter, vec_string_getter, (void *)&g_pixelFilterTypes, g_pixelFilterTypes.size())) { pixelFilterTypeStr = g_pixelFilterTypes[whichPixelFilter]; OSPPixelFilterType pixelFilterType = OSPPixelFilterType::OSP_PIXELFILTER_GAUSS; if (pixelFilterTypeStr == "point") pixelFilterType = OSPPixelFilterType::OSP_PIXELFILTER_POINT; else if (pixelFilterTypeStr == "box") pixelFilterType = OSPPixelFilterType::OSP_PIXELFILTER_BOX; else if (pixelFilterTypeStr == "gaussian") pixelFilterType = OSPPixelFilterType::OSP_PIXELFILTER_GAUSS; else if (pixelFilterTypeStr == "mitchell") pixelFilterType = OSPPixelFilterType::OSP_PIXELFILTER_MITCHELL; else if (pixelFilterTypeStr == "blackmanHarris") pixelFilterType = OSPPixelFilterType::OSP_PIXELFILTER_BLACKMAN_HARRIS; rendererPT.setParam("pixelFilter", pixelFilterType); rendererSV.setParam("pixelFilter", pixelFilterType); rendererAO.setParam("pixelFilter", pixelFilterType); rendererDBG.setParam("pixelFilter", pixelFilterType); addObjectToCommit(renderer->handle()); } ImGui::Separator(); static int spp = 1; if (ImGui::SliderInt("pixelSamples", &spp, 1, 64)) { rendererPT.setParam("pixelSamples", spp); rendererSV.setParam("pixelSamples", spp); rendererAO.setParam("pixelSamples", spp); rendererDBG.setParam("pixelSamples", spp); addObjectToCommit(renderer->handle()); } if (scene == "mip_map_textures") { static float mipBias = 0.0f; if (ImGui::SliderFloat("mipMapBias", &mipBias, -5.0f, 10.0f)) { rendererPT.setParam("mipMapBias", mipBias); rendererSV.setParam("mipMapBias", mipBias); rendererAO.setParam("mipMapBias", mipBias); rendererDBG.setParam("mipMapBias", mipBias); addObjectToCommit(renderer->handle()); } } static float varianceThreshold = 0.0f; if (ImGui::SliderFloat("varianceThreshold", &varianceThreshold, 0.f, 5.f)) { renderer->setParam("varianceThreshold", varianceThreshold); addObjectToCommit(renderer->handle()); } static vec3f bgColorSRGB{0.0f}; // imGUI's widget implicitly uses sRGB if (ImGui::ColorEdit3("backgroundColor", bgColorSRGB)) { bgColor = vec3f(std::pow(bgColorSRGB.x, 2.2f), std::pow(bgColorSRGB.y, 2.2f), std::pow(bgColorSRGB.z, 2.2f)); // approximate rendererPT.setParam("backgroundColor", bgColor); rendererSV.setParam("backgroundColor", bgColor); rendererAO.setParam("backgroundColor", bgColor); rendererDBG.setParam("backgroundColor", bgColor); addObjectToCommit(renderer->handle()); } static bool useTestTex = true; static bool init = true; if (init || ImGui::Checkbox("backplate texture", &useTestTex)) { init = false; if (useTestTex) { rendererPT.setParam("map_backplate", backplateTex); rendererSV.setParam("map_backplate", backplateTex); rendererAO.setParam("map_backplate", backplateTex); rendererDBG.setParam("map_backplate", backplateTex); } else { rendererPT.removeParam("map_backplate"); rendererSV.removeParam("map_backplate"); rendererAO.removeParam("map_backplate"); rendererDBG.removeParam("map_backplate"); } addObjectToCommit(renderer->handle()); } if (rendererType == OSPRayRendererType::SCIVIS || rendererType == OSPRayRendererType::PATHTRACER) { if (ImGui::Checkbox("sun-sky illumination", &renderSunSky)) { if (renderSunSky) { sunSky.setParam("direction", sunDirection); sunSky.setParam("horizonExtension", horizonExtension); sunSky.setParam("turbidity", turbidity); world.setParam("light", cpp::CopiedData(sunSky)); addObjectToCommit(sunSky.handle()); // turn-off background bgColorSRGB = bgColor = vec3f(0.f); renderer->setParam("backgroundColor", bgColor); useTestTex = false; rendererPT.removeParam("map_backplate"); rendererSV.removeParam("map_backplate"); rendererAO.removeParam("map_backplate"); rendererDBG.removeParam("map_backplate"); addObjectToCommit(renderer->handle()); } else { cpp::Light light("ambient"); light.setParam("visible", false); light.commit(); world.setParam("light", cpp::CopiedData(light)); } addObjectToCommit(world.handle()); } if (renderSunSky) { if (ImGui::DragFloat3("sunDirection", sunDirection, 0.01f, -1.f, 1.f)) { sunSky.setParam("direction", sunDirection); addObjectToCommit(sunSky.handle()); addObjectToCommit(world.handle()); } if (ImGui::DragFloat("turbidity", &turbidity, 0.1f, 1.f, 10.f)) { sunSky.setParam("turbidity", turbidity); addObjectToCommit(sunSky.handle()); addObjectToCommit(world.handle()); } if (ImGui::DragFloat( "horizonExtension", &horizonExtension, 0.01f, 0.f, 1.f)) { sunSky.setParam("horizonExtension", horizonExtension); addObjectToCommit(sunSky.handle()); addObjectToCommit(world.handle()); } } } if (rendererType == OSPRayRendererType::PATHTRACER) { static int lightSamples = -1; if (ImGui::SliderInt("lightSamples", &lightSamples, -1, 32)) { renderer->setParam("lightSamples", lightSamples); addObjectToCommit(renderer->handle()); } static bool limitIndirectLightSamples = true; if (ImGui::Checkbox("limitIndirectLightSamples", &limitIndirectLightSamples)) { renderer->setParam("limitIndirectLightSamples", limitIndirectLightSamples); addObjectToCommit(renderer->handle()); } if (accumLimit) { if (ImGui::Checkbox("blue noise", &blueNoise)) updateTargetFrames(); } else { ImGui::BeginDisabled(); bool f = false; ImGui::Checkbox("blue noise (needs accumulation limit)", &f); ImGui::EndDisabled(); } static int maxDepth = 20; if (ImGui::SliderInt("maxPathLength", &maxDepth, 1, 64)) { renderer->setParam("maxPathLength", maxDepth); addObjectToCommit(renderer->handle()); } static int rouletteDepth = 1; if (ImGui::SliderInt("roulettePathLength", &rouletteDepth, 1, 64)) { renderer->setParam("roulettePathLength", rouletteDepth); addObjectToCommit(renderer->handle()); } static float minContribution = 0.001f; if (ImGui::SliderFloat("minContribution", &minContribution, 0.f, 1.f)) { renderer->setParam("minContribution", minContribution); addObjectToCommit(renderer->handle()); } static float maxContribution = 10000.f; if (ImGui::SliderFloat("maxContribution", &maxContribution, 0.f, 10000.f)) { renderer->setParam("maxContribution", maxContribution); addObjectToCommit(renderer->handle()); } if (ImGui::SliderFloat("camera motion blur", &cameraMotionBlur, 0.f, 1.f)) { updateCamera(); } 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 (uint32_t 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(); } } if (cameraShutterType != OSP_SHUTTER_GLOBAL && ImGui::SliderFloat( "rollingShutterDuration", &cameraRollingShutter, 0.f, 1.0f)) { updateCamera(); } } else if (rendererType == OSPRayRendererType::SCIVIS) { static bool init = true; static bool shadowsEnabled = true; if (init || ImGui::Checkbox("shadows", &shadowsEnabled)) { renderer->setParam("shadows", shadowsEnabled); addObjectToCommit(renderer->handle()); } static bool visibleLights = true; if (init || ImGui::Checkbox("visibleLights", &visibleLights)) { renderer->setParam("visibleLights", visibleLights); addObjectToCommit(renderer->handle()); } static int aoSamples = 1; if (init || ImGui::SliderInt("aoSamples", &aoSamples, 0, 64)) { renderer->setParam("aoSamples", aoSamples); addObjectToCommit(renderer->handle()); } static float samplingRate = 1.f; if (ImGui::SliderFloat("volumeSamplingRate", &samplingRate, 0.001f, 2.f)) { renderer->setParam("volumeSamplingRate", samplingRate); addObjectToCommit(renderer->handle()); } init = false; } else if (rendererType == OSPRayRendererType::AO) { static int aoSamples = 1; if (ImGui::SliderInt("aoSamples", &aoSamples, 0, 64)) { renderer->setParam("aoSamples", aoSamples); addObjectToCommit(renderer->handle()); } static float aoIntensity = 1.f; if (ImGui::SliderFloat("aoIntensity", &aoIntensity, 0.f, 1.f)) { renderer->setParam("aoIntensity", aoIntensity); addObjectToCommit(renderer->handle()); } static float samplingRate = 1.f; if (ImGui::SliderFloat("volumeSamplingRate", &samplingRate, 0.001f, 2.f)) { renderer->setParam("volumeSamplingRate", samplingRate); addObjectToCommit(renderer->handle()); } } static const char *cameraStereoModes[] = { "none", "left", "right", "side-by-side", "top/bottom"}; if (ImGui::BeginCombo("camera stereoMode##cameraStereoMode", cameraStereoModes[cameraStereoMode])) { for (uint32_t 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(); } if (uiCallback) { ImGui::Separator(); uiCallback(); } ImGui::End(); } void GLFWOSPRayWindow::commitOutstandingHandles() { auto handles = objectsToCommit.consume(); if (!handles.empty()) { for (auto &h : handles) ospCommit(h); frame = 0; framebuffer.resetAccumulation(); } } void GLFWOSPRayWindow::refreshScene(bool resetCamera) { auto builder = testing::newBuilder(scene); testing::setParam(builder, "rendererType", rendererTypeStr); if (scene == "curves") { testing::setParam(builder, "curveVariant", curveVariant); } else if (scene == "unstructured_volume") { testing::setParam(builder, "showCells", showUnstructuredCells); } testing::commit(builder); world = testing::buildWorld(builder); testing::release(builder); switch (rendererType) { case OSPRayRendererType::PATHTRACER: renderer = &rendererPT; break; case OSPRayRendererType::SCIVIS: renderer = &rendererSV; break; case OSPRayRendererType::AO: renderer = &rendererAO; break; case OSPRayRendererType::DEBUGGER: renderer = &rendererDBG; break; default: throw std::runtime_error("invalid renderer chosen!"); } if (rendererType == OSPRayRendererType::SCIVIS || rendererType == OSPRayRendererType::PATHTRACER) { if (renderSunSky) world.setParam("light", cpp::CopiedData(sunSky)); } else renderSunSky = false; // retains a set background color on renderer change renderer->setParam("backgroundColor", bgColor); addObjectToCommit(renderer->handle()); world.commit(); if (resetCamera) { // create the arcball camera model arcballCamera.reset( new ArcballCamera(world.getBounds(), windowSize)); lastXfm = arcballCamera->transform(); // init camera camera.setParam("position", vec3f(0.0f, 0.0f, 1.0f)); updateCamera(); } } void GLFWOSPRayWindow::refreshFrameOperations() { if (denoiserEnabled) { framebuffer.setParam("imageOperation", cpp::CopiedData(denoiser)); } else { framebuffer.removeParam("imageOperation"); } framebuffer.commit(); } void GLFWOSPRayWindow::updateTargetFrames(const bool commit) { framebuffer.setParam("targetFrames", rendererType != OSPRayRendererType::PATHTRACER || blueNoise ? accumLimit : 0); if (commit) addObjectToCommit(framebuffer.handle()); } RenderKit-ospray-85af292/apps/ospExamples/GLFWOSPRayWindow.h000066400000000000000000000070041464752671100236750ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ArcballCamera.h" // glfw #include "GLFW/glfw3.h" // ospray #include "ospray/ospray_cpp.h" #include "rkcommon/containers/TransactionalBuffer.h" // std #include using namespace rkcommon::math; using namespace ospray; enum class OSPRayRendererType { SCIVIS, PATHTRACER, AO, DEBUGGER, OTHER }; class GLFWOSPRayWindow { public: GLFWOSPRayWindow(const vec2i &windowSize, bool denoiserAvail = false, bool denoiserGPUAvail = false); ~GLFWOSPRayWindow(); static GLFWOSPRayWindow *getActiveWindow(); void mainLoop(); protected: void addObjectToCommit(OSPObject obj); void updateCamera(); void reshape(const vec2i &newWindowSize); void motion(const vec2f &position); void display(); void startNewOSPRayFrame(); void waitOnOSPRayFrame(); void updateTitleBar(); void buildUI(); void commitOutstandingHandles(); void refreshScene(bool resetCamera = false); void refreshFrameOperations(); void updateTargetFrames(const bool commit = true); static GLFWOSPRayWindow *activeWindow; vec2i windowSize; vec2f previousMouse{-1.f}; bool denoiserAvailable{false}; bool updateFrameOpsNextFrame{false}; bool denoiserEnabled{false}; bool showAlbedo{false}; bool showNormal{false}; bool showDepth{false}; bool showPrimID{false}; bool showGeomID{false}; bool showInstID{false}; bool renderSunSky{false}; bool cancelFrameOnInteraction{false}; bool showUnstructuredCells{false}; // GLFW window instance GLFWwindow *glfwWindow = nullptr; // 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}; // OSPRay objects managed by this class cpp::Renderer rendererPT{"pathtracer"}; cpp::Renderer rendererSV{"scivis"}; cpp::Renderer rendererAO{"ao"}; cpp::Renderer rendererDBG{"debug"}; cpp::Renderer *renderer{nullptr}; cpp::Camera camera{"perspective"}; cpp::World world; cpp::Light sunSky{"sunSky"}; cpp::FrameBuffer framebuffer; cpp::Future currentFrame; cpp::Texture backplateTex{"texture2d"}; cpp::ImageOperation denoiser; int frame{0}; bool blueNoise{true}; int accumLimit{0}; vec3f bgColor{0.f}; vec3f sunDirection{-0.25f, -1.0f, 1.0f}; float turbidity{3.f}; float horizonExtension{0.25f}; std::string scene{"cornell_box"}; std::string curveVariant{"bspline"}; OSPRayRendererType rendererType{OSPRayRendererType::PATHTRACER}; std::string rendererTypeStr{"pathtracer"}; std::string pixelFilterTypeStr{"gaussian"}; // List of OSPRay handles to commit before the next frame rkcommon::containers::TransactionalBuffer objectsToCommit; // OpenGL framebuffer texture GLuint framebufferTexture = 0; // optional registered display callback, called before every display() std::function displayCallback; // toggles display of ImGui UI, if an ImGui callback is provided bool showUi = true; // optional registered ImGui callback, called during every frame to build UI std::function uiCallback; // FPS measurement of last frame uint32_t framesCounter{0}; float latestFPS{0.f}; float displayFPS{0.f}; }; RenderKit-ospray-85af292/apps/ospExamples/example_common.h000066400000000000000000000030241464752671100237110ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "ospray/ospray.h" // std #include #include inline void initializeOSPRay( int argc, const char **argv, bool errorsFatal = true) { // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, // e.g. "--osp:debug" OSPError initError = ospInit(&argc, argv); if (initError != OSP_NO_ERROR) throw std::runtime_error("OSPRay not initialized correctly!"); OSPDevice device = ospGetCurrentDevice(); if (!device) throw std::runtime_error("OSPRay device could not be fetched!"); // set an error callback to catch any OSPRay errors and exit the application if (errorsFatal) { ospDeviceSetErrorCallback( device, [](void *, OSPError error, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; exit(error); }, nullptr); } else { ospDeviceSetErrorCallback( device, [](void *, OSPError, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; }, nullptr); } ospDeviceSetStatusCallback( device, [](void *, const char *msg) { std::cout << msg; }, nullptr); bool warnAsErrors = true; auto logLevel = OSP_LOG_WARNING; ospDeviceSetParam(device, "warnAsError", OSP_BOOL, &warnAsErrors); ospDeviceSetParam(device, "logLevel", OSP_UINT, &logLevel); ospDeviceCommit(device); ospDeviceRelease(device); } RenderKit-ospray-85af292/apps/ospExamples/ospExample.cpp000066400000000000000000000015111464752671100233550ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "GLFWOSPRayWindow.h" #include "example_common.h" using namespace ospray; using rkcommon::make_unique; int main(int argc, const char *argv[]) { initializeOSPRay(argc, argv, false); const bool denoiserAvailable = ospLoadModule("denoiser") == OSP_NO_ERROR; bool denoiserGPUSupport = false; if (denoiserAvailable) { const void *sym = rkcommon::getSymbol("ospray_module_denoiser_gpu_supported"); if (sym) { auto denoiserGPUSupported = (int (*)())sym; denoiserGPUSupport = denoiserGPUSupported(); } } auto glfwOSPRayWindow = make_unique( vec2i(1024, 768), denoiserAvailable, denoiserGPUSupport); glfwOSPRayWindow->mainLoop(); glfwOSPRayWindow.reset(); ospShutdown(); return 0; } RenderKit-ospray-85af292/apps/ospTestSuite/000077500000000000000000000000001464752671100207115ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospTestSuite/CMakeLists.txt000066400000000000000000000036621464752671100234600ustar00rootroot00000000000000## Copyright 2017 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 if (NOT OSPRAY_ENABLE_APPS_TESTING) return() endif() # Note: CMake provides FindGTest which defines target GTest::GTest find_package(GTest REQUIRED CONFIG) ospray_disable_compiler_warnings() add_library(ospray_gtest_utils environment.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} environment.cpp # potentially compile with SYCL, overriding non-SYCL ospray_gtest_utils test_geometry.cpp test_volumetric.cpp test_appearance.cpp test_assigned_data.cpp test_sharedusm_data.cpp test_light.cpp test_enums.cpp $<$:test_glm_compat.cpp> test_camera.cpp test_motionblur.cpp test_framebuffer.cpp test_interpolation.cpp test_imageop.cpp ospTestSuite.cpp ) # We need to know if volumes are enabled at compile time so that # we can enable/disable the VKL-dependent tests for enum values # Same for OIDN tests target_compile_definitions(ospTestSuite PRIVATE $<$:OSPRAY_ENABLE_VOLUMES> $<$:OSPRAY_MODULE_DENOISER> ) target_include_directories(ospTestSuite PRIVATE $<$:$> $<$:$> ) target_link_libraries(ospTestSuite PRIVATE ospray_testing ospray_gtest_utils embree $<$:${GLM_TARGET}> ) if (OSPRAY_MODULE_GPU) ospray_add_sycl_target(ospTestSuite) endif() ospray_sign_target(ospTestSuite) install(TARGETS ospTestSuite DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) RenderKit-ospray-85af292/apps/ospTestSuite/environment.cpp000066400000000000000000000055631464752671100237720ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "environment.h" #ifdef SYCL_LANGUAGE_VERSION #include "sycl/sycl.hpp" #endif OSPRayEnvironment::OSPRayEnvironment(int argc, char **argv) { ParseArgs(argc, argv); } void OSPRayEnvironment::ParseArgs(int argc, char **argv) { std::vector testArgs; for (int idx = 0; idx < argc; ++idx) { testArgs.push_back(argv[idx]); } for (size_t idx = 0; idx < testArgs.size(); ++idx) { if (testArgs.at(idx) == "--help") { std::cout << "--help : display this help msg\n" << "--dump-img : dump the rendered image to file\n" << "--imgsize-x=XX : change the length of an image\n" << "--imgsize-y=XX : change the height of an image\n" << "--renderer-type=XX : change the renderer used for tests\n" << "--baseline-dir=XX : Change the directory used for baseline " "images during tests\n" << "--own-SYCL : turn on SYCL data sharing.\n"; std::exit(EXIT_SUCCESS); } else if (testArgs.at(idx) == "--dump-img") { dumpImg = true; } else if (testArgs.at(idx).find("--renderer-type=") == 0) { rendererType = GetStrArgValue(&testArgs.at(idx)); } else if (testArgs.at(idx).find("--imgsize-x=") == 0) { imgSize.x = GetNumArgValue(&testArgs.at(idx)); } else if (testArgs.at(idx).find("--imgsize-y=") == 0) { imgSize.y = GetNumArgValue(&testArgs.at(idx)); } else if (testArgs.at(idx).find("--baseline-dir=") == 0) { baselineDir = GetStrArgValue(&testArgs.at(idx)); } else if (testArgs.at(idx).find("--failed-dir=") == 0) { failedDir = GetStrArgValue(&testArgs.at(idx)); } else if (testArgs.at(idx).find("--own-SYCL") == 0) { #ifdef SYCL_LANGUAGE_VERSION ownSYCL = true; #else std::cerr << "WARNING: Compiled without SYCL support, " "SYCL data sharing not supported." << std::endl; #endif } } } int OSPRayEnvironment::GetNumArgValue(std::string *arg) const { int ret = 0; size_t valueStartPos = arg->find_first_of('='); if (valueStartPos != std::string::npos) { ret = std::stoi(arg->substr(valueStartPos + 1)); if (ret <= 0) { std::cout << "Incorrect value specified for argument %s " << *arg << std::endl << std::flush; } } return ret; } std::string OSPRayEnvironment::GetStrArgValue(std::string *arg) const { std::string ret; size_t valueStartPos = arg->find_first_of('='); if (valueStartPos != std::string::npos) { ret = arg->substr(valueStartPos + 1); } return ret; } #ifdef SYCL_LANGUAGE_VERSION OSPRayEnvironment::~OSPRayEnvironment() { delete appsSyclQueue; } sycl::queue *OSPRayEnvironment::GetAppsSyclQueue() { if (ownSYCL && !appsSyclQueue) appsSyclQueue = new sycl::queue; return appsSyclQueue; } #endif RenderKit-ospray-85af292/apps/ospTestSuite/environment.h000066400000000000000000000025351464752671100234330ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" using namespace ospray; using namespace rkcommon::math; namespace sycl { inline namespace _V1 { class queue; } } // namespace sycl class OSPRayEnvironment : public ::testing::Environment { public: OSPRayEnvironment(int argc, char **argv); ~OSPRayEnvironment() #ifndef SYCL_LANGUAGE_VERSION = default #endif ; bool GetDumpImg() const { return dumpImg; } std::string GetRendererType() const { return rendererType; } vec2i GetImgSize() const { return imgSize; } std::string GetBaselineDir() const { return baselineDir; } std::string GetFailedDir() const { return failedDir; } #ifdef SYCL_LANGUAGE_VERSION sycl::queue *GetAppsSyclQueue(); #endif void ParseArgs(int argc, char **argv); std::string GetStrArgValue(std::string *arg) const; int GetNumArgValue(std::string *arg) const; private: bool dumpImg{false}; std::string rendererType{"scivis"}; std::string baselineDir{"regression_test_baseline"}; std::string failedDir{false}; vec2i imgSize{1024, 768}; bool ownSYCL{false}; #ifdef SYCL_LANGUAGE_VERSION sycl::queue *appsSyclQueue{nullptr}; #endif }; RenderKit-ospray-85af292/apps/ospTestSuite/ospTestSuite.cpp000066400000000000000000000034411464752671100240720ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_fixture.h" #ifdef SYCL_LANGUAGE_VERSION #include "sycl/sycl.hpp" #endif OSPRayEnvironment *ospEnv; int main(int argc, char **argv) { { // Check to make sure these functions work without a currently set device std::cout << "Verify device API usage prior to ospInit()..." << std::endl; auto d = ospGetCurrentDevice(); ospDeviceRetain(d); ospDeviceRelease(d); std::cout << "...done!" << std::endl; } ospInit(&argc, (const char **)argv); ::testing::InitGoogleTest(&argc, argv); ospEnv = new OSPRayEnvironment(argc, argv); AddGlobalTestEnvironment(ospEnv); { cpp::Device device = cpp::Device::current(); #ifdef SYCL_LANGUAGE_VERSION sycl::queue *appsSyclQueue = ospEnv->GetAppsSyclQueue(); if (appsSyclQueue) { static auto appsSyclContext = appsSyclQueue->get_context(); static auto appsSyclDevice = appsSyclQueue->get_device(); device.setParam("syclContext", OSP_VOID_PTR, (void *)&appsSyclContext); device.setParam("syclDevice", OSP_VOID_PTR, (void *)&appsSyclDevice); } #endif 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(); } auto result = RUN_ALL_TESTS(); ospShutdown(); return result; } RenderKit-ospray-85af292/apps/ospTestSuite/test_appearance.cpp000066400000000000000000000460261464752671100245630ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_appearance.h" #include "ArcballCamera.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" namespace OSPRayTestScenes { Texture2D::Texture2D() { rendererType = "pathtracer"; samplesPerPixel = 8; } void Texture2D::SetUp() { Base::SetUp(); camera.setParam("position", vec3f(4.f, 3.f, 0.f)); // flip image to have origin in upper left corner, plus mirror camera.setParam("imageStart", vec2f(1.f, 1.f)); camera.setParam("imageEnd", vec2f(0.f, 0.f)); auto params = GetParam(); OSPTextureFilter filter = std::get<0>(params); // create (4*2) x 5 grid constexpr int cols = 8; constexpr int rows = 5; std::vector vertex; std::vector texcoord; rkcommon::index_sequence_2D iidx(vec2i(cols, rows)); // Generate each quad, each needs its own vertex coordinates w/ unique // texcoords when we're testing w/ texture coordinates on for (auto i : iidx) { const int idx_start = vertex.size(); vertex.push_back(vec3f(i.x, i.y * 1.2f, 5.3f)); vertex.push_back(vec3f(i.x + 1.f, i.y * 1.2f, 5.3f)); vertex.push_back(vec3f(i.x + 1.f, (i.y + 1.f) * 1.2f, 5.3f)); vertex.push_back(vec3f(i.x, (i.y + 1.f) * 1.2f, 5.3f)); texcoord.push_back(vec2f(0.f, 0.f)); texcoord.push_back(vec2f(1.f, 0.f)); texcoord.push_back(vec2f(1.f, 1.f)); texcoord.push_back(vec2f(0.f, 1.f)); } cpp::Geometry mesh("mesh"); mesh.setParam("vertex.position", cpp::CopiedData(vertex)); if (std::get<3>(params)) { mesh.setParam("vertex.texcoord", cpp::CopiedData(texcoord)); } mesh.setParam("quadSoup", true); mesh.commit(); // create textures: // columns=#channels, rows=type=[byte, byte, float, short, half] std::array format = {OSP_TEXTURE_R8, OSP_TEXTURE_RA8, OSP_TEXTURE_RGB8, OSP_TEXTURE_RGBA8, OSP_TEXTURE_L8, OSP_TEXTURE_LA8, OSP_TEXTURE_SRGB, OSP_TEXTURE_SRGBA, OSP_TEXTURE_R32F, OSP_TEXTURE_RA32F, OSP_TEXTURE_RGB32F, OSP_TEXTURE_RGBA32F, OSP_TEXTURE_R16, OSP_TEXTURE_RA16, OSP_TEXTURE_RGB16, OSP_TEXTURE_RGBA16, OSP_TEXTURE_R16F, OSP_TEXTURE_RA16F, OSP_TEXTURE_RGB16F, OSP_TEXTURE_RGBA16F}; std::array eltype = {OSP_UCHAR, OSP_VEC2UC, OSP_VEC3UC, OSP_VEC4UC, OSP_UCHAR, OSP_VEC2UC, OSP_VEC3UC, OSP_VEC4UC, OSP_FLOAT, OSP_VEC2F, OSP_VEC3F, OSP_VEC4F, OSP_USHORT, OSP_VEC2US, OSP_VEC3US, OSP_VEC4US, OSP_USHORT, OSP_VEC2US, OSP_VEC3US, OSP_VEC4US}; std::array dbyte; std::array dshort; std::array dfloat; std::array dhalf; rkcommon::index_sequence_2D didx(vec2i(3, 5)); for (auto idx : didx) { auto i = didx.flatten(idx); // the center texel should be 127 / 32767 / 0.5, to test normal maps dbyte[i] = vec4uc(idx.x * 80 + 47, idx.y * 56 + 15, 204, i * 15 + 40); dshort[i] = vec4us( idx.x * 20480 + 12287, idx.y * 14336 + 4095, 52428, i * 3932 + 9830); dfloat[i] = vec4f(idx.x * 0.3125f + 0.1875f, idx.y * 0.21875f + 0.0625f, 0.8f, i * 0.06f + 0.15f); } // float to half conversion uint32_t *pf = (uint32_t *)dfloat.data(); uint16_t *ph = (uint16_t *)dhalf.data(); for (int i = 0; i < 4 * 15; i++, pf++, ph++) *ph = (((*pf >> 23) - 112) << 10) | ((*pf >> 13) & 0x3ff); std::array addr = { dbyte.data(), dbyte.data(), dfloat.data(), dshort.data(), dhalf.data()}; std::array stride = {4, 4, 16, 8, 8}; cpp::GeometricModel model(mesh); std::array material; for (auto idx : iidx) { auto i = iidx.flatten(idx); auto fmt = format[i / 2]; auto eltp = eltype[i / 2]; cpp::Texture tex("texture2d"); tex.setParam("format", fmt); tex.setParam("filter", filter); auto tmp = ospNewSharedData(addr[idx.y], eltp, 3, stride[idx.y], 5); auto data = ospNewData(eltp, 3, 5); ospCopyData(tmp, data); ospRelease(tmp); tex.setParam("data", data); tex.commit(); ospRelease(data); cpp::Material mat("obj"); mat.setParam("kd", vec3f(0.8)); mat.setParam(i & 1 ? "map_bump" : "map_kd", tex); mat.commit(); material[i] = mat; } model.setParam("material", cpp::CopiedData(material)); AddModel(model); { // set up backplate texture std::array bpdata; bool toggle = false; for (auto &el : bpdata) { el = toggle ? vec3uc(5, 10, 5) : vec3uc(10, 5, 10); toggle = !toggle; } cpp::CopiedData texData(bpdata.data(), vec2ul(125, 94)); cpp::Texture backplateTex("texture2d"); backplateTex.setParam("format", OSP_TEXTURE_RGB8); backplateTex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); backplateTex.setParam("data", texData); backplateTex.commit(); renderer.setParam("map_backplate", backplateTex); } cpp::Light light1("distant"); cpp::Light light2("distant"); // two light sets if (std::get<2>(params)) { // default light light1.setParam("intensity", 3.f); // highlighting normal direction light2.setParam("direction", vec3f(0.7f, 0.2f, 0.f)); light2.setParam("intensity", 5.f); light2.setParam("color", vec3f(0.f, 0.f, 0.5f)); } else { // perpendicular bright lights, testing center normal light1.setParam("direction", vec3f(0.5f, -1.f, 0.f)); light1.setParam("color", vec3f(999.f, 0.f, 0.0f)); light2.setParam("direction", vec3f(-0.5f, 1.f, 0.f)); light2.setParam("color", vec3f(0.f, 999.f, 0.0f)); } AddLight(light1); AddLight(light2); renderer.setParam("mipMapBias", std::get<1>(params)); } static cpp::Texture createTexture2D(uint32_t width = 32, uint32_t height = 32, vec2ui wrapMode = vec2ui(OSP_TEXTURE_WRAP_REPEAT), OSPTextureFilter filter = OSP_TEXTURE_FILTER_LINEAR) { // Prepare texel data std::vector dbyte(width * height); rkcommon::index_sequence_2D idx(vec2i(width, height)); for (auto i : idx) dbyte[idx.flatten(i)] = vec3uc(i.x * (256 / width), i.y * (256 / height), i.x * (256 / width)); // Create texture object cpp::Texture tex("texture2d"); tex.setParam("format", OSP_TEXTURE_RGB8); tex.setParam("filter", filter); tex.setParam("wrapMode", wrapMode); tex.setParam("data", cpp::CopiedData(dbyte.data(), vec2ul(width, height))); tex.commit(); return tex; } static cpp::Geometry createQuads( const int cols, const int rows, const float gap, const bool withTC = false) { cpp::Geometry quads("mesh"); { // Create quads data std::vector position(4 * cols * rows); rkcommon::index_sequence_2D idx(vec2i(cols, rows)); for (auto i : idx) { auto l = static_cast(i) * gap; auto u = l + (.75f * gap); position[4 * idx.flatten(i) + 0] = vec3f(l.x, l.y, 0.f); position[4 * idx.flatten(i) + 1] = vec3f(l.x, u.y, 0.f); position[4 * idx.flatten(i) + 2] = vec3f(u.x, u.y, 0.f); position[4 * idx.flatten(i) + 3] = vec3f(u.x, l.y, 0.f); } // Set quads parameters quads.setParam( "vertex.position", cpp::CopiedData(position.data(), 4 * cols * rows)); if (withTC) { std::vector texcoord(4 * cols * rows); for (auto i : idx) { texcoord[4 * idx.flatten(i) + 0] = vec2f(-1.f, -1.f); texcoord[4 * idx.flatten(i) + 1] = vec2f(-1.f, 3.f); texcoord[4 * idx.flatten(i) + 2] = vec2f(3.f, 3.f); texcoord[4 * idx.flatten(i) + 3] = vec2f(3.f, -1.f); } quads.setParam( "vertex.texcoord", cpp::CopiedData(texcoord.data(), 4 * cols * rows)); } quads.setParam("quadSoup", true); quads.commit(); } return quads; } Texture2DTransform::Texture2DTransform() { rendererType = GetParam(); } void Texture2DTransform::SetUp() { Base::SetUp(); camera.setParam("position", vec3f(4.f, 4.f, -10.f)); camera.setParam("direction", vec3f(0.f, 0.f, 1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); // Create quad geometry constexpr int cols = 2; constexpr int rows = 2; cpp::Geometry quads = createQuads(cols, rows, 5.f); // Create materials std::array materials; cpp::Texture tex = createTexture2D(); for (int i = 0; i < cols * rows; i++) { cpp::Material mat("obj"); mat.setParam("map_kd", tex); mat.commit(); materials[i] = mat; } // Set scale materials[1].setParam("map_kd.scale", vec2f(.5f)); materials[1].commit(); // Set rotation materials[2].setParam("map_kd.rotation", 45.f); materials[2].commit(); // Set translation materials[3].setParam("map_kd.translation", vec2f(.5f)); materials[3].commit(); // Create geometric model cpp::GeometricModel model(quads); model.setParam("material", cpp::CopiedData(materials)); AddModel(model); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.5f); AddLight(ambient); } Texture2DWrapMode::Texture2DWrapMode() { rendererType = "scivis"; } void Texture2DWrapMode::SetUp() { Base::SetUp(); auto params = GetParam(); OSPTextureFilter filter = std::get<1>(params); camera.setParam("position", vec3f(4.f, 4.f, -8.f)); camera.setParam("direction", vec3f(0.f, 0.f, 1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); // Create quad geometry constexpr int cols = 3; constexpr int rows = 3; cpp::Geometry quads = createQuads(cols, rows, 3.f, true); // Create materials std::array materials; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { cpp::Texture tex = createTexture2D(4, 4, vec2ui(j, i), filter); cpp::Material mat("obj"); mat.setParam("map_kd", tex); mat.commit(); materials[(i * cols) + j] = mat; } } // Create geometric model cpp::GeometricModel model(quads); model.setParam("material", cpp::CopiedData(materials)); AddModel(model); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.5f); AddLight(ambient); renderer.setParam("mipMapBias", std::get<0>(params)); } Texture2DMipMapping::Texture2DMipMapping() { auto params = GetParam(); rendererType = std::get<0>(params); samplesPerPixel = 4; } void Texture2DMipMapping::SetUp() { Base::SetUp(); auto params = GetParam(); auto builder = ospray::testing::newBuilder("mip_map_textures"); ospray::testing::setParam(builder, "filter", (uint32_t)std::get<2>(params)); ospray::testing::setParam(builder, "tcScale", std::get<4>(params)); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); std::string cameraType = std::get<1>(params); camera = cpp::Camera(cameraType); if (cameraType == "perspective") camera.setParam("aspect", imgSize.x / (float)imgSize.y); if (cameraType == "orthographic") camera.setParam("height", 10.0f); camera.setParam( "position", vec3f(0.f, 0.f, cameraType == "panoramic" ? -4.f : -6.f)); OSPStereoMode stereoMode = std::get<5>(params); if (cameraType == "perspective" || cameraType == "panoramic") camera.setParam("stereoMode", stereoMode); if (stereoMode == OSP_STEREO_TOP_BOTTOM) { camera.setParam("imageStart", vec2f(0.25f)); camera.setParam("imageEnd", vec2f(0.75f)); } renderer.setParam("mipMapBias", std::get<3>(params)); cpp::Light distant("distant"); distant.setParam("direction", vec3f(0.f, 0.f, 1.f)); distant.setParam("intensity", 3.f); AddLight(distant); } RendererMaterialList::RendererMaterialList() { rendererType = GetParam(); } void RendererMaterialList::SetUp() { Base::SetUp(); // Setup geometry // cpp::Geometry sphereGeometry("sphere"); constexpr int dimSize = 3; rkcommon::index_sequence_2D numSpheres(dimSize); std::vector spheres; std::vector index; std::vector materials; auto makeObjMaterial = [](vec3f Kd, vec3f Ks) -> cpp::Material { cpp::Material mat("obj"); mat.setParam("kd", Kd); mat.setParam("ks", Ks); mat.commit(); return mat; }; for (auto i : numSpheres) { auto i_f = static_cast(i); spheres.emplace_back(i_f.x, i_f.y, 0.f); auto l = i_f / (dimSize - 1); materials.push_back( makeObjMaterial(lerp(l.x, vec3f(0.1f), vec3f(0.f, 0.f, 1.f)), lerp(l.y, vec3f(0.f), vec3f(1.f)))); index.push_back(static_cast(numSpheres.flatten(i))); } sphereGeometry.setParam("sphere.position", cpp::CopiedData(spheres)); sphereGeometry.setParam("radius", 0.4f); sphereGeometry.commit(); cpp::GeometricModel model(sphereGeometry); model.setParam("material", cpp::CopiedData(index)); AddModel(model); // Setup renderer material list // renderer.setParam("material", cpp::CopiedData(materials)); // Create the world to get bounds for camera setup // if (!instances.empty()) world.setParam("instance", cpp::CopiedData(instances)); instances.clear(); world.commit(); auto worldBounds = world.getBounds(); ArcballCamera arcballCamera(worldBounds, imgSize); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); // Setup lights // cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.5f); AddLight(ambient); } PTBackgroundRefraction::PTBackgroundRefraction() { rendererType = "pathtracer"; samplesPerPixel = 64; } void PTBackgroundRefraction::SetUp() { bool backgroundRefraction = GetParam(); Base::SetUp(); // Setup geometry // cpp::Geometry boxGeometry("box"); rkcommon::index_sequence_3D numBoxes(vec3i(2, 2, 1)); std::vector boxes; for (auto i : numBoxes) { auto f3 = static_cast(i); auto lower = f3 * vec3f(1.5f, 1.5f, 0.0f) + vec3f(-1.25f, -1.25f, 2.5f); auto upper = lower + vec3f(1.f, 1.f, 0.27f); boxes.emplace_back(lower, upper); } boxGeometry.setParam("box", cpp::CopiedData(boxes)); boxGeometry.commit(); cpp::GeometricModel model(boxGeometry); std::vector materials; materials.emplace_back(cpp::Material("thinGlass")); materials.emplace_back(cpp::Material("glass")); materials.emplace_back(cpp::Material("glass")); materials.back().setParam("eta", 1.2f); materials.emplace_back(cpp::Material("obj")); materials.back().setParam("d", 0.2f); materials.back().setParam("kd", vec3f(0.7f, 0.5f, 0.1f)); for (auto &m : materials) m.commit(); model.setParam("material", cpp::CopiedData(materials)); AddModel(model); renderer.setParam("backgroundRefraction", backgroundRefraction); { // set up backplate texture std::vector bpdata; bpdata.push_back(vec4uc(199, 60, 10, 255)); bpdata.push_back(vec4uc(60, 199, 40, 255)); bpdata.push_back(vec4uc(80, 40, 199, 255)); bpdata.push_back(vec4uc(99, 10, 99, 255)); cpp::CopiedData texData(bpdata.data(), vec2ul(2, 2)); cpp::Texture backplateTex("texture2d"); backplateTex.setParam("format", OSP_TEXTURE_RGBA8); backplateTex.setParam("data", texData); backplateTex.commit(); renderer.setParam("map_backplate", backplateTex); } cpp::Light light("sunSky"); light.setParam("turbidity", 8.0f); light.setParam("intensity", 0.005f); AddLight(light); cpp::Light mirrorlight("sunSky"); mirrorlight.setParam("up", vec3f(0.0f, -1.0f, 0.0f)); AddLight(mirrorlight); } // Test Instantiations ////////////////////////////////////////////////////// INSTANTIATE_TEST_SUITE_P(Transparency, FromOsprayTesting, ::testing::Combine(::testing::Values("transparency"), ::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values(16))); TEST_P(RendererMaterialList, material_list) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(MaterialLists, RendererMaterialList, ::testing::Values("scivis", "pathtracer")); INSTANTIATE_TEST_SUITE_P(TestScenesPtMaterials, FromOsprayTesting, ::testing::Combine(::testing::Values("test_pt_alloy_roughness", "test_pt_carpaint", "test_pt_glass", "test_pt_thinglass", "test_pt_luminous", "test_pt_material_tex", "test_pt_metal_roughness", "test_pt_metallic_flakes", "test_pt_mix_tex", "test_pt_obj", "test_pt_plastic", "test_pt_principled_metal", "test_pt_principled_plastic", "test_pt_principled_glass", "test_pt_principled_tex", "test_pt_velvet"), ::testing::Values("pathtracer"), ::testing::Values(64))); TEST_P(Texture2D, filter) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Appearance, Texture2D, ::testing::Combine(::testing::Values(OSP_TEXTURE_FILTER_LINEAR, OSP_TEXTURE_FILTER_NEAREST), ::testing::Values(0.0f), ::testing::Bool(), ::testing::Bool())); INSTANTIATE_TEST_SUITE_P(AppearanceMipMap, Texture2D, ::testing::Combine(::testing::Values(OSP_TEXTURE_FILTER_LINEAR, OSP_TEXTURE_FILTER_NEAREST), ::testing::Values(6.0f), ::testing::Bool(), ::testing::Values(false))); TEST_P(Texture2DTransform, simple) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P( Appearance, Texture2DTransform, ::testing::Values("scivis")); TEST_P(Texture2DWrapMode, wrap) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Appearance, Texture2DWrapMode, ::testing::Combine(::testing::Values(0.0f, 5.0f), ::testing::Values( OSP_TEXTURE_FILTER_NEAREST, OSP_TEXTURE_FILTER_LINEAR))); TEST_P(Texture2DMipMapping, mipMapping) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(MipMap, Texture2DMipMapping, ::testing::Combine(::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values("perspective"), ::testing::Values( OSP_TEXTURE_FILTER_NEAREST, OSP_TEXTURE_FILTER_LINEAR), ::testing::Values(0.0f, 1.0f), ::testing::Values(1.0f), ::testing::Values(OSP_STEREO_NONE))); INSTANTIATE_TEST_SUITE_P(MipMapScale, Texture2DMipMapping, ::testing::Combine(::testing::Values("pathtracer"), ::testing::Values("perspective"), ::testing::Values(OSP_TEXTURE_FILTER_LINEAR), ::testing::Values(1.0f), ::testing::Values(0.3f, 3.1f), ::testing::Values(OSP_STEREO_NONE))); INSTANTIATE_TEST_SUITE_P(MipMapCamera, Texture2DMipMapping, ::testing::Combine(::testing::Values("pathtracer"), ::testing::Values("perspective", "orthographic", "panoramic"), ::testing::Values(OSP_TEXTURE_FILTER_LINEAR), ::testing::Values(1.0f), ::testing::Values(1.0f), ::testing::Values(OSP_STEREO_NONE, OSP_STEREO_TOP_BOTTOM))); TEST_P(PTBackgroundRefraction, backgroundRefraction) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Appearance, PTBackgroundRefraction, ::testing::Bool()); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_appearance.h000066400000000000000000000030751464752671100242250ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_fixture.h" namespace OSPRayTestScenes { // Test all texture image formats (and filter modes) class Texture2D : public Base, public ::testing::TestWithParam> { public: Texture2D(); void SetUp() override; }; class Texture2DTransform : public Base, public ::testing::TestWithParam { public: Texture2DTransform(); void SetUp() override; }; class Texture2DWrapMode : public Base, public ::testing::TestWithParam< std::tuple> { public: Texture2DWrapMode(); void SetUp() override; }; class Texture2DMipMapping : public Base, public ::testing::TestWithParam> { public: Texture2DMipMapping(); void SetUp() override; }; class RendererMaterialList : public Base, public ::testing::TestWithParam { public: RendererMaterialList(); void SetUp() override; }; class PTBackgroundRefraction : public Base, public ::testing::TestWithParam { public: PTBackgroundRefraction(); void SetUp() override; }; } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_assigned_data.cpp000066400000000000000000000106331464752671100252450ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include "test_fixture.h" #ifdef SYCL_LANGUAGE_VERSION #include "sycl/sycl.hpp" #endif extern OSPRayEnvironment *ospEnv; namespace OSPRayTestScenes { struct TestAssignedCopyDelCounts { ~TestAssignedCopyDelCounts(); static int delcounts; }; int TestAssignedCopyDelCounts::delcounts{0}; static void exiting() { ASSERT_EQ(TestAssignedCopyDelCounts::delcounts, 2) << "Mem leak: The buffers should have been freed by now."; } TestAssignedCopyDelCounts::~TestAssignedCopyDelCounts() { exiting(); } class TestAssignedCopy : public Base, public ::testing::Test, virtual public TestAssignedCopyDelCounts { public: void SetUp() override; }; #define VALIDATION_MESSAGE \ std::cout << __FUNCTION__ \ << " delcounts = " << TestAssignedCopyDelCounts::delcounts \ << std::endl static void customMallocDeleter(const void *dels, const void *buff) { free((void *)buff); (*(int *)dels)++; VALIDATION_MESSAGE; } #ifdef SYCL_LANGUAGE_VERSION static void customSYCLDeleter(const void *syclQueue, const void *buff) { sycl::free((void *)buff, *(sycl::queue *)syclQueue); TestAssignedCopyDelCounts::delcounts++; VALIDATION_MESSAGE; } #endif static void customNewDeleter(const void *dels, const void *buff) { delete[] (float *)buff; (*(int *)dels)++; VALIDATION_MESSAGE; } void TestAssignedCopy::SetUp() { Base::SetUp(); camera.setParam("position", vec3f(0.f, 0.f, 4.f)); camera.setParam("direction", vec3f(0.f, 0.f, -1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); cpp::Geometry spheres("sphere"); const int numspheres = 1000; std::vector centersB; // per default use malloc float *radiiB = (float *)malloc(numspheres * sizeof(float)); OSPDeleterCallback radiiDeleter = customMallocDeleter; void *radiiUserData = &TestAssignedCopyDelCounts::delcounts; #ifdef SYCL_LANGUAGE_VERSION auto *appsSyclQueue = ospEnv->GetAppsSyclQueue(); if (appsSyclQueue) { // but on GPU use sycl::malloc free(radiiB); radiiB = sycl::malloc_shared(numspheres, *appsSyclQueue); radiiDeleter = customSYCLDeleter; radiiUserData = appsSyclQueue; } #endif vec2f *tcoordsB = new vec2f[numspheres]; unsigned int randomSeed{0}; std::mt19937 gen(randomSeed); std::uniform_real_distribution centerDistribution(-1.f, 1.f); std::uniform_real_distribution radiusDistribution(0.05f, 0.15f); for (int i = 0; i < numspheres; i++) { radiiB[i] = radiusDistribution(gen); const float x = centerDistribution(gen); const float y = centerDistribution(gen); const float z = centerDistribution(gen); centersB.emplace_back(x, y, z); tcoordsB[i] = vec2f((float)i / (float)numspheres, 0.f); } OSPData radii = ospNewAssignedData1D( radiiB, OSP_FLOAT, numspheres, radiiDeleter, radiiUserData); OSPData tcoords = ospNewAssignedData1D(tcoordsB, OSP_VEC2F, numspheres, customNewDeleter, &TestAssignedCopyDelCounts::delcounts); spheres.setParam("sphere.position", cpp::MovedData(centersB)); EXPECT_TRUE(centersB.empty()) << "Buffer was not moved."; spheres.setParam("sphere.radius", radii); spheres.setParam("sphere.texcoord", tcoords); spheres.commit(); ASSERT_EQ(delcounts, 0) << "Buffers were freed before the app released them."; ospRelease(radii); ospRelease(tcoords); cpp::GeometricModel model(spheres); cpp::Material sphereMaterial("obj"); sphereMaterial.commit(); model.setParam("material", sphereMaterial); AddModel(model); cpp::Light distant("distant"); distant.setParam("intensity", 3.0f); distant.setParam("direction", vec3f(0.3f, -4.0f, 0.8f)); distant.setParam("color", vec3f(1.0f, 0.5f, 0.5f)); distant.setParam("angularDiameter", 1.0f); AddLight(distant); cpp::Light ambient = ospNewLight("ambient"); ambient.setParam("intensity", 0.1f); AddLight(ambient); if (delcounts > 0) std::cout << "Buffers were already freed " "(internal copy? missing internal Ref<>?)." << std::endl; } // Test Instantiations ////////////////////////////////////////////////////// TEST_F(TestAssignedCopy, deleterCallbacks) { PerformRenderTest(); } } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_camera.cpp000066400000000000000000000065041464752671100237110ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray_testing.h" #include "test_fixture.h" namespace OSPRayTestScenes { // Test all stereo modes of perspective and panoramic class Stereo : public Base, public ::testing::TestWithParam< std::tuple> { public: Stereo(); void SetUp() override; protected: std::string cameraType; vec3f pos{0.0f, 0.0f, -0.5f}; OSPStereoMode stereoMode; }; class PixelFilter : public Base, public ::testing::TestWithParam< std::tuple> { public: PixelFilter(); void SetUp() override; protected: OSPPixelFilterType pixelFilter; }; // Implementations ///////////////////////////////////////////////////////////// Stereo::Stereo() { rendererType = "scivis"; samplesPerPixel = 4; auto params = GetParam(); cameraType = std::get<0>(params); stereoMode = std::get<1>(params); } void Stereo::SetUp() { Base::SetUp(); auto builder = ospray::testing::newBuilder("cornell_box"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); camera = cpp::Camera(cameraType); if (cameraType == "perspective") { pos.z = -2.f; camera.setParam("aspect", imgSize.x / (float)imgSize.y); } camera.setParam("position", pos); camera.setParam("stereoMode", stereoMode); camera.setParam("transform", affine3f(one)); } PixelFilter::PixelFilter() { auto params = GetParam(); rendererType = std::get<0>(params); pixelFilter = std::get<1>(params); } void PixelFilter::SetUp() { Base::SetUp(); const float aspect = imgSize.x / (float)imgSize.y; const float diag = sqrt(aspect * aspect + 1.f); for (float r = 0.1f; r < diag;) { const float w = lerp(sqrt(r / diag), 0.1f, 0.002f); cpp::Light light("spot"); light.setParam("innerRadius", r); light.setParam("radius", r + 0.5f * w); light.setParam("intensityQuantity", OSP_INTENSITY_QUANTITY_RADIANCE); AddLight(light); r += w; } camera = cpp::Camera("orthographic"); camera.setParam("aspect", aspect); camera.setParam("position", vec3f(0.5f * aspect, -0.5f, 1.f)); camera.setParam("direction", vec3f(0.f, 0.f, -1.f)); renderer.setParam("pixelFilter", pixelFilter); renderer.setParam("backgroundColor", vec4f(0.f, 0.f, 0.f, 1.0f)); if (rendererType == "scivis") renderer.setParam("visibleLights", true); } // Test Instantiations ///////////////////////////////////////////////////////// TEST_P(Stereo, stereo) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Camera, Stereo, ::testing::Combine(::testing::Values("perspective", "panoramic"), ::testing::Values(OSP_STEREO_LEFT, OSP_STEREO_RIGHT, OSP_STEREO_SIDE_BY_SIDE, OSP_STEREO_TOP_BOTTOM))); TEST_P(PixelFilter, test) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Camera, PixelFilter, ::testing::Combine(::testing::Values("scivis", "pathtracer"), ::testing::Values(OSP_PIXELFILTER_POINT, OSP_PIXELFILTER_BOX, OSP_PIXELFILTER_GAUSS, OSP_PIXELFILTER_MITCHELL, OSP_PIXELFILTER_BLACKMAN_HARRIS))); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_camera.h000066400000000000000000000000001464752671100233370ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospTestSuite/test_enums.cpp000066400000000000000000000133071464752671100236070ustar00rootroot00000000000000// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #ifdef SYCL_LANGUAGE_VERSION #include "sycl/sycl.hpp" #endif #include "embree4/rtcore.h" #include "ospray/OSPEnums.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "openvkl/openvkl.h" TEST(Enums, VKLLogLevel) { ASSERT_LE(sizeof(OSPLogLevel), sizeof(VKLLogLevel)); ASSERT_EQ(OSP_LOG_DEBUG, VKL_LOG_DEBUG); ASSERT_EQ(OSP_LOG_INFO, VKL_LOG_INFO); ASSERT_EQ(OSP_LOG_WARNING, VKL_LOG_WARNING); ASSERT_EQ(OSP_LOG_ERROR, VKL_LOG_ERROR); ASSERT_EQ(OSP_LOG_NONE, VKL_LOG_NONE); } TEST(Enums, VKLDataType) { ASSERT_LE(sizeof(OSPDataType), sizeof(VKLDataType)); ASSERT_EQ(OSP_BOOL, VKL_BOOL); ASSERT_EQ(OSP_CHAR, VKL_CHAR); ASSERT_EQ(OSP_VEC2C, VKL_VEC2C); ASSERT_EQ(OSP_VEC3C, VKL_VEC3C); ASSERT_EQ(OSP_VEC4C, VKL_VEC4C); ASSERT_EQ(OSP_UCHAR, VKL_UCHAR); ASSERT_EQ(OSP_VEC2UC, VKL_VEC2UC); ASSERT_EQ(OSP_VEC3UC, VKL_VEC3UC); ASSERT_EQ(OSP_VEC4UC, VKL_VEC4UC); ASSERT_EQ(OSP_SHORT, VKL_SHORT); ASSERT_EQ(OSP_VEC2S, VKL_VEC2S); ASSERT_EQ(OSP_VEC3S, VKL_VEC3S); ASSERT_EQ(OSP_VEC4S, VKL_VEC4S); ASSERT_EQ(OSP_USHORT, VKL_USHORT); ASSERT_EQ(OSP_VEC2US, VKL_VEC2US); ASSERT_EQ(OSP_VEC3US, VKL_VEC3US); ASSERT_EQ(OSP_VEC4US, VKL_VEC4US); ASSERT_EQ(OSP_INT, VKL_INT); ASSERT_EQ(OSP_VEC2I, VKL_VEC2I); ASSERT_EQ(OSP_VEC3I, VKL_VEC3I); ASSERT_EQ(OSP_VEC4I, VKL_VEC4I); ASSERT_EQ(OSP_UINT, VKL_UINT); ASSERT_EQ(OSP_VEC2UI, VKL_VEC2UI); ASSERT_EQ(OSP_VEC3UI, VKL_VEC3UI); ASSERT_EQ(OSP_VEC4UI, VKL_VEC4UI); ASSERT_EQ(OSP_LONG, VKL_LONG); ASSERT_EQ(OSP_VEC2L, VKL_VEC2L); ASSERT_EQ(OSP_VEC3L, VKL_VEC3L); ASSERT_EQ(OSP_VEC4L, VKL_VEC4L); ASSERT_EQ(OSP_ULONG, VKL_ULONG); ASSERT_EQ(OSP_VEC2UL, VKL_VEC2UL); ASSERT_EQ(OSP_VEC3UL, VKL_VEC3UL); ASSERT_EQ(OSP_VEC4UL, VKL_VEC4UL); ASSERT_EQ(OSP_HALF, VKL_HALF); ASSERT_EQ(OSP_VEC2H, VKL_VEC2H); ASSERT_EQ(OSP_VEC3H, VKL_VEC3H); ASSERT_EQ(OSP_VEC4H, VKL_VEC4H); ASSERT_EQ(OSP_FLOAT, VKL_FLOAT); ASSERT_EQ(OSP_VEC2F, VKL_VEC2F); ASSERT_EQ(OSP_VEC3F, VKL_VEC3F); ASSERT_EQ(OSP_VEC4F, VKL_VEC4F); ASSERT_EQ(OSP_DOUBLE, VKL_DOUBLE); ASSERT_EQ(OSP_VEC2D, VKL_VEC2D); ASSERT_EQ(OSP_VEC3D, VKL_VEC3D); ASSERT_EQ(OSP_VEC4D, VKL_VEC4D); ASSERT_EQ(OSP_BOX1I, VKL_BOX1I); ASSERT_EQ(OSP_BOX2I, VKL_BOX2I); ASSERT_EQ(OSP_BOX3I, VKL_BOX3I); ASSERT_EQ(OSP_BOX4I, VKL_BOX4I); ASSERT_EQ(OSP_BOX1F, VKL_BOX1F); ASSERT_EQ(OSP_BOX2F, VKL_BOX2F); ASSERT_EQ(OSP_BOX3F, VKL_BOX3F); ASSERT_EQ(OSP_BOX4F, VKL_BOX4F); ASSERT_EQ(OSP_DATA, VKL_DATA); ASSERT_EQ(OSP_LINEAR2F, VKL_LINEAR2F); ASSERT_EQ(OSP_LINEAR3F, VKL_LINEAR3F); ASSERT_EQ(OSP_AFFINE2F, VKL_AFFINE2F); ASSERT_EQ(OSP_AFFINE3F, VKL_AFFINE3F); ASSERT_EQ(OSP_RAW, VKL_RAW); ASSERT_EQ(OSP_BYTE, VKL_BYTE); ASSERT_EQ(OSP_VOID_PTR, VKL_VOID_PTR); ASSERT_EQ(OSP_STRING, VKL_STRING); ASSERT_EQ(OSP_OBJECT, VKL_OBJECT); // those are different object types: // ASSERT_EQ(OSP_VOLUME, VKL_VOLUME); } TEST(Enums, VKLUnstructuredCellType) { ASSERT_LE(sizeof(OSPUnstructuredCellType), sizeof(VKLUnstructuredCellType)); ASSERT_EQ(OSP_TETRAHEDRON, VKL_TETRAHEDRON); ASSERT_EQ(OSP_HEXAHEDRON, VKL_HEXAHEDRON); ASSERT_EQ(OSP_WEDGE, VKL_WEDGE); ASSERT_EQ(OSP_PYRAMID, VKL_PYRAMID); } TEST(Enums, VKLAMRMethod) { ASSERT_LE(sizeof(OSPAMRMethod), sizeof(VKLAMRMethod)); ASSERT_EQ(OSP_AMR_CURRENT, VKL_AMR_CURRENT); ASSERT_EQ(OSP_AMR_FINEST, VKL_AMR_FINEST); ASSERT_EQ(OSP_AMR_OCTANT, VKL_AMR_OCTANT); } TEST(Enums, VKLFilter) { ASSERT_LE(sizeof(OSPVolumeFilter), sizeof(VKLFilter)); ASSERT_EQ(OSP_VOLUME_FILTER_NEAREST, VKL_FILTER_NEAREST); ASSERT_EQ(OSP_VOLUME_FILTER_LINEAR, VKL_FILTER_LINEAR); ASSERT_EQ(OSP_VOLUME_FILTER_CUBIC, VKL_FILTER_CUBIC); } TEST(Enums, VKLFormat) { ASSERT_LE(sizeof(OSPVolumeFormat), sizeof(VKLFormat)); ASSERT_EQ(OSP_VOLUME_FORMAT_TILE, VKL_FORMAT_TILE); ASSERT_EQ(OSP_VOLUME_FORMAT_DENSE_ZYX, VKL_FORMAT_DENSE_ZYX); } TEST(Enums, VKLError) { ASSERT_LE(sizeof(OSPError), sizeof(VKLError)); ASSERT_EQ(OSP_NO_ERROR, VKL_NO_ERROR); ASSERT_EQ(OSP_UNKNOWN_ERROR, VKL_UNKNOWN_ERROR); ASSERT_EQ(OSP_INVALID_ARGUMENT, VKL_INVALID_ARGUMENT); ASSERT_EQ(OSP_INVALID_OPERATION, VKL_INVALID_OPERATION); ASSERT_EQ(OSP_OUT_OF_MEMORY, VKL_OUT_OF_MEMORY); ASSERT_EQ(OSP_UNSUPPORTED_CPU, VKL_UNSUPPORTED_CPU); } #endif TEST(Enums, RTCSubdivisionMode) { ASSERT_LE(sizeof(OSPSubdivisionMode), sizeof(RTCSubdivisionMode)); ASSERT_EQ(OSP_SUBDIVISION_NO_BOUNDARY, RTC_SUBDIVISION_MODE_NO_BOUNDARY); ASSERT_EQ( OSP_SUBDIVISION_SMOOTH_BOUNDARY, RTC_SUBDIVISION_MODE_SMOOTH_BOUNDARY); ASSERT_EQ(OSP_SUBDIVISION_PIN_CORNERS, RTC_SUBDIVISION_MODE_PIN_CORNERS); ASSERT_EQ(OSP_SUBDIVISION_PIN_BOUNDARY, RTC_SUBDIVISION_MODE_PIN_BOUNDARY); ASSERT_EQ(OSP_SUBDIVISION_PIN_ALL, RTC_SUBDIVISION_MODE_PIN_ALL); } TEST(Enums, RTCError) { ASSERT_LE(sizeof(OSPError), sizeof(RTCError)); ASSERT_EQ(OSP_NO_ERROR, RTC_ERROR_NONE); ASSERT_EQ(OSP_UNKNOWN_ERROR, RTC_ERROR_UNKNOWN); ASSERT_EQ(OSP_INVALID_ARGUMENT, RTC_ERROR_INVALID_ARGUMENT); ASSERT_EQ(OSP_INVALID_OPERATION, RTC_ERROR_INVALID_OPERATION); ASSERT_EQ(OSP_OUT_OF_MEMORY, RTC_ERROR_OUT_OF_MEMORY); ASSERT_EQ(OSP_UNSUPPORTED_CPU, RTC_ERROR_UNSUPPORTED_CPU); } TEST(Enums, RTCGeometryType) { ASSERT_EQ(OSP_SPHERE, RTC_GEOMETRY_TYPE_SPHERE_POINT); ASSERT_EQ(OSP_DISC, RTC_GEOMETRY_TYPE_DISC_POINT); ASSERT_EQ(OSP_ORIENTED_DISC, RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT); } #ifdef OSPRAY_MODULE_DENOISER #include "OpenImageDenoise/oidn.h" TEST(Enums, OIDNQuality) { ASSERT_LE(sizeof(OSPDenoiserQuality), sizeof(OIDNQuality)); ASSERT_EQ(OSP_DENOISER_QUALITY_LOW, OIDN_QUALITY_FAST); ASSERT_EQ(OSP_DENOISER_QUALITY_MEDIUM, OIDN_QUALITY_BALANCED); ASSERT_EQ(OSP_DENOISER_QUALITY_HIGH, OIDN_QUALITY_HIGH); } #endif RenderKit-ospray-85af292/apps/ospTestSuite/test_fixture.cpp000066400000000000000000000124061464752671100241450ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_fixture.h" #include "ArcballCamera.h" #include "ospray_testing.h" extern OSPRayEnvironment *ospEnv; namespace OSPRayTestScenes { Base::Base() { const ::testing::TestCase *const testCase = ::testing::UnitTest::GetInstance()->current_test_case(); const ::testing::TestInfo *const testInfo = ::testing::UnitTest::GetInstance()->current_test_info(); { std::string testCaseName = testCase->name(); std::string testInfoName = testInfo->name(); size_t pos = testCaseName.find('/'); if (pos == std::string::npos) { testName = testCaseName + "_" + testInfoName; } else { std::string instantiationName = testCaseName.substr(0, pos); std::string className = testCaseName.substr(pos + 1); testName = className + "_" + instantiationName + "_" + testInfoName; } for (char &byte : testName) if (byte == '/') byte = '_'; } imgSize = ospEnv->GetImgSize(); rendererType = "scivis"; frames = 1; samplesPerPixel = 16; } void Base::SetUp() { framebuffer = cpp::FrameBuffer(imgSize.x, imgSize.y, frameBufferFormat, OSP_FB_COLOR | OSP_FB_ACCUM | OSP_FB_DEPTH); imageTool.reset(new OSPImageTools(imgSize, GetTestName(), frameBufferFormat)); CreateEmptyScene(); } void Base::AddLight(cpp::Light light) { light.commit(); lightsList.push_back(light); } void Base::AddModel(cpp::GeometricModel model, affine3f xfm) { model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); cpp::Instance instance(group); instance.setParam("transform", xfm); AddInstance(instance); } void Base::AddModel(cpp::VolumetricModel model, affine3f xfm) { model.commit(); cpp::Group group; group.setParam("volume", cpp::CopiedData(model)); group.commit(); cpp::Instance instance(group); instance.setParam("transform", xfm); AddInstance(instance); } void Base::AddInstance(cpp::Instance instance) { instance.commit(); instances.push_back(instance); } void Base::PerformRenderTest() { SetLights(); if (!instances.empty()) world.setParam("instance", cpp::CopiedData(instances)); camera.commit(); world.commit(); renderer.commit(); framebuffer.resetAccumulation(); RenderFrame(); void *framebuffer_data = 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); } void Base::CreateEmptyScene() { camera = cpp::Camera("perspective"); camera.setParam("aspect", imgSize.x / (float)imgSize.y); camera.setParam("position", vec3f(0.f)); camera.setParam("direction", vec3f(0.f, 0.f, 1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); renderer = cpp::Renderer(rendererType); if (rendererType == "ao") renderer.setParam("aoSamples", 0); if (rendererType == "scivis") { renderer.setParam("shadows", true); renderer.setParam("aoSamples", 16); } renderer.setParam("backgroundColor", vec3f(1.0f)); renderer.setParam("pixelSamples", samplesPerPixel); world = cpp::World(); } void Base::SetLights() { if (!lightsList.empty()) world.setParam("light", cpp::CopiedData(lightsList)); } void Base::RenderFrame() { for (int frame = 0; frame < frames; ++frame) cpp::Future future = framebuffer.renderFrame(renderer, camera, world); } FromOsprayTesting::FromOsprayTesting() { auto params = GetParam(); sceneName = std::get<0>(params); rendererType = std::get<1>(params); samplesPerPixel = std::get<2>(params); } void FromOsprayTesting::SetUp() { Base::SetUp(); auto builder = ospray::testing::newBuilder(sceneName); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); world.commit(); auto worldBounds = world.getBounds(); ArcballCamera arcballCamera(worldBounds, imgSize); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); if (rendererType == "pathtracer") renderer.setParam("limitIndirectLightSamples", false); } void FromOsprayTestingMaxDepth::SetUp() { FromOsprayTesting::SetUp(); // set up max depth texture { cpp::Texture maxDepthTex("texture2d"); std::vector maxDepth = {3.f, 3.f, 3.f, 3.f}; maxDepthTex.setParam( "data", cpp::CopiedData(maxDepth.data(), vec2ul(2, 2))); maxDepthTex.setParam("format", OSP_TEXTURE_R32F); maxDepthTex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); maxDepthTex.commit(); renderer.setParam("map_maxDepth", maxDepthTex); } } void FromOsprayTestingVariance::SetUp() { FromOsprayTesting::SetUp(); frames = 22; framebuffer = cpp::FrameBuffer(imgSize.x, imgSize.y, frameBufferFormat, OSP_FB_COLOR | OSP_FB_ACCUM | OSP_FB_VARIANCE); renderer.setParam("varianceThreshold", 10.0f); } void FromOsprayTestingLightSamples::SetUp() { FromOsprayTesting::SetUp(); renderer.setParam("lightSamples", 8); } } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_fixture.h000066400000000000000000000044361464752671100236160ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #include #include #include #include "environment.h" #include "test_tools.h" namespace OSPRayTestScenes { // Base class for all test fixtures. // Deriving classes can call CreateEmptyScene() to set up model, renderer, // camera etc. Behaviour of this method can be changed by modifying fields // rendererType, frames and samplesPerPixel beforehand. class Base { public: Base(); virtual ~Base() = default; virtual void SetUp(); Base &operator=(const Base &) = delete; Base(const Base &) = delete; void AddLight(cpp::Light new_light); void AddModel(cpp::GeometricModel model, affine3f xfm = one); void AddModel(cpp::VolumetricModel model, affine3f xfm = one); virtual void AddInstance(cpp::Instance instance); virtual void PerformRenderTest(); vec2i GetImgSize() const { return imgSize; } std::string GetTestName() const { return testName; } protected: void CreateEmptyScene(); void SetLights(); void RenderFrame(); // Data // vec2i imgSize; std::string testName; std::string rendererType; int frames; int samplesPerPixel; cpp::FrameBuffer framebuffer{nullptr}; cpp::Renderer renderer{nullptr}; cpp::Camera camera{nullptr}; cpp::World world{nullptr}; OSPFrameBufferFormat frameBufferFormat = OSP_FB_SRGBA; std::unique_ptr imageTool; std::vector lightsList; std::vector instances; }; // Fixture class used for tests that uses 'ospray_testing' scenes class FromOsprayTesting : public Base, public ::testing::TestWithParam> { public: FromOsprayTesting(); void SetUp() override; protected: std::string sceneName; }; // with map_maxDepth texture class FromOsprayTestingMaxDepth : public FromOsprayTesting { public: void SetUp() override; }; class FromOsprayTestingVariance : public FromOsprayTesting { public: void SetUp() override; }; class FromOsprayTestingLightSamples : public FromOsprayTesting { public: void SetUp() override; }; } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_framebuffer.cpp000066400000000000000000000063041464752671100247430ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ArcballCamera.h" #include "ospray_testing.h" #include "rkcommon/utility/random.h" #include "test_fixture.h" extern OSPRayEnvironment *ospEnv; namespace OSPRayTestScenes { class IDBuffer : public Base, public ::testing::TestWithParam> { public: IDBuffer(); void SetUp() override; void PerformRenderTest() override; protected: OSPFrameBufferChannel idBuffer{OSP_FB_ID_PRIMITIVE}; bool appIDs{false}; }; IDBuffer::IDBuffer() { auto params = GetParam(); idBuffer = std::get<0>(params); appIDs = std::get<1>(params); rendererType = std::get<2>(params); samplesPerPixel = 2; } void IDBuffer::SetUp() { Base::SetUp(); framebuffer = cpp::FrameBuffer(imgSize.x, imgSize.y, frameBufferFormat, idBuffer); instances.clear(); auto builder = ospray::testing::newBuilder( idBuffer == OSP_FB_ID_PRIMITIVE ? "perlin_noise_volumes" : "instancing"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::setParam(builder, "numInstances", vec2ui(10, 3)); ospray::testing::setParam(builder, "useIDs", appIDs); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); } inline uint8_t to_uc(const float f) { return 255.f * clamp(f, 0.f, 1.0f); } inline uint32_t to_rgba8(const vec3f c) { return to_uc(c.x) | (to_uc(c.y) << 8) | (to_uc(c.z) << 16) | 0xff000000; } void IDBuffer::PerformRenderTest() { if (!instances.empty()) world.setParam("instance", cpp::CopiedData(instances)); world.commit(); ArcballCamera arcballCamera(world.getBounds(), imgSize); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); camera.setParam("fovy", 45.0f); camera.commit(); renderer.commit(); framebuffer.resetAccumulation(); RenderFrame(); auto *framebuffer_data = (uint32_t *)framebuffer.map(idBuffer); std::vector framebufferData(imgSize.product()); for (int i = 0; i < imgSize.product(); i++) framebufferData[i] = framebuffer_data[i] == -1u ? 0 : to_rgba8(rkcommon::utility::makeRandomColor(framebuffer_data[i])); framebuffer.unmap(framebuffer_data); if (ospEnv->GetDumpImg()) { EXPECT_EQ( imageTool->saveTestImage(framebufferData.data()), OsprayStatus::Ok); } else { EXPECT_EQ(imageTool->compareImgWithBaseline(framebufferData.data()), OsprayStatus::Ok); } } // Test Instantiations ////////////////////////////////////////////////////// TEST_P(IDBuffer, IDBuffer) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Primitive, IDBuffer, ::testing::Combine(::testing::Values(OSP_FB_ID_PRIMITIVE), ::testing::Values(false), ::testing::Values("scivis", "pathtracer"))); INSTANTIATE_TEST_SUITE_P(ObjectInstance, IDBuffer, ::testing::Combine(::testing::Values(OSP_FB_ID_OBJECT, OSP_FB_ID_INSTANCE), ::testing::Bool(), ::testing::Values("scivis", "pathtracer"))); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_geometry.cpp000066400000000000000000000204771464752671100243210ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_geometry.h" #include "ArcballCamera.h" #include "ospray_testing.h" namespace OSPRayTestScenes { SpherePrecision::SpherePrecision() { auto params = GetParam(); radius = std::get<0>(params); dist = std::get<1>(params) * radius; move_cam = std::get<2>(params); rendererType = std::get<3>(params); } void SpherePrecision::SetUp() { Base::SetUp(); float fov = 160.0f * std::min(std::tan(radius / std::abs(dist)), 1.0f); float cent = move_cam ? 0.0f : dist + radius; camera.setParam( "position", vec3f(0.f, 0.f, move_cam ? -dist - radius : 0.0f)); camera.setParam("direction", vec3f(0.f, 0.f, 1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); camera.setParam("fovy", fov); renderer.setParam("pixelSamples", 16); renderer.setParam("backgroundColor", vec4f(0.2f, 0.2f, 0.4f, 1.0f)); if (rendererType == "scivis") { renderer.setParam("shadows", true); renderer.setParam("aoSamples", 16); } else if (rendererType == "ao") { renderer.setParam("aoSamples", 16); renderer.setParam("aoIntensity", 1.f); } else if (rendererType == "pathtracer") { renderer.setParam("maxPathLength", 2); renderer.setParam("limitIndirectLightSamples", false); } cpp::Geometry sphere("sphere"); cpp::Geometry inst_sphere("sphere"); std::vector sph_center = {vec3f(-0.5f * radius, -0.3f * radius, cent), vec3f(0.8f * radius, -0.3f * radius, cent), vec3f(0.8f * radius, 1.5f * radius, cent), vec3f(0.0f, -10001.3f * radius, cent)}; std::vector sph_radius = { radius, 0.9f * radius, 0.9f * radius, 10000.f * radius}; sphere.setParam("sphere.position", cpp::CopiedData(sph_center)); sphere.setParam("sphere.radius", cpp::CopiedData(sph_radius)); sphere.commit(); inst_sphere.setParam("sphere.position", cpp::CopiedData(vec3f(0.f))); inst_sphere.setParam("sphere.radius", cpp::CopiedData(90.f * radius)); inst_sphere.commit(); cpp::GeometricModel model1(sphere); cpp::GeometricModel model2(inst_sphere); cpp::Material sphereMaterial("obj"); sphereMaterial.setParam("d", 1.0f); sphereMaterial.commit(); model1.setParam("material", sphereMaterial); model2.setParam("material", sphereMaterial); affine3f xfm(vec3f(0.01, 0, 0), vec3f(0, 0.01, 0), vec3f(0, 0, 0.01), vec3f(-0.5f * radius, 1.6f * radius, cent)); AddModel(model1); AddModel(model2, xfm); cpp::Light distant("distant"); distant.setParam("intensity", 3.0f); distant.setParam("direction", vec3f(0.3f, -4.0f, 0.8f)); distant.setParam("color", vec3f(1.0f, 0.5f, 0.5f)); distant.setParam("angularDiameter", 1.0f); AddLight(distant); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.1f); AddLight(ambient); } Curves::Curves() { auto params = GetParam(); curveVariant = std::get<0>(params); rendererType = std::get<1>(params); } void Curves::SetUp() { Base::SetUp(); auto builder = ospray::testing::newBuilder("curves"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::setParam(builder, "curveVariant", curveVariant); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); world.commit(); auto worldBounds = world.getBounds(); ArcballCamera arcballCamera(worldBounds, imgSize); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); } class ClippingParallel : public Base, public ::testing::Test { public: ClippingParallel(); void SetUp() override; }; ClippingParallel::ClippingParallel() { rendererType = "pathtracer"; } void ClippingParallel::SetUp() { Base::SetUp(); instances.clear(); auto builder = ospray::testing::newBuilder("clip_with_planes"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); camera = cpp::Camera("orthographic"); camera.setParam("height", 2.5f); camera.setParam("direction", vec3f(-0.5f, -0.5f, 1.0f)); camera.setParam("position", vec3f(1.0f, 1.0f, -2.0f)); } // Test Instantiations ////////////////////////////////////////////////////// TEST_P(SpherePrecision, sphere) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Intersection, SpherePrecision, ::testing::Combine(::testing::Values(0.001f, 3.e5f), ::testing::Values(3.f, 8000.0f, 2.e5f), ::testing::Values(true, false), ::testing::Values("scivis", "pathtracer"))); TEST_P(FromOsprayTesting, test_scenes) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(TestScenesGeometry, FromOsprayTesting, ::testing::Combine(::testing::Values("cornell_box", "gravity_spheres_isosurface", "empty", "random_spheres", "streamlines", "subdivision_cube", "planes", "unstructured_volume_isosurface", "instancing", "nolight", "random_discs", "random_oriented_discs"), ::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values(16))); // INSTANTIATE_TEST_SUITE_P(TestScenesInterpolation, // FromOsprayTesting, // ::testing::Combine(::testing::Values("interpolation_quads_color_fv", // "interpolation_subd_color_fv", // "interpolation_quads_color_vv", // "interpolation_subd_color_vv", // "interpolation_quads_color_u", // "interpolation_subd_color_u", // "interpolation_quads_color_c", // "interpolation_subd_color_c", // "interpolation_quads_tex_fv", // "interpolation_subd_tex_fv", // "interpolation_quads_tex_vv", // "interpolation_subd_tex_vv"), // ::testing::Values("scivis"), // ::testing::Values(1))); TEST_P(Curves, test_scenes) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(TestScenesGeometry, Curves, ::testing::Combine(::testing::Values("bspline", "hermite", "catmull-rom", "linear_deprecated", "linear", "cones", "bezier"), ::testing::Values("scivis", "pathtracer", "ao"))); INSTANTIATE_TEST_SUITE_P(TestScenesClipping, FromOsprayTesting, ::testing::Combine(::testing::Values("clip_with_spheres", "clip_with_boxes", "clip_with_planes", "clip_with_meshes", "clip_with_subdivisions", "clip_with_linear_curves", "clip_with_bspline_curves", "clip_gravity_spheres_volume", "clip_perlin_noise_volumes"), ::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values(16))); TEST_F(ClippingParallel, planes) { PerformRenderTest(); } TEST_P(FromOsprayTestingMaxDepth, test_scenes) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(TestScenesMaxDepth, FromOsprayTestingMaxDepth, ::testing::Combine( ::testing::Values( "cornell_box", "clip_with_spheres", "clip_gravity_spheres_volume"), ::testing::Values("ao"), ::testing::Values(16))); /* TEST_P(FromOsprayTestingVariance, testScenes) { PerformRenderTest(); EXPECT_LE(framebuffer.variance(), 10.0f); } INSTANTIATE_TEST_SUITE_P(TestScenesVariance, FromOsprayTestingVariance, ::testing::Values(std::make_tuple("cornell_box", "pathtracer", 4))); */ TEST_P(FromOsprayTestingLightSamples, testScenes) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(TestScenesLightSamples, FromOsprayTestingLightSamples, ::testing::Combine(::testing::Values("cornell_box", "nolight"), ::testing::Values("pathtracer"), ::testing::Values(1))); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_geometry.h000066400000000000000000000017171464752671100237620ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_fixture.h" namespace OSPRayTestScenes { // Fixture class to test cornercases of intersection precision and epsilon // handling; parametrized with renderer, sphere radius, distance factor, and // whether the sphere is in origin class SpherePrecision : public Base, public ::testing::TestWithParam> { public: SpherePrecision(); void SetUp() override; protected: float dist; float radius; bool move_cam; }; // Fixture class used for testing curves variants class Curves : public Base, public ::testing::TestWithParam> { public: Curves(); void SetUp() override; protected: std::string curveVariant; }; } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_glm_compat.cpp000066400000000000000000000103421464752671100245760ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include // ospray_cpp #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #define OSPRAY_GLM_DEFINITIONS #include "ospray/ospray_cpp/ext/glm.h" // glm extras #include "glm/gtc/matrix_transform.hpp" TEST(glm, TypeCompatibility) { static_assert(sizeof(rkcommon::math::vec2f) == sizeof(glm::vec2), ""); static_assert(sizeof(rkcommon::math::vec3f) == sizeof(glm::vec3), ""); static_assert(sizeof(rkcommon::math::vec4f) == sizeof(glm::vec4), ""); static_assert(sizeof(rkcommon::math::vec2i) == sizeof(glm::ivec2), ""); static_assert(sizeof(rkcommon::math::vec3i) == sizeof(glm::ivec3), ""); static_assert(sizeof(rkcommon::math::vec4i) == sizeof(glm::ivec4), ""); static_assert(sizeof(rkcommon::math::vec2ui) == sizeof(glm::uvec2), ""); static_assert(sizeof(rkcommon::math::vec3ui) == sizeof(glm::uvec3), ""); static_assert(sizeof(rkcommon::math::vec4ui) == sizeof(glm::uvec4), ""); static_assert(sizeof(rkcommon::math::linear2f) == sizeof(glm::mat2x2), ""); static_assert(sizeof(rkcommon::math::linear3f) == sizeof(glm::mat3x3), ""); static_assert(sizeof(rkcommon::math::affine2f) == sizeof(glm::mat3x2), ""); static_assert(sizeof(rkcommon::math::affine3f) == sizeof(glm::mat4x3), ""); // Test vecXf // glm::vec2 glm_vec2(1, 2); rkcommon::math::vec2f rk_vec2f; std::memcpy(&rk_vec2f, &glm_vec2, sizeof(rk_vec2f)); ASSERT_EQ(rk_vec2f.x, 1); ASSERT_EQ(rk_vec2f.y, 2); glm::vec3 glm_vec3(1, 2, 3); rkcommon::math::vec3f rk_vec3f; std::memcpy(&rk_vec3f, &glm_vec3, sizeof(rk_vec3f)); ASSERT_EQ(rk_vec3f.x, 1); ASSERT_EQ(rk_vec3f.y, 2); ASSERT_EQ(rk_vec3f.z, 3); glm::vec4 glm_vec4(1, 2, 3, 4); rkcommon::math::vec4f rk_vec4f; std::memcpy(&rk_vec4f, &glm_vec4, sizeof(rk_vec4f)); ASSERT_EQ(rk_vec4f.x, 1); ASSERT_EQ(rk_vec4f.y, 2); ASSERT_EQ(rk_vec4f.z, 3); ASSERT_EQ(rk_vec4f.w, 4); // Test vecXi // glm::ivec2 glm_ivec2(1, 2); rkcommon::math::vec2i rk_vec2i; std::memcpy(&rk_vec2i, &glm_ivec2, sizeof(rk_vec2i)); ASSERT_EQ(rk_vec2i.x, 1); ASSERT_EQ(rk_vec2i.y, 2); glm::ivec3 glm_ivec3(1, 2, 3); rkcommon::math::vec3i rk_vec3i; std::memcpy(&rk_vec3i, &glm_ivec3, sizeof(rk_vec3i)); ASSERT_EQ(rk_vec3i.x, 1); ASSERT_EQ(rk_vec3i.y, 2); ASSERT_EQ(rk_vec3i.z, 3); glm::ivec4 glm_ivec4(1, 2, 3, 4); rkcommon::math::vec4i rk_vec4i; std::memcpy(&rk_vec4i, &glm_ivec4, sizeof(rk_vec4i)); ASSERT_EQ(rk_vec4i.x, 1); ASSERT_EQ(rk_vec4i.y, 2); ASSERT_EQ(rk_vec4i.z, 3); ASSERT_EQ(rk_vec4i.w, 4); // Test vecXu // glm::uvec2 glm_uvec2(1, 2); rkcommon::math::vec2ui rk_vec2ui; std::memcpy(&rk_vec2ui, &glm_uvec2, sizeof(rk_vec2ui)); ASSERT_EQ(rk_vec2ui.x, 1); ASSERT_EQ(rk_vec2ui.y, 2); glm::uvec3 glm_uvec3(1, 2, 3); rkcommon::math::vec3ui rk_vec3ui; std::memcpy(&rk_vec3ui, &glm_uvec3, sizeof(rk_vec3ui)); ASSERT_EQ(rk_vec3ui.x, 1); ASSERT_EQ(rk_vec3ui.y, 2); ASSERT_EQ(rk_vec3ui.z, 3); glm::uvec4 glm_uvec4(1, 2, 3, 4); rkcommon::math::vec4ui rk_vec4ui; std::memcpy(&rk_vec4ui, &glm_uvec4, sizeof(rk_vec4ui)); ASSERT_EQ(rk_vec4ui.x, 1); ASSERT_EQ(rk_vec4ui.y, 2); ASSERT_EQ(rk_vec4ui.z, 3); ASSERT_EQ(rk_vec4ui.w, 4); // Matrix tests // // linear glm::mat2x2 glm_mat2x2(1.f); rkcommon::math::linear2f rk_linear2f; std::memcpy(&rk_linear2f, &glm_mat2x2, sizeof(rk_linear2f)); ASSERT_EQ(rk_linear2f.vx, rkcommon::math::vec2f(1, 0)); ASSERT_EQ(rk_linear2f.vy, rkcommon::math::vec2f(0, 1)); glm::mat3x3 glm_mat3x3(1.f); rkcommon::math::linear3f rk_linear3f; std::memcpy(&rk_linear3f, &glm_mat3x3, sizeof(rk_linear3f)); ASSERT_EQ(rk_linear3f.vx, rkcommon::math::vec3f(1, 0, 0)); ASSERT_EQ(rk_linear3f.vy, rkcommon::math::vec3f(0, 1, 0)); ASSERT_EQ(rk_linear3f.vz, rkcommon::math::vec3f(0, 0, 1)); // affine glm::mat4x3 glm_mat4x3 = glm::translate(glm::mat4(1.f), glm::vec3(1, 2, 3)); rkcommon::math::affine3f rk_affine3f; std::memcpy(&rk_affine3f, &glm_mat4x3, sizeof(rk_affine3f)); ASSERT_EQ(rk_affine3f.l.vx, rkcommon::math::vec3f(1, 0, 0)); ASSERT_EQ(rk_affine3f.l.vy, rkcommon::math::vec3f(0, 1, 0)); ASSERT_EQ(rk_affine3f.l.vz, rkcommon::math::vec3f(0, 0, 1)); ASSERT_EQ(rk_affine3f.p, rkcommon::math::vec3f(1, 2, 3)); } RenderKit-ospray-85af292/apps/ospTestSuite/test_imageop.cpp000066400000000000000000000047531464752671100241060ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray_testing.h" #include "test_fixture.h" namespace OSPRayTestScenes { class ImageOpBase : public Base { public: ImageOpBase() { samplesPerPixel = 4; } void SetUp() override; protected: std::string imageOpType; cpp::ImageOperation imageOp; }; void ImageOpBase::SetUp() { Base::SetUp(); instances.clear(); auto builder = ospray::testing::newBuilder("random_discs"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); camera.setParam("position", vec3f(0.f, 0.f, -2.5f)); imageOp = cpp::ImageOperation(imageOpType); frames = 1; framebuffer = cpp::FrameBuffer(imgSize.x, imgSize.y, frameBufferFormat, OSP_FB_COLOR | OSP_FB_ALBEDO | OSP_FB_NORMAL); framebuffer.setParam("imageOperation", cpp::CopiedData(imageOp)); framebuffer.commit(); } #ifdef OSPRAY_MODULE_DENOISER class DenoiserOp : public ImageOpBase, public ::testing::TestWithParam< std::tuple> { public: DenoiserOp() { ospLoadModule("denoiser"); rendererType = "pathtracer"; imageOpType = "denoiser"; } void SetUp() override { ImageOpBase::SetUp(); auto params = GetParam(); imageOp.setParam("denoiseAlpha", std::get<0>(params)); imageOp.setParam("quality", std::get<1>(params)); imageOp.commit(); } }; #endif class ImageOp : public ImageOpBase, public ::testing::TestWithParam< std::tuple> { public: ImageOp() { auto params = GetParam(); imageOpType = std::get<0>(params); rendererType = std::get<1>(params); } void SetUp() override { ImageOpBase::SetUp(); } }; // Test Instantiations ////////////////////////////////////////////////////// #ifdef OSPRAY_MODULE_DENOISER TEST_P(DenoiserOp, DenoiserOp) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(DenoiserOp, DenoiserOp, ::testing::Combine(::testing::Bool(), ::testing::Values(OSP_DENOISER_QUALITY_LOW, OSP_DENOISER_QUALITY_MEDIUM, OSP_DENOISER_QUALITY_HIGH))); #endif TEST_P(ImageOp, ImageOp) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P( DebugOp, ImageOp, ::testing::Values(std::make_tuple("debug", "scivis"))); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_interpolation.cpp000066400000000000000000000067701464752671100253550ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ArcballCamera.h" #include "ospray_testing.h" #include "rkcommon/utility/random.h" #include "test_fixture.h" extern OSPRayEnvironment *ospEnv; namespace OSPRayTestScenes { class Interpolation : public Base, public ::testing::TestWithParam> { public: Interpolation(); void SetUp() override; void PerformRenderTest() override; protected: OSPFrameBufferChannel idBuffer{OSP_FB_COLOR}; bool useSubd{false}; unsigned int attribute{0}; unsigned int interpolation{0}; }; Interpolation::Interpolation() { samplesPerPixel = 2; rendererType = "scivis"; auto params = GetParam(); useSubd = std::get<0>(params); attribute = std::get<1>(params); interpolation = std::get<2>(params); if (attribute == 2) idBuffer = OSP_FB_NORMAL; } void Interpolation::SetUp() { Base::SetUp(); framebuffer = cpp::FrameBuffer(imgSize.x, imgSize.y, frameBufferFormat, idBuffer); instances.clear(); auto builder = ospray::testing::newBuilder("interpolation"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::setParam(builder, "useSubd", useSubd); ospray::testing::setParam(builder, "attribute", attribute); ospray::testing::setParam(builder, "interpolation", interpolation); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); } inline uint8_t to_uc(const float f) { return 255.f * clamp(f, 0.f, 1.0f); } inline uint32_t to_rgba8(const vec3f c) { return to_uc(c.x) | (to_uc(c.y) << 8) | (to_uc(c.z) << 16) | 0xff000000; } void Interpolation::PerformRenderTest() { if (!instances.empty()) world.setParam("instance", cpp::CopiedData(instances)); world.commit(); ArcballCamera arcballCamera(world.getBounds(), imgSize); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); camera.commit(); renderer.commit(); framebuffer.resetAccumulation(); RenderFrame(); auto *framebuffer_data = (uint32_t *)framebuffer.map(idBuffer); std::vector framebufferData(imgSize.product()); for (int i = 0; i < imgSize.product(); i++) { if (attribute == 2) { // normals const vec3f normal = ((vec3f *)framebuffer_data)[i]; framebufferData[i] = to_rgba8(0.5f * normal + 0.5f); } else framebufferData[i] = framebuffer_data[i]; } framebuffer.unmap(framebuffer_data); if (ospEnv->GetDumpImg()) { EXPECT_EQ( imageTool->saveTestImage(framebufferData.data()), OsprayStatus::Ok); } else { EXPECT_EQ(imageTool->compareImgWithBaseline(framebufferData.data()), OsprayStatus::Ok); } } // Test Instantiations ////////////////////////////////////////////////////// TEST_P(Interpolation, Interpolation) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Color, Interpolation, ::testing::Combine(::testing::Bool(), ::testing::Values(0), ::testing::Values(0, 1, 2, 3))); INSTANTIATE_TEST_SUITE_P(Texcoord, Interpolation, ::testing::Combine( ::testing::Bool(), ::testing::Values(1), ::testing::Values(0, 1))); INSTANTIATE_TEST_SUITE_P(Normal, Interpolation, ::testing::Combine(::testing::Values(false), ::testing::Values(2), ::testing::Values(0, 1))); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_light.cpp000066400000000000000000000505451464752671100235740ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_light.h" #include "ospray_testing.h" 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() { Base::SetUp(); // set common renderer parameter if (rendererType == "pathtracer") renderer.setParam("maxPathLength", 1); if (rendererType == "scivis") { renderer.setParam("shadows", true); renderer.setParam("visibleLights", true); } // build cornell box scene auto builder = ospray::testing::newBuilder("cornell_box"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::commit(builder); auto group = ospray::testing::buildGroup(builder); AddInstance(cpp::Instance(group)); ospray::testing::release(builder); // position camera camera.setParam("position", vec3f(0, 0, -2.4641)); } void LightTest::AddInstancedLightWithMB( cpp::Light light, const affine3f &xfm1, const affine3f &xfm2) { 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); AddInstance(instance); } AmbientLight::AmbientLight() { rendererType = GetParam(); } void AmbientLight::SetUp() { LightTest::SetUp(); cpp::Light ambient = ospNewLight("ambient"); ambient.setParam("intensity", 0.5f); AddLight(ambient); if (rendererType == "scivis") renderer.setParam("aoSamples", 1); } DistantLight::DistantLight() { auto params = GetParam(); direction = std::get<0>(params); rendererType = std::get<1>(params); motionBlur = std::get<2>(params); } void DistantLight::SetUp() { LightTest::SetUp(); cpp::Light distant("distant"); distant.setParam("direction", xfmVector(xfm, direction)); distant.setParam("color", vec3f(1.0f, 0.75f, 0.25f)); distant.setParam("angularDiameter", 1.0f); AddInstancedLightWithRotateMB(distant); } GeometricLight::GeometricLight() { rendererType = "pathtracer"; auto params = GetParam(); size = std::get<0>(params); useMaterialList = std::get<1>(params); textureMode = std::get<2>(params); motionBlur = std::get<3>(params); } void GeometricLight::SetUp() { LightTest::SetUp(); const float area = size * size; const float halfSize = 0.5f * size; std::vector lightVertices = {{-halfSize, 0.98f, -halfSize}, {halfSize, 0.98f, -halfSize}, {halfSize, 0.98f, halfSize}, {-halfSize, 0.98f, halfSize}}; std::vector lightIndices = {{0, 1, 2, 3}}; cpp::Geometry lightMesh("mesh"); lightMesh.setParam("index", cpp::CopiedData(lightIndices)); if (motionBlur == 2) { // deformation for (vec3f &p : lightVertices) p.x -= 0.5f; std::vector mposdata; mposdata.push_back(cpp::CopiedData(lightVertices)); for (vec3f &p : lightVertices) p.x += 1.0f; mposdata.push_back(cpp::CopiedData(lightVertices)); lightMesh.setParam("motion.vertex.position", cpp::CopiedData(mposdata)); } else lightMesh.setParam("vertex.position", cpp::CopiedData(lightVertices)); if (textureMode == 2) { std::array data = {vec2f(0.3f, 0.4f), vec2f(1.3f, 0.4f), vec2f(1.3f, 1.4f), vec2f(0.3f, 1.4f)}; lightMesh.setParam("vertex.texcoord", cpp::CopiedData(data)); } lightMesh.commit(); cpp::GeometricModel lightModel(lightMesh); cpp::Material lightMaterial("luminous"); lightMaterial.setParam("intensity", 10.f / area); if (textureMode) { cpp::Texture tex("texture2d"); std::array data = {vec3f(0.f, 0.f, 0.f), vec3f(0.78f, 0.551f, 0.183f), vec3f(1.f, 1.f, 1.f), vec3f(0.f, 0.f, 1.f)}; cpp::CopiedData texData(data.data(), vec2ul(2, 2)); tex.setParam("format", OSP_TEXTURE_RGB32F); tex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); tex.setParam("data", texData); tex.commit(); lightMaterial.setParam("map_color", tex); if (textureMode == 2) lightMaterial.setParam("map_color.translation", vec2f(0.3f, 0.4f)); } else lightMaterial.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); lightMaterial.commit(); if (useMaterialList) { std::vector materials{lightMaterial}; renderer.setParam("material", cpp::CopiedData(materials)); uint32_t materialIndex = 0; lightModel.setParam("material", materialIndex); } else { lightModel.setParam("material", lightMaterial); } if (motionBlur == 1) { // instance lightModel.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(lightModel)); group.commit(); cpp::Instance instance(group); std::vector xfms; xfms.push_back(affine3f::translate(vec3f(-0.5, 0, 0))); xfms.push_back(affine3f::translate(vec3f(0.5, 0, 0))); instance.setParam("motion.transform", cpp::CopiedData(xfms)); AddInstance(instance); } else AddModel(lightModel); if (motionBlur) camera.setParam("shutter", range1f(0, 1)); } PhotometricLight::PhotometricLight() { auto params = GetParam(); lightType = std::get<0>(params); size = std::get<1>(params); rendererType = std::get<2>(params); // area lights need a minimum size if (lightType == "quad") size = std::max(0.01f, size); } void PhotometricLight::SetUp() { LightTest::SetUp(); const vec3f pos1 = xfmPoint(xfm, vec3f(-0.6f, 0.8f, -0.5f)); const vec3f pos2 = xfmPoint(xfm, vec3f(0.3f, 0.6f, 0.f)); const vec3f dir = xfmVector(xfm, vec3f(0.0f, -1.0f, 0.0f)); const vec3f edge1 = xfmVector(xfm, vec3f(1.0f, 0.0f, 0.0f)); const vec3f edge2 = xfmVector(xfm, vec3f(0.0f, 0.0f, 1.0f)); cpp::Light light1d(lightType); light1d.setParam("intensity", 5.f); light1d.setParam("intensityQuantity", OSP_INTENSITY_QUANTITY_SCALE); float lid1d[] = {2.5f, 0.4f, 0.2f, 0.1f, 0.03f, 0.01f, 0.01f}; light1d.setParam("intensityDistribution", cpp::CopiedData(lid1d, 7)); if (lightType == "spot") { light1d.setParam("position", pos1); light1d.setParam("direction", dir); light1d.setParam("openingAngle", 360.f); light1d.setParam("penumbraAngle", 0.f); light1d.setParam("radius", size); } else if (lightType == "quad") { light1d.setParam("position", pos1 - size * edge1 - size * edge2); light1d.setParam("edge1", 2.0f * size * edge1); light1d.setParam("edge2", 2.0f * size * edge2); } else if (lightType == "sphere") { light1d.setParam("position", pos1); light1d.setParam("radius", size); light1d.setParam("direction", dir); } light1d.commit(); cpp::Light light2d(lightType); light2d.setParam("intensity", 1.f); light2d.setParam("intensityQuantity", OSP_INTENSITY_QUANTITY_SCALE); float lid2d[60] = { 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", xfmVector(xfm, vec3f(1.0f, 0.0f, 0.0f))); if (lightType == "spot") { light2d.setParam("position", pos2); light2d.setParam("direction", dir); light2d.setParam("openingAngle", 270.f); light2d.setParam("penumbraAngle", 10.f); light2d.setParam("radius", size); } else if (lightType == "quad") { light2d.setParam("position", pos2 - size * edge1 - size * edge2); light2d.setParam("edge1", 2.0f * size * edge1); light2d.setParam("edge2", 2.0f * size * edge2); } else if (lightType == "sphere") { light2d.setParam("position", pos2); light2d.setParam("radius", size); light2d.setParam("direction", dir); } 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() { auto params = GetParam(); size = std::get<0>(params); rendererType = std::get<1>(params); intensityQuantity = std::get<2>(params); motionBlur = std::get<3>(params); } void QuadLight::SetUp() { LightTest::SetUp(); cpp::Light light("quad"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 10.f); light.setParam("intensityQuantity", intensityQuantity); 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() { auto params = GetParam(); radius = std::get<0>(params); rendererType = std::get<1>(params); intensityQuantity = std::get<2>(params); motionBlur = std::get<3>(params); } void SphereLight::SetUp() { LightTest::SetUp(); cpp::Light light("sphere"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 2.5f); light.setParam("intensityQuantity", intensityQuantity); light.setParam("position", xfmPoint(xfm, vec3f(0.0f, 0.48f, 0.0f))); light.setParam("radius", radius); AddInstancedLightWithTranslateMB(light); } SpotLight::SpotLight() { auto params = GetParam(); innerOuterRadius = std::get<0>(params); rendererType = std::get<1>(params); intensityQuantity = std::get<2>(params); motionBlur = std::get<3>(params); } void SpotLight::SetUp() { LightTest::SetUp(); cpp::Light light("spot"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 10.f); light.setParam("intensityQuantity", intensityQuantity); 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]); AddInstancedLightWithTranslateMB(light); } HDRILight::HDRILight() { auto params = GetParam(); rendererType = std::get<0>(params); motionBlur = std::get<1>(params); } void HDRILight::SetUp() { Base::SetUp(); // set common renderer parameter if (rendererType == "pathtracer") renderer.setParam("maxPathLength", 1); if (rendererType == "scivis") { renderer.setParam("shadows", true); renderer.setParam("visibleLights", true); } // create sphere cpp::Group group; { cpp::Geometry sphere("sphere"); sphere.setParam("sphere.position", cpp::CopiedData(vec3f(0.f))); sphere.setParam("radius", 1.f); sphere.commit(); cpp::GeometricModel model(sphere); cpp::Material material("obj"); material.commit(); model.setParam("material", material); model.commit(); group.setParam("geometry", cpp::CopiedData(model)); group.commit(); } AddInstance(cpp::Instance(group)); // position camera camera.setParam("position", vec3f(0.f, 0.f, -3.f)); // prepare environment texture cpp::Texture envTex("texture2d"); { std::array data = {vec3f(0.f, 1.f, 1.f), vec3f(1.f, 0.f, 1.f), vec3f(1.f, 1.f, 0.f), vec3f(1.f, 1.f, 1.f), vec3f(0.f, 1.f, 1.f), vec3f(1.f, 0.f, 1.f), vec3f(1.f, 1.f, 0.f), vec3f(1.f, 1.f, 1.f), vec3f(1.f, 0.f, 0.f), vec3f(0.f, 1.f, 0.f), vec3f(0.f, 0.f, 1.f), vec3f(0.f, 0.f, 0.f), vec3f(1.f, 0.f, 0.f), vec3f(0.f, 1.f, 0.f), vec3f(0.f, 0.f, 1.f), vec3f(0.f, 0.f, 0.f)}; cpp::CopiedData texData(data.data(), vec2ul(4, 4)); envTex.setParam("format", OSP_TEXTURE_RGB32F); envTex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); envTex.setParam("data", texData); envTex.commit(); } // prepare light cpp::Light light("hdri"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); 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); AddInstancedLightWithRotateMB(light); renderer.setParam("backgroundColor", vec4f(0.f, 0.f, 0.f, 1.0f)); } SunSky::SunSky() { rendererType = "pathtracer"; samplesPerPixel = 1; auto params = GetParam(); motionBlur = std::get<5>(params); } void SunSky::SetUp() { 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)); } // Test Instantiations ////////////////////////////////////////////////////// // Ambient Light TEST_P(AmbientLight, parameter) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P( Light, AmbientLight, ::testing::Values("scivis", "pathtracer")); // Distant Light TEST_P(DistantLight, parameter) { PerformRenderTest(); } 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(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) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Light, GeometricLight, ::testing::Combine(::testing::Values(0.2f, 0.4f), ::testing::Bool(), ::testing::Values(0), ::testing::Values(0))); INSTANTIATE_TEST_SUITE_P(LightMotionBlur, GeometricLight, ::testing::Combine(::testing::Values(0.2f), ::testing::Values(false), ::testing::Values(0), ::testing::Values(1, 2))); INSTANTIATE_TEST_SUITE_P(LightTexture, GeometricLight, ::testing::Combine(::testing::Values(0.5f), ::testing::Values(false), ::testing::Values(1, 2), ::testing::Values(0))); // Quad Light TEST_P(QuadLight, parameter) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Light, QuadLight, ::testing::Combine(::testing::Values(0.2f, 0.4f), ::testing::Values("scivis", "pathtracer"), ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY), ::testing::Values(false))); 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, CylinderLight, ::testing::Combine(::testing::Values(0.02f, 0.15f), ::testing::Values("scivis", "pathtracer"), ::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) { PerformRenderTest(); } 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(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) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Light, SpotLight, ::testing::Combine(::testing::Values(vec2f(0.0f, 0.0f), vec2f(0.0f, 0.2f), vec2f(0.0f, 0.4f), vec2f(0.2f, 0.4f), vec2f(0.7f, 0.8f)), ::testing::Values("scivis", "pathtracer"), ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY), ::testing::Values(false))); INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, SpotLight, ::testing::Combine( ::testing::Values( 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), ::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("spot", "quad", "sphere"), ::testing::Values(0.0f, 0.1f), ::testing::Values("scivis", "pathtracer"))); // HDRI Light TEST_P(HDRILight, parameter) { PerformRenderTest(); } 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 RenderKit-ospray-85af292/apps/ospTestSuite/test_light.h000066400000000000000000000102731464752671100232330ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_fixture.h" namespace OSPRayTestScenes { class LightTest : public Base { public: LightTest(); 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 : public LightTest, public ::testing::TestWithParam { public: AmbientLight(); void SetUp() override; }; class DistantLight : public LightTest, public ::testing::TestWithParam> { public: DistantLight(); void SetUp() override; private: vec3f direction{0.f, 0.f, 1.f}; }; class GeometricLight : public LightTest, public ::testing::TestWithParam> { public: GeometricLight(); void SetUp() override; private: float size{0.2}; bool useMaterialList{true}; int textureMode{0}; int motionBlur{0}; }; class PhotometricLight : public LightTest, public ::testing::TestWithParam> { public: PhotometricLight(); void SetUp() override; private: std::string lightType; float size{0.0}; }; class QuadLight : public LightTest, public ::testing::TestWithParam> { public: QuadLight(); void SetUp() override; private: float size{0.2}; 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> { public: SphereLight(); void SetUp() override; private: float radius{0.0}; OSPIntensityQuantity intensityQuantity{OSP_INTENSITY_QUANTITY_UNKNOWN}; }; class SpotLight : public LightTest, public ::testing::TestWithParam> { public: SpotLight(); void SetUp() override; private: vec2f innerOuterRadius{0.0, 0.2}; OSPIntensityQuantity intensityQuantity{OSP_INTENSITY_QUANTITY_UNKNOWN}; }; class HDRILight : public LightTest, public ::testing::TestWithParam< std::tuple> { public: HDRILight(); void SetUp() override; }; class SunSky : public LightTest, public ::testing::TestWithParam> { public: SunSky(); void SetUp() override; }; } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_motionblur.cpp000066400000000000000000000261061464752671100246530ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray_testing.h" #include "test_fixture.h" namespace OSPRayTestScenes { class MotionBlurBoxes : public Base, 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() { 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() { 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( "box", cpp::CopiedData(box3f(vec3f(-0.5f), vec3f(0.5f)))); boxGeometry.commit(); cpp::GeometricModel model(boxGeometry); cpp::Material material("obj"); material.setParam("kd", vec3f(0.8f, 0.1, 0.4)); material.setParam("ks", vec3f(0.2f)); material.setParam("ns", 99.f); material.commit(); model.setParam("material", material); model.commit(); cpp::Volume volume("structuredRegular"); std::vector volData(8); std::generate( volData.begin(), volData.end(), [n = 0]() mutable { return n++; }); volume.setParam("data", cpp::CopiedData(volData.data(), vec3ul(2))); volume.setParam("gridOrigin", vec3f(-0.5, 0.5, -0.5)); volume.setParam("filter", OSP_VOLUME_FILTER_NEAREST); volume.commit(); cpp::TransferFunction transferFun("piecewiseLinear"); transferFun.setParam("value", range1f(0.f, 7.f)); std::vector colors = {vec3f(1.0f, 0.5f, 0.5f), vec3f(0.5f, 1.0f, 0.5f), vec3f(0.5f, 1.0f, 1.0f), vec3f(0.5f, 0.5f, 1.0f)}; std::vector opacities = {0.1f, 1.0f}; transferFun.setParam("color", cpp::CopiedData(colors)); transferFun.setParam("opacity", cpp::CopiedData(opacities)); transferFun.commit(); cpp::VolumetricModel volModel(volume); volModel.setParam("transferFunction", transferFun); volModel.setParam("densityScale", 99.0f); volModel.commit(); cpp::Geometry sphereGeometry("sphere"); sphereGeometry.setParam( "sphere.position", cpp::CopiedData(vec3f(0.3f, 0.6f, -0.2f))); sphereGeometry.setParam("radius", 0.6f); sphereGeometry.commit(); cpp::GeometricModel clipModel(sphereGeometry); clipModel.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.setParam("volume", cpp::CopiedData(volModel)); group.setParam("clippingGeometry", cpp::CopiedData(clipModel)); group.commit(); { // static original cpp::Instance instance(group); instance.setParam("transform", affine3f::rotate(vec3f(1, 1, 0.1), -0.4)); AddInstance(instance); } { // linear cpp::Instance instance(group); std::vector xfms; xfms.push_back(affine3f::translate(vec3f(3, -3, 0))); xfms.push_back(affine3f::translate(vec3f(2.5, -3, 0))); xfms.push_back(affine3f::translate(vec3f(2.2, -1, 0))); instance.setParam("motion.transform", cpp::CopiedData(xfms)); AddInstance(instance); } { // linear, time cpp::Instance instance(group); std::vector xfms; xfms.push_back(affine3f::translate(vec3f(5, -3, 0))); xfms.push_back(affine3f::translate(vec3f(4.5, -3, 0))); xfms.push_back(affine3f::translate(vec3f(4.2, -1, 0))); instance.setParam("motion.transform", cpp::CopiedData(xfms)); instance.setParam("time", range1f(-2, 0.8)); AddInstance(instance); } { // scale cpp::Instance instance(group); std::vector xfms; xfms.push_back(affine3f::translate(vec3f(1, 2, 0))); xfms.push_back(affine3f::translate(vec3f(1, 2, 0)) * affine3f::scale(vec3f(1.8, 0.9, 1))); instance.setParam("motion.transform", cpp::CopiedData(xfms)); AddInstance(instance); } { // rot cpp::Instance instance(group); std::vector xfms; xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 0.8)); xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 1.2)); xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 1.6)); instance.setParam("motion.transform", cpp::CopiedData(xfms)); 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); } { // deformation std::vector pos = {vec3f(-3.0f, -3.5f, -0.5f), vec3f(-2.0f, -3.5f, -0.5f), vec3f(-2.0f, -2.5f, -0.5f), vec3f(-3.0f, -2.5f, -0.5f)}; std::vector nor(4, vec3f(0.0f, 0.0f, -1.0f)); std::vector mposdata; mposdata.push_back(cpp::CopiedData(pos)); std::vector mnordata; mnordata.push_back(cpp::CopiedData(nor)); for (vec3f &p : pos) p.x -= 1.5f; mposdata.push_back(cpp::CopiedData(pos)); for (vec3f &n : nor) n.x += 1.0f; mnordata.push_back(cpp::CopiedData(nor)); for (vec3f &p : pos) p = xfmPoint(quatf::rotate(vec3f(.4f, 0.f, 1.f), -.1f), p); mposdata.push_back(cpp::CopiedData(pos)); for (vec3f &n : nor) n.x -= 0.5f; mnordata.push_back(cpp::CopiedData(nor)); cpp::CopiedData mpos(mposdata); cpp::CopiedData mnor(mnordata); { // triangle cpp::Geometry geom("mesh"); geom.setParam("motion.vertex.position", mpos); geom.setParam("motion.vertex.normal", mnor); geom.setParam("index", cpp::CopiedData(vec3ui(0, 1, 2))); geom.commit(); cpp::GeometricModel model(geom); model.setParam("material", material); AddModel(model); } { // quad cpp::Geometry geom("mesh"); geom.setParam("motion.vertex.position", mpos); geom.setParam("motion.vertex.normal", mnor); geom.setParam("index", cpp::CopiedData(vec4ui(0, 1, 2, 3))); geom.commit(); cpp::GeometricModel model(geom); model.setParam("material", material); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); cpp::Instance instance(group); instance.setParam("transform", affine3f::translate(vec3f(0, 1.5, 0))); AddInstance(instance); } } cpp::Light distant("distant"); distant.setParam("intensity", 3.0f); distant.setParam("direction", vec3f(0.3f, -4.0f, 2.8f)); distant.setParam("color", vec3f(1.0f, 0.5f, 0.5f)); distant.setParam("angularDiameter", 1.0f); AddLight(distant); cpp::Light ambient("ambient"); ambient.setParam("visible", false); ambient.setParam("intensity", 0.1f); AddLight(ambient); } // Test camera MB (also in combination with stereo) //////////////////////////// class MotionCamera : public Base, public ::testing::TestWithParam< std::tuple> { public: MotionCamera(); void SetUp() override; protected: std::string cameraType; vec3f pos{0.0f, 0.0f, -0.5f}; OSPStereoMode stereoMode{OSP_STEREO_NONE}; OSPShutterType shutterType{OSP_SHUTTER_GLOBAL}; }; MotionCamera::MotionCamera() { rendererType = "pathtracer"; samplesPerPixel = 64; auto params = GetParam(); cameraType = std::get<0>(params); stereoMode = std::get<1>(params); shutterType = std::get<2>(params); } void MotionCamera::SetUp() { Base::SetUp(); instances.clear(); auto builder = ospray::testing::newBuilder("cornell_box"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); camera = cpp::Camera(cameraType); if (cameraType != "panoramic") { pos.z = -2.f; camera.setParam("aspect", imgSize.x / (float)imgSize.y); } camera.setParam("position", pos); if (cameraType == "orthographic") camera.setParam("height", 2.0f); else camera.setParam("stereoMode", stereoMode); std::vector xfms; xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 0.1)); 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.setParam("shutterType", shutterType); } // Test Instantiations ////////////////////////////////////////////////////// TEST_P(MotionBlurBoxes, instance_mb) { PerformRenderTest(); } 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) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Camera, MotionCamera, ::testing::Combine(::testing::Values("perspective", "panoramic"), ::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, 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 RenderKit-ospray-85af292/apps/ospTestSuite/test_sharedusm_data.cpp000066400000000000000000000070131464752671100254410ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef SYCL_LANGUAGE_VERSION #include #include #include #include #include "test_fixture.h" extern OSPRayEnvironment *ospEnv; #include "sycl/sycl.hpp" namespace OSPRayTestScenes { // Fixture class for a unit test of gpu capable, data sharing class TestUSMSharing : public Base, public ::testing::TestWithParam { public: TestUSMSharing(); ~TestUSMSharing(); void SetUp() override; protected: std::string memoryType; // host, shared, device private: std::vector voxels; float *deviceVoxels = nullptr; }; TestUSMSharing::TestUSMSharing() { memoryType = GetParam(); } TestUSMSharing::~TestUSMSharing() { sycl::queue *appsSyclQueue = ospEnv->GetAppsSyclQueue(); if (appsSyclQueue) free(deviceVoxels, *appsSyclQueue); } void TestUSMSharing::SetUp() { Base::SetUp(); vec3i dims{100, 100, 100}; size_t numVoxels = dims.long_product(); voxels = std::vector(numVoxels); for (int x = 0; x < dims.x; ++x) { double dx = (double)x / (double)dims.x - 0.5; for (int y = 0; y < dims.y; ++y) { double dy = (double)y / (double)dims.y - 0.5; for (int z = 0; z < dims.z; ++z) { double dz = (double)z / (double)dims.z - 0.5; voxels[x * dims.y * dims.z + y * dims.z + z] = 1.0 - sqrt(dx * dx + dy * dy + dz * dz); } } } deviceVoxels = voxels.data(); sycl::queue *appsSyclQueue = ospEnv->GetAppsSyclQueue(); if (appsSyclQueue) { if (memoryType == "host") { deviceVoxels = sycl::malloc_host(numVoxels, *appsSyclQueue); } else if (memoryType == "device") { deviceVoxels = sycl::malloc_device(numVoxels, *appsSyclQueue); } else { deviceVoxels = sycl::malloc_shared(numVoxels, *appsSyclQueue); } appsSyclQueue->memcpy( deviceVoxels, voxels.data(), numVoxels * sizeof(float)); appsSyclQueue->wait(); } // create and setup camera camera.setParam("position", vec3f(200.f, 50.f, 50.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); camera.setParam("direction", vec3f(-1.f, 0.f, 0.f)); // create and setup model and mesh ospray::cpp::Volume volume("structuredRegular"); volume.setParam("data", cpp::SharedData(deviceVoxels, dims)); volume.commit(); ospray::cpp::TransferFunction tf("piecewiseLinear"); std::vector color = {vec3f(0.5f, 0.0f, 0.0f), vec3f(0.0f, 0.5f, 0.0f), vec3f(0.0f, 0.0f, 1.0f)}; std::vector opacity = {0.05f, 0.0f, 0.1f, 0.0f, 0.2f, 0.0f, 1.0f}; tf.setParam("value", box1f(0.14f, 1.0f)); tf.setParam("color", ospray::cpp::CopiedData(color)); tf.setParam("opacity", ospray::cpp::CopiedData(opacity)); tf.commit(); ospray::cpp::VolumetricModel vm(volume); vm.setParam("transferFunction", tf); vm.commit(); AddModel(vm); cpp::Light distant("distant"); distant.setParam("intensity", 3.0f); distant.setParam("direction", vec3f(0.3f, -4.0f, 0.8f)); distant.setParam("color", vec3f(1.0f, 0.5f, 0.5f)); distant.setParam("angularDiameter", 1.0f); AddLight(distant); cpp::Light ambient = ospNewLight("ambient"); ambient.setParam("intensity", 0.1f); AddLight(ambient); } // Test Instantiations ////////////////////////////////////////////////////// TEST_P(TestUSMSharing, structured_regular) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P( SharedData, TestUSMSharing, ::testing::Values("host", "shared", "device")); } // namespace OSPRayTestScenes #endif RenderKit-ospray-85af292/apps/ospTestSuite/test_tools.cpp000066400000000000000000000202411464752671100236130ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #include "test_tools.h" #include #include "rkcommon/utility/SaveImage.h" extern OSPRayEnvironment *ospEnv; OSPImageTools::OSPImageTools( vec2i imgSize, std::string testName, OSPFrameBufferFormat frameBufferFormat) : size(imgSize), imgName(testName) { switch (frameBufferFormat) { case OSP_FB_RGBA8: fileFormat = ".ppm"; break; case OSP_FB_SRGBA: fileFormat = ".png"; break; case OSP_FB_RGBA32F: fileFormat = ".pfm"; break; default: fileFormat = ".err"; break; } } OsprayStatus OSPImageTools::writePNG( std::string fileName, const uint32_t *pixel) { stbi_flip_vertically_on_write(true); int retCode = stbi_write_png( fileName.c_str(), size.x, size.y, ImgType::RGBA, (const void *)pixel, 0); if (!retCode) { std::cerr << "Failed to save image: " << fileName << std::endl; return OsprayStatus::Fail; } return OsprayStatus::Ok; } OsprayStatus OSPImageTools::writeHDR(std::string fileName, const float *pixel) { stbi_flip_vertically_on_write(true); int retCode = stbi_write_hdr(fileName.c_str(), size.x, size.y, ImgType::RGBA, pixel); if (!retCode) { std::cerr << "Failed to save image: " << fileName << std::endl; return OsprayStatus::Fail; } return OsprayStatus::Ok; } // helper function to write the rendered image OsprayStatus OSPImageTools::writeImg(std::string fileName, const void *pixel) { OsprayStatus writeErr = OsprayStatus::Error; fileName += GetFileFormat(); if (GetFileFormat() == ".ppm") { rkcommon::utility::writePPM( fileName, size.x, size.y, (const uint32_t *)pixel); writeErr = OsprayStatus::Ok; } else if (GetFileFormat() == ".png") { writeErr = writePNG(fileName, (const uint32_t *)pixel); } else if (GetFileFormat() == ".hdr") { writeErr = writeHDR(fileName, (const float *)pixel); } else if (GetFileFormat() == ".pfm") { try { rkcommon::utility::writePFM(fileName, size.x, size.y, (const vec4f *)pixel); writeErr = OsprayStatus::Ok; } catch (...) { writeErr = OsprayStatus::Fail; } } else { std::cerr << "Unsupported file format" << std::endl; writeErr = OsprayStatus::Error; } return writeErr; } OsprayStatus OSPImageTools::verifyBaselineImage(const int sizeX, const int sizeY, const void *baselineImage, const std::string &baselineName) { // Check if baseline image is suitable if (!baselineImage) { std::cerr << "Failed to load image: " << baselineName << std::endl; return OsprayStatus::Fail; } else if (sizeX != size.x || sizeY != size.y) { std::cerr << "Wrong image loaded for: " << baselineName << std::endl; return OsprayStatus::Fail; } return OsprayStatus::Ok; } vec4f OSPImageTools::getAveragedPixel(const vec4f *image, vec2i pixelIndex, const rkcommon::index_sequence_2D &imageIndices) { vec4f p(0.f); unsigned int count = 0; rkcommon::index_sequence_2D indices(vec2i(5)); for (vec2i id : indices) { vec2i pid = pixelIndex + (id - vec2i(2)); if ((reduce_min(pid) < 0) || (reduce_min(size - pid) < 1)) continue; p += image[imageIndices.flatten(pid)]; count++; } return p / float(count); } // compare the baseline image with the values form the framebuffer template OsprayStatus OSPImageTools::compareImgWithBaselineTmpl(const T *testImage, const T *baselineImage, const std::string &baselineName, const float pixelConversionFactor) { bool notPerfect = false; double totalError = 0.; rkcommon::index_sequence_2D imageIndices(size); std::vector diffAbsImage(imageIndices.total_indices()); { // Prepare temporary diff image with floats std::vector diffImage(imageIndices.total_indices()); for (vec2i i : imageIndices) { const unsigned int pixelIndex = imageIndices.flatten(i); const vec4f baselineValue = baselineImage[pixelIndex]; const vec4f renderedValue = testImage[pixelIndex]; diffImage[pixelIndex] = baselineValue - renderedValue; } for (vec2i i : imageIndices) { const unsigned int pixelIndex = imageIndices.flatten(i); const T diffValue = abs(diffImage[pixelIndex]); const vec4f diffAvgValue = abs(getAveragedPixel(diffImage.data(), i, imageIndices)); // Only count errors if above specified threshold, this removes blurred // noise const float pixelError = reduce_add(diffAvgValue) * pixelConversionFactor; if (pixelError > pixelThreshold) totalError += pixelError; // Not a perfect match if any difference detected notPerfect = notPerfect || reduce_add(diffValue); // Set values for output diff image diffAbsImage[pixelIndex] = diffValue; diffAbsImage[pixelIndex].w = std::numeric_limits::max(); } } if (notPerfect) std::cerr << "[ WARNING ] " << baselineName << " is not pixel perfect" << std::endl; double meanError = totalError / double(4 * size.x * size.y); if (totalError) { std::cerr << "[ STATISTIC] Total/mean error: " << totalError << "/" << std::fixed << std::setprecision(3) << meanError << std::endl; } bool failed = meanError > errorRate; if (failed) { writeImg( ospEnv->GetFailedDir() + "/" + imgName + "_baseline", baselineImage); writeImg(ospEnv->GetFailedDir() + "/" + imgName + "_rendered", testImage); writeImg( ospEnv->GetFailedDir() + "/" + imgName + "_diff", diffAbsImage.data()); } if (failed) return OsprayStatus::Fail; else return OsprayStatus::Ok; } OsprayStatus OSPImageTools::saveTestImage(const void *pixel) { return writeImg(ospEnv->GetBaselineDir() + "/" + imgName, pixel); } vec4f *loadPF4(std::string fileName, int &sizeX, int &sizeY) { std::ifstream ifs; ifs.open(fileName, std::ifstream::in | std::ifstream::binary); if (!ifs.good()) return nullptr; std::string header; std::getline(ifs, header); if (!ifs.good() || header != "PF4") return nullptr; ifs >> sizeX >> sizeY; std::getline(ifs, header); // eat newline after size information if (!ifs.good()) return nullptr; std::getline(ifs, header); if (!ifs.good() || header != "-1.0") return nullptr; size_t sz = sizeX * sizeY; vec4f *img = new vec4f[sz]; ifs.read((char*)img, sz * sizeof(float) * 4); if (!ifs.good()) return nullptr; ifs.close(); return img; } // compare the baseline image with the values form the framebuffer OsprayStatus OSPImageTools::compareImgWithBaseline(const void *testImage) { std::string baselineName = ospEnv->GetBaselineDir() + "/" + imgName + GetFileFormat(); stbi_set_flip_vertically_on_load(true); int dataX, dataY, dataN; OsprayStatus compErr = OsprayStatus::Error; if (GetFileFormat() == ".png") { vec4uc *baselineImage = (vec4uc *)stbi_load( baselineName.c_str(), &dataX, &dataY, &dataN, ImgType::RGBA); compErr = verifyBaselineImage(dataX, dataY, baselineImage, baselineName); if (compErr == OsprayStatus::Ok) compErr = compareImgWithBaselineTmpl( (vec4uc *)testImage, baselineImage, baselineName); if (baselineImage) stbi_image_free(baselineImage); } else if (GetFileFormat() == ".hdr") { vec4f *baselineImage = (vec4f *)stbi_loadf( baselineName.c_str(), &dataX, &dataY, &dataN, ImgType::RGBA); compErr = verifyBaselineImage(dataX, dataY, baselineImage, baselineName); if (compErr == OsprayStatus::Ok) compErr = compareImgWithBaselineTmpl( (vec4f *)testImage, baselineImage, baselineName, 255.0f); if (baselineImage) stbi_image_free(baselineImage); } else if (GetFileFormat() == ".pfm") { vec4f *baselineImage = loadPF4(baselineName, dataX, dataY); compErr = verifyBaselineImage(dataX, dataY, baselineImage, baselineName); if (compErr == OsprayStatus::Ok) compErr = compareImgWithBaselineTmpl( (vec4f *)testImage, baselineImage, baselineName, 255.0f); if (baselineImage) delete[] baselineImage; } else { std::cerr << "Unsupported file format" << std::endl; compErr = OsprayStatus::Error; } return compErr; } RenderKit-ospray-85af292/apps/ospTestSuite/test_tools.h000066400000000000000000000040721464752671100232640ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #include #include #include #include #include #include "environment.h" #include "stb_image.h" #include "stb_image_write.h" #include "rkcommon/utility/multidim_index_sequence.h" using pixelColorValue = float; const pixelColorValue pixelThreshold = 13.f; const float errorRate = 0.1; enum class OsprayStatus { Ok, Fail, Error, }; enum ImgType { Y = 1, YA, RGB, RGBA, }; class OSPImageTools { protected: vec2i size; std::string fileFormat; std::string imgName; std::string GetFileFormat() const { return fileFormat; } // helper method to write the rendered image as PNG file OsprayStatus writePNG(std::string fileName, const uint32_t *pixel); // helper method to write the rendered image as HDR file OsprayStatus writeHDR(std::string fileName, const float *pixel); // helper method to write the image with given format OsprayStatus writeImg(std::string fileName, const void *pixel); // average pixels over some window OsprayStatus verifyBaselineImage(const int sizeX, const int sizeY, const void *baselineImage, const std::string &baselineName); vec4f getAveragedPixel(const vec4f *image, vec2i pixelIndex, const rkcommon::index_sequence_2D &imageIndices); // compare gold image with fb but with storage type abstraction template OsprayStatus compareImgWithBaselineTmpl(const T *testImage, const T *baselineImage, const std::string &baselineName, const float pixelConversionFactor = 1.0f); public: OSPImageTools(vec2i imgSize, std::string testName, OSPFrameBufferFormat frameBufferFormat); ~OSPImageTools() = default; // helper method to saved rendered file OsprayStatus saveTestImage(const void *pixel); // helper method to compare gold image with current framebuffer render OsprayStatus compareImgWithBaseline(const void *testImage); }; RenderKit-ospray-85af292/apps/ospTestSuite/test_volumetric.cpp000066400000000000000000000177631464752671100246630ustar00rootroot00000000000000// Copyright 2017 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_volumetric.h" #include "ArcballCamera.h" #include "ospray_testing.h" #include "rkcommon/utility/multidim_index_sequence.h" namespace OSPRayTestScenes { // Helper functions ///////////////////////////////////////////////////////// // creates a torus // volumetric data: stores data of torus // returns created ospvolume of torus static cpp::Volume CreateTorus(const int size) { std::vector volumetricData(size * size * size); const float r = 30; const float R = 80; const int size_2 = size / 2; const vec3i dims = vec3i(size); rkcommon::index_sequence_3D idx(dims); for (vec3i i : idx) { const float X = i.x - size_2; const float Y = i.y - size_2; const float Z = i.z - size_2; const float d = (R - std::sqrt(Z * Z + Y * Y)); volumetricData[idx.flatten(i)] = r * r - d * d - X * X; } cpp::Volume torus("structuredRegular"); torus.setParam("data", cpp::CopiedData(volumetricData.data(), vec3ul(size))); torus.setParam("gridOrigin", vec3f(-0.5f)); torus.setParam("gridSpacing", vec3f(1.f / size)); torus.commit(); return torus; } ///////////////////////////////////////////////////////////////////////////// TextureVolumeTransform::TextureVolumeTransform() { rendererType = GetParam(); } void TextureVolumeTransform::SetUp() { Base::SetUp(); camera.setParam("position", vec3f(.66f, .66f, -2.5f)); camera.setParam("direction", vec3f(0.f, 0.f, 1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); // Create transfer function cpp::TransferFunction transferFun("piecewiseLinear"); { std::vector colors = {vec3f(1.f, 0.f, 0.f), vec3f(0.f, 1.f, 0.f), vec3f(0.f, 1.f, 1.f), vec3f(1.f, 1.f, 0.f), vec3f(1.f, 1.f, 1.f), vec3f(1.f, 0.f, 1.f)}; std::vector opacities = {1.f, 1.f}; transferFun.setParam("value", range1f(-10000.f, 100.f)); transferFun.setParam("color", cpp::CopiedData(colors)); transferFun.setParam("opacity", cpp::CopiedData(opacities)); transferFun.commit(); } // Create volumetric model cpp::Volume volume = CreateTorus(256); volume.commit(); // Create volume texture cpp::Texture tex("volume"); tex.setParam("volume", volume); tex.setParam("transferFunction", transferFun); tex.commit(); // Create a single sphere geometry cpp::Geometry sphere("sphere"); { sphere.setParam("sphere.position", cpp::CopiedData(vec3f(0.f))); sphere.setParam("radius", 0.51f); sphere.commit(); } // Prepare material array constexpr uint32_t cols = 2; constexpr uint32_t rows = 2; std::array materials; { // Create materials for (uint32_t i = 0; i < cols * rows; i++) { cpp::Material mat("obj"); mat.setParam("map_kd", tex); mat.commit(); materials[i] = mat; } // Set scale materials[1].setParam("map_kd.transform", affine3f::scale(vec3f(1.2f))); materials[1].commit(); // Set rotation materials[2].setParam( "map_kd.transform", affine3f::rotate(vec3f(0.5, 0.2, 1), 1.f)); materials[2].commit(); } // Prepare instances rkcommon::index_sequence_2D idx(vec2i(cols, rows)); for (auto i : idx) { // Create geometric model cpp::GeometricModel model(sphere); model.setParam("material", materials[idx.flatten(i)]); model.commit(); // Create group cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); // Create instance cpp::Instance instance(group); instance.setParam( "transform", affine3f::translate(1.25f * vec3f(i.x, i.y, 0.f))); instance.commit(); AddInstance(instance); } cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.5f); AddLight(ambient); } DepthCompositeVolume::DepthCompositeVolume() { auto params = GetParam(); rendererType = std::get<0>(params); bgColor = std::get<1>(params); } void DepthCompositeVolume::SetUp() { Base::SetUp(); camera.setParam("position", vec3f(0.f, 0.f, 1.f)); camera.setParam("direction", vec3f(0.f, 0.f, -1.f)); camera.setParam("up", vec3f(0.f, 1.f, 0.f)); cpp::Volume torus = CreateTorus(256); cpp::VolumetricModel volumetricModel(torus); cpp::TransferFunction transferFun("piecewiseLinear"); transferFun.setParam("value", range1f(-10000.f, 10000.f)); std::vector colors = { vec3f(1.0f, 0.0f, 0.0f), vec3f(0.0f, 1.0f, 0.0f)}; std::vector opacities = {0.05f, 1.0f}; transferFun.setParam("color", cpp::CopiedData(colors)); transferFun.setParam("opacity", cpp::CopiedData(opacities)); transferFun.commit(); volumetricModel.setParam("transferFunction", transferFun); volumetricModel.commit(); AddModel(volumetricModel); cpp::Texture depthTex("texture2d"); std::vector texData(imgSize.product()); for (int y = 0; y < imgSize.y; y++) { for (int x = 0; x < imgSize.x; x++) { const size_t index = imgSize.x * y + x; if (x < imgSize.x / 3) { texData[index] = 999.f; } else if (x < (imgSize.x * 2) / 3) { texData[index] = 0.75f; } else { texData[index] = 0.00001f; } } } depthTex.setParam("format", OSP_TEXTURE_R32F); depthTex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST); depthTex.setParam("data", cpp::CopiedData(texData.data(), imgSize)); depthTex.commit(); renderer.setParam("map_maxDepth", depthTex); renderer.setParam("backgroundColor", bgColor); cpp::Light ambient("ambient"); ambient.setParam("intensity", 0.5f); AddLight(ambient); } UnstructuredVolume::UnstructuredVolume() { auto params = GetParam(); rendererType = std::get<0>(params); showCells = std::get<1>(params); } void UnstructuredVolume::SetUp() { Base::SetUp(); instances.clear(); auto builder = ospray::testing::newBuilder("unstructured_volume"); ospray::testing::setParam(builder, "rendererType", rendererType); ospray::testing::setParam(builder, "showCells", showCells); ospray::testing::commit(builder); world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); world.commit(); auto worldBounds = world.getBounds(); ArcballCamera arcballCamera(worldBounds, imgSize); camera.setParam("position", arcballCamera.eyePos()); camera.setParam("direction", arcballCamera.lookDir()); camera.setParam("up", arcballCamera.upDir()); renderer.setParam("maxPathLength", 1); } // Test Instantiations ////////////////////////////////////////////////////// INSTANTIATE_TEST_SUITE_P(TestScenesVolumes, FromOsprayTesting, ::testing::Combine(::testing::Values("gravity_spheres_volume", "perlin_noise_volumes", "unstructured_volume_simple", "particle_volume", "vdb_volume", "vdb_volume_packed", "gravity_spheres_amr"), ::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values(16))); INSTANTIATE_TEST_SUITE_P(TestScenesVolumesStrictParams, FromOsprayTesting, ::testing::Values(std::make_tuple("perlin_noise_many_volumes", "scivis", 4), std::make_tuple("perlin_noise_many_volumes", "pathtracer", 32), std::make_tuple("perlin_noise_many_volumes", "ao", 4))); TEST_P(UnstructuredVolume, simple) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(TestScenesVolumes, UnstructuredVolume, ::testing::Combine(::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values(false, true))); TEST_P(TextureVolumeTransform, simple) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P( Renderers, TextureVolumeTransform, ::testing::Values("scivis")); TEST_P(DepthCompositeVolume, simple) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Renderers, DepthCompositeVolume, ::testing::Combine(::testing::Values("scivis"), ::testing::Values(vec4f(0.f), vec4f(1.f), vec4f(0.f, 0.f, 0.f, 1.f), vec4f(1.f, 0.f, 0.f, 0.5f)))); } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTestSuite/test_volumetric.h000066400000000000000000000025601464752671100243150ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "test_fixture.h" namespace OSPRayTestScenes { // Test a texture colored by a volume. Creates spheres colored by the torus // volume It's parametrized with type of the renderer. class TextureVolumeTransform_deprecated : public Base, public ::testing::TestWithParam { public: TextureVolumeTransform_deprecated(); void SetUp() override; }; class TextureVolumeTransform : public Base, public ::testing::TestWithParam { public: TextureVolumeTransform(); void SetUp() override; }; // Test a texture colored by a volume. Creates a sphere colored by the torus // volume It's parametrized with type of the renderer and background color class DepthCompositeVolume : public Base, public ::testing::TestWithParam> { public: DepthCompositeVolume(); void SetUp() override; private: vec4f bgColor; }; // Test an unstructured volume rendering. Generates a complex scene made of // different cell types. Parametrized with cells visibility boolean. class UnstructuredVolume : public Base, public ::testing::TestWithParam> { public: UnstructuredVolume(); void SetUp() override; private: bool showCells; }; } // namespace OSPRayTestScenes RenderKit-ospray-85af292/apps/ospTutorial/000077500000000000000000000000001464752671100205635ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospTutorial/CMakeLists.txt000066400000000000000000000021071464752671100233230ustar00rootroot00000000000000## Copyright 2018 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 if (NOT OSPRAY_ENABLE_APPS_TUTORIALS) return() endif() # build ospTutorial, for demonstration and API testing add_executable(ospTutorial ${OSPRAY_RESOURCE} ospTutorial.c) target_link_libraries(ospTutorial PRIVATE ospray) ospray_sign_target(ospTutorial) # C++ version add_executable(ospTutorialCpp ${OSPRAY_RESOURCE} ospTutorial.cpp) target_link_libraries(ospTutorialCpp PRIVATE ospray_sdk) ospray_sign_target(ospTutorialCpp) # async version add_executable(ospTutorialAsync ${OSPRAY_RESOURCE} ospTutorialAsync.c) target_link_libraries(ospTutorialAsync PRIVATE ospray) ospray_sign_target(ospTutorialAsync) install(TARGETS ospTutorial ospTutorialCpp ospTutorialAsync DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) # GLM C++ version if (OSPRAY_APPS_ENABLE_GLM) add_executable(ospTutorialGLM ${OSPRAY_RESOURCE} ospTutorialGLM.cpp) target_link_libraries(ospTutorialGLM PRIVATE ospray ${GLM_TARGET}) install(TARGETS ospTutorialGLM DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) endif() RenderKit-ospray-85af292/apps/ospTutorial/ospTutorial.c000066400000000000000000000160151464752671100232570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial how to use OSPRay in an application. * * On Linux build it in the build_directory with * gcc -std=c99 ../apps/ospTutorial/ospTutorial.c \ * -I ../ospray/include -L . -lospray -Wl,-rpath,. -o ospTutorial * On Windows build it in the build_directory\$Configuration with * cl ..\..\apps\ospTutorial\ospTutorial.c -I ..\..\ospray\include ^ * -I ..\.. ospray.lib */ #include #include #include #ifdef _WIN32 #include #include #include #else #include #endif #include "ospray/ospray_util.h" // helper function to write the rendered image as PPM file void writePPM( const char *fileName, int size_x, int size_y, const uint32_t *pixel) { FILE *file = fopen(fileName, "wb"); if (!file) { fprintf(stderr, "fopen('%s', 'wb') failed: %d", fileName, errno); return; } fprintf(file, "P6\n%i %i\n255\n", size_x, size_y); unsigned char *out = (unsigned char *)alloca(3 * size_x); for (int y = 0; y < size_y; y++) { const unsigned char *in = (const unsigned char *)&pixel[(size_y - 1 - y) * size_x]; for (int x = 0; x < size_x; x++) { out[3 * x + 0] = in[4 * x + 0]; out[3 * x + 1] = in[4 * x + 1]; out[3 * x + 2] = in[4 * x + 2]; } fwrite(out, 3 * size_x, sizeof(char), file); } fprintf(file, "\n"); fclose(file); } int main(int argc, const char **argv) { // image size int imgSize_x = 1024; // width int imgSize_y = 768; // height // camera float cam_pos[] = {0.f, 0.f, 0.f}; float cam_up[] = {0.f, 1.f, 0.f}; float cam_view[] = {0.1f, 0.f, 1.f}; // triangle mesh data float vertex[] = {-1.0f, -1.0f, 3.0f, -1.0f, 1.0f, 3.0f, 1.0f, -1.0f, 3.0f, 0.1f, 0.1f, 0.3f}; float color[] = {0.9f, 0.5f, 0.5f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 0.5f, 0.9f, 0.5f, 1.0f}; int32_t index[] = {0, 1, 2, 1, 2, 3}; #ifdef _WIN32 int waitForKey = 0; CONSOLE_SCREEN_BUFFER_INFO csbi; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { // detect standalone console: cursor at (0,0)? waitForKey = csbi.dwCursorPosition.X == 0 && csbi.dwCursorPosition.Y == 0; } #endif printf("initialize OSPRay..."); // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, // e.g. "--osp:debug" OSPError init_error = ospInit(&argc, argv); if (init_error != OSP_NO_ERROR) return init_error; printf("done\n"); printf("setting up camera..."); // create and setup camera OSPCamera camera = ospNewCamera("perspective"); ospSetFloat(camera, "aspect", imgSize_x / (float)imgSize_y); ospSetParam(camera, "position", OSP_VEC3F, cam_pos); ospSetParam(camera, "direction", OSP_VEC3F, cam_view); ospSetParam(camera, "up", OSP_VEC3F, cam_up); ospCommit(camera); // commit each object to indicate modifications are done printf("done\n"); printf("setting up scene..."); // create and setup model and mesh OSPGeometry mesh = ospNewGeometry("mesh"); OSPData data = ospNewSharedData1D(vertex, OSP_VEC3F, 4); // alternatively with an OSPRay managed OSPData // OSPData managed = ospNewData1D(OSP_VEC3F, 4); // ospCopyData1D(data, managed, 0); ospCommit(data); ospSetObject(mesh, "vertex.position", data); ospRelease(data); // we are done using this handle data = ospNewSharedData1D(color, OSP_VEC4F, 4); ospCommit(data); ospSetObject(mesh, "vertex.color", data); ospRelease(data); data = ospNewSharedData1D(index, OSP_VEC3UI, 2); ospCommit(data); ospSetObject(mesh, "index", data); ospRelease(data); ospCommit(mesh); OSPMaterial mat = ospNewMaterial("obj"); ospCommit(mat); // put the mesh into a model OSPGeometricModel model = ospNewGeometricModel(mesh); ospSetObject(model, "material", mat); ospCommit(model); ospRelease(mesh); ospRelease(mat); // put the model into a group (collection of models) OSPGroup group = ospNewGroup(); ospSetObjectAsData(group, "geometry", OSP_GEOMETRIC_MODEL, model); ospCommit(group); ospRelease(model); // put the group into an instance (give the group a world transform) OSPInstance instance = ospNewInstance(group); ospCommit(instance); ospRelease(group); // put the instance in the world OSPWorld world = ospNewWorld(); ospSetObjectAsData(world, "instance", OSP_INSTANCE, instance); ospRelease(instance); // create and setup light for Ambient Occlusion OSPLight light = ospNewLight("ambient"); ospCommit(light); ospSetObjectAsData(world, "light", OSP_LIGHT, light); ospRelease(light); ospCommit(world); printf("done\n"); // print out world bounds OSPBounds worldBounds = ospGetBounds(world); printf("world bounds: ({%f, %f, %f}, {%f, %f, %f}\n\n", worldBounds.lower[0], worldBounds.lower[1], worldBounds.lower[2], worldBounds.upper[0], worldBounds.upper[1], worldBounds.upper[2]); printf("setting up renderer..."); // create renderer OSPRenderer renderer = ospNewRenderer("pathtracer"); // choose path tracing renderer // complete setup of renderer ospSetFloat(renderer, "backgroundColor", 1.0f); // white, transparent ospCommit(renderer); // create and setup framebuffer OSPFrameBuffer framebuffer = ospNewFrameBuffer(imgSize_x, imgSize_y, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); ospResetAccumulation(framebuffer); printf("rendering initial frame to firstFrame.ppm..."); // render one frame ospRenderFrameBlocking(framebuffer, renderer, camera, world); // access framebuffer and write its content as PPM file const uint32_t *fb = (uint32_t *)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("firstFrame.ppm", imgSize_x, imgSize_y, fb); ospUnmapFrameBuffer(fb, framebuffer); printf("done\n"); printf("rendering 10 accumulated frames to accumulatedFrame.ppm..."); // render 10 more frames, which are accumulated to result in a better // converged image for (int frames = 0; frames < 10; frames++) ospRenderFrameBlocking(framebuffer, renderer, camera, world); fb = (uint32_t *)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("accumulatedFrame.ppm", imgSize_x, imgSize_y, fb); ospUnmapFrameBuffer(fb, framebuffer); printf("done\n\n"); OSPPickResult p; ospPick(&p, framebuffer, renderer, camera, world, 0.5f, 0.5f); printf("ospPick() center of screen --> [inst: %p, model: %p, prim: %u]\n", p.instance, p.model, p.primID); printf("cleaning up objects..."); // cleanup pick handles (because p.hasHit was 'true') ospRelease(p.instance); ospRelease(p.model); // final cleanups ospRelease(renderer); ospRelease(camera); ospRelease(framebuffer); ospRelease(world); printf("done\n"); ospShutdown(); #ifdef _WIN32 if (waitForKey) { printf("\n\tpress any key to exit"); _getch(); } #endif return 0; } RenderKit-ospray-85af292/apps/ospTutorial/ospTutorial.cpp000066400000000000000000000126111464752671100236150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial how to use OSPRay in an application. * * On Linux build it in the build_directory with * g++ ../apps/ospTutorial/ospTutorial.cpp -I ../ospray/include \ * -I ../../rkcommon -L . -lospray -Wl,-rpath,. -o ospTutorial * On Windows build it in the build_directory\$Configuration with * cl ..\..\apps\ospTutorial\ospTutorial.cpp /EHsc -I ..\..\ospray\include ^ * -I ..\.. -I ..\..\..\rkcommon ospray.lib * Above commands assume that rkcommon is present in a directory right "next * to" the OSPRay directory. If this is not the case, then adjust the include * path (alter "-I " appropriately). */ #include #include #include #ifdef _WIN32 #define NOMINMAX #include #include #include #else #include #endif #include #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "rkcommon/utility/SaveImage.h" using namespace rkcommon::math; int main(int argc, const char **argv) { // image size vec2i imgSize; imgSize.x = 1024; // width imgSize.y = 768; // height // camera vec3f cam_pos{0.f, 0.f, 0.f}; vec3f cam_up{0.f, 1.f, 0.f}; vec3f cam_view{0.1f, 0.f, 1.f}; // triangle mesh data std::vector vertex = {vec3f(-1.0f, -1.0f, 3.0f), vec3f(-1.0f, 1.0f, 3.0f), vec3f(1.0f, -1.0f, 3.0f), vec3f(0.1f, 0.1f, 0.3f)}; std::vector color = {vec4f(0.9f, 0.5f, 0.5f, 1.0f), vec4f(0.8f, 0.8f, 0.8f, 1.0f), vec4f(0.8f, 0.8f, 0.8f, 1.0f), vec4f(0.5f, 0.9f, 0.5f, 1.0f)}; std::vector index = {vec3ui(0, 1, 2), vec3ui(1, 2, 3)}; #ifdef _WIN32 bool waitForKey = false; CONSOLE_SCREEN_BUFFER_INFO csbi; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { // detect standalone console: cursor at (0,0)? waitForKey = csbi.dwCursorPosition.X == 0 && csbi.dwCursorPosition.Y == 0; } #endif // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, // e.g. "--osp:debug" OSPError init_error = ospInit(&argc, argv); if (init_error != OSP_NO_ERROR) return init_error; // use scoped lifetimes of wrappers to release everything before ospShutdown() { // create and setup camera ospray::cpp::Camera camera("perspective"); camera.setParam("aspect", imgSize.x / (float)imgSize.y); camera.setParam("position", cam_pos); camera.setParam("direction", cam_view); camera.setParam("up", cam_up); camera.commit(); // commit each object to indicate modifications are done // create and setup model and mesh ospray::cpp::Geometry mesh("mesh"); mesh.setParam("vertex.position", ospray::cpp::CopiedData(vertex)); mesh.setParam("vertex.color", ospray::cpp::CopiedData(color)); mesh.setParam("index", ospray::cpp::CopiedData(index)); mesh.commit(); // put the mesh into a model ospray::cpp::GeometricModel model(mesh); model.commit(); // put the model into a group (collection of models) ospray::cpp::Group group; group.setParam("geometry", ospray::cpp::CopiedData(model)); group.commit(); // put the group into an instance (give the group a world transform) ospray::cpp::Instance instance(group); instance.commit(); // put the instance in the world ospray::cpp::World world; world.setParam("instance", ospray::cpp::CopiedData(instance)); // create and setup light for Ambient Occlusion ospray::cpp::Light light("ambient"); light.commit(); world.setParam("light", ospray::cpp::CopiedData(light)); world.commit(); // create renderer, choose Scientific Visualization renderer ospray::cpp::Renderer renderer("scivis"); // complete setup of renderer renderer.setParam("aoSamples", 1); renderer.setParam("backgroundColor", 1.0f); // white, transparent renderer.commit(); // create and setup framebuffer ospray::cpp::FrameBuffer framebuffer( imgSize.x, imgSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); framebuffer.clear(); // render one frame framebuffer.renderFrame(renderer, camera, world); // access framebuffer and write its content as PPM file uint32_t *fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); rkcommon::utility::writePPM("firstFrameCpp.ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); std::cout << "rendering initial frame to firstFrameCpp.ppm" << std::endl; // render 10 more frames, which are accumulated to result in a better // converged image for (int frames = 0; frames < 10; frames++) framebuffer.renderFrame(renderer, camera, world); fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); rkcommon::utility::writePPM( "accumulatedFrameCpp.ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); std::cout << "rendering 10 accumulated frames to accumulatedFrameCpp.ppm" << std::endl; ospray::cpp::PickResult res = framebuffer.pick(renderer, camera, world, 0.5f, 0.5f); if (res.hasHit) { std::cout << "picked geometry [instance: " << res.instance.handle() << ", model: " << res.model.handle() << ", primitive: " << res.primID << "]" << std::endl; } } ospShutdown(); #ifdef _WIN32 if (waitForKey) { printf("\n\tpress any key to exit"); _getch(); } #endif return 0; } RenderKit-ospray-85af292/apps/ospTutorial/ospTutorialAsync.c000066400000000000000000000270731464752671100242630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial of how to use OSPRay's async API in an * application. We setup up two scenes which are rendered asynchronously * in parallel to each other. */ #include #include #include #ifdef _WIN32 #include #include #include #else #include #endif #include "ospray/ospray_util.h" typedef struct { int x, y; } vec2i; // helper function to write the rendered image as PPM file void writePPM(const char *fileName, const vec2i *size, const uint32_t *pixel) { FILE *file = fopen(fileName, "wb"); if (!file) { fprintf(stderr, "fopen('%s', 'wb') failed: %d", fileName, errno); return; } fprintf(file, "P6\n%i %i\n255\n", size->x, size->y); unsigned char *out = (unsigned char *)alloca(3 * size->x); for (int y = 0; y < size->y; y++) { const unsigned char *in = (const unsigned char *)&pixel[(size->y - 1 - y) * size->x]; for (int x = 0; x < size->x; x++) { out[3 * x + 0] = in[4 * x + 0]; out[3 * x + 1] = in[4 * x + 1]; out[3 * x + 2] = in[4 * x + 2]; } fwrite(out, 3 * size->x, sizeof(char), file); } fprintf(file, "\n"); fclose(file); } void buildScene1(OSPCamera *camera, OSPWorld *world, OSPRenderer *renderer, OSPFrameBuffer *framebuffer, vec2i imgSize); void buildScene2(OSPCamera *camera, OSPWorld *world, OSPRenderer *renderer, OSPFrameBuffer *framebuffer, vec2i imgSize); int main(int argc, const char **argv) { #ifdef _WIN32 int waitForKey = 0; CONSOLE_SCREEN_BUFFER_INFO csbi; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { // detect standalone console: cursor at (0,0)? waitForKey = csbi.dwCursorPosition.X == 0 && csbi.dwCursorPosition.Y == 0; } #endif // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, // e.g. "--osp:debug" OSPError init_error = ospInit(&argc, argv); if (init_error != OSP_NO_ERROR) return init_error; vec2i imgSizes[2] = {0}; imgSizes[0].x = 1024; // width imgSizes[0].y = 768; // height imgSizes[1].x = 800; imgSizes[1].y = 600; OSPCamera cameras[2] = {0}; OSPWorld worlds[2] = {0}; OSPRenderer renderers[2] = {0}; OSPFrameBuffer framebuffers[2] = {0}; buildScene1( &cameras[0], &worlds[0], &renderers[0], &framebuffers[0], imgSizes[0]); buildScene2( &cameras[1], &worlds[1], &renderers[1], &framebuffers[1], imgSizes[1]); printf("starting renders...\n"); OSPFuture futures[2] = {0}; // render one frame for each scene for (int i = 0; i < 2; ++i) { futures[i] = ospRenderFrame(framebuffers[i], renderers[i], cameras[i], worlds[i]); } for (int i = 0; i < 2; ++i) { int isFinished = ospIsReady(futures[i], OSP_TASK_FINISHED); printf("status of 'futures[%i]' is %i\n", i, isFinished); } // We don't need to wait for them in the order they were started for (int i = 1; i >= 0; --i) { ospWait(futures[i], OSP_FRAME_FINISHED); printf("...done, variance of render %i was %f\n", i, ospGetVariance(framebuffers[i])); ospRelease(futures[i]); } // access framebuffer and write its content as PPM file const uint32_t *fb = (uint32_t *)ospMapFrameBuffer(framebuffers[0], OSP_FB_COLOR); writePPM("firstFrame-scene1.ppm", &imgSizes[0], fb); ospUnmapFrameBuffer(fb, framebuffers[0]); printf("wrote rendered scene 1 to firstFrame-scene1.ppm\n"); fb = (uint32_t *)ospMapFrameBuffer(framebuffers[1], OSP_FB_COLOR); writePPM("firstFrame-scene2.ppm", &imgSizes[1], fb); ospUnmapFrameBuffer(fb, framebuffers[1]); printf("wrote rendered scene 2 to firstFrame-scene2.ppm\n"); // render 10 more frames, which are accumulated to result in a better // converged image printf("starting accumulation...\n"); for (int frames = 0; frames < 10; frames++) { for (int i = 0; i < 2; ++i) { futures[i] = ospRenderFrame(framebuffers[i], renderers[i], cameras[i], worlds[i]); } for (int i = 0; i < 2; ++i) { ospWait(futures[i], OSP_FRAME_FINISHED); if (frames < 9) // don't release future of last frame yet ospRelease(futures[i]); } } for (int i = 1; i >= 0; --i) { printf("...done, variance of render %i is now %f\n", i, ospGetVariance(framebuffers[i])); ospRelease(futures[i]); } fb = (uint32_t *)ospMapFrameBuffer(framebuffers[0], OSP_FB_COLOR); writePPM("accumulatedFrame-scene1.ppm", &imgSizes[0], fb); ospUnmapFrameBuffer(fb, framebuffers[0]); printf("wrote accumulated scene 1 to accumulatedFrame-scene1.ppm\n"); fb = (uint32_t *)ospMapFrameBuffer(framebuffers[1], OSP_FB_COLOR); writePPM("accumulatedFrame-scene2.ppm", &imgSizes[1], fb); ospUnmapFrameBuffer(fb, framebuffers[1]); printf("wrote accumulated scene 2 to accumulatedFrame-scene2.ppm\n"); // final cleanups for (int i = 0; i < 2; ++i) { ospRelease(cameras[i]); ospRelease(worlds[i]); ospRelease(renderers[i]); ospRelease(framebuffers[i]); } printf("shutting down\n"); ospShutdown(); #ifdef _WIN32 if (waitForKey) { printf("\n\tpress any key to exit"); _getch(); } #endif return 0; } void buildScene1(OSPCamera *camera, OSPWorld *world, OSPRenderer *renderer, OSPFrameBuffer *framebuffer, vec2i imgSize) { // camera float cam_pos[] = {0.f, 0.f, 0.f}; float cam_up[] = {0.f, 1.f, 0.f}; float cam_view[] = {0.1f, 0.f, 1.f}; // triangle mesh data static float vertex[] = {-1.0f, -1.0f, 3.0f, -1.0f, 1.0f, 3.0f, 1.0f, -1.0f, 3.0f, 0.1f, 0.1f, 0.3f}; static float color[] = {0.9f, 0.5f, 0.5f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 0.5f, 0.9f, 0.5f, 1.0f}; static int32_t index[] = {0, 1, 2, 1, 2, 3}; // create and setup camera *camera = ospNewCamera("perspective"); ospSetFloat(*camera, "aspect", imgSize.x / (float)imgSize.y); ospSetParam(*camera, "pos", OSP_VEC3F, cam_pos); ospSetParam(*camera, "dir", OSP_VEC3F, cam_view); ospSetParam(*camera, "up", OSP_VEC3F, cam_up); ospCommit(*camera); // commit each object to indicate modifications are done // create and setup model and mesh OSPGeometry mesh = ospNewGeometry("mesh"); OSPData data = ospNewSharedData1D(vertex, OSP_VEC3F, 4); ospCommit(data); ospSetObject(mesh, "vertex.position", data); ospRelease(data); // we are done using this handle data = ospNewSharedData1D(color, OSP_VEC4F, 4); ospCommit(data); ospSetObject(mesh, "vertex.color", data); ospRelease(data); data = ospNewSharedData1D(index, OSP_VEC3UI, 2); ospCommit(data); ospSetObject(mesh, "index", data); ospRelease(data); ospCommit(mesh); // put the mesh into a model static OSPGeometricModel model; model = ospNewGeometricModel(mesh); ospCommit(model); ospRelease(mesh); // put the model into a group (collection of models) OSPGroup group = ospNewGroup(); OSPData models = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1); ospSetObject(group, "geometry", models); ospCommit(group); ospRelease(model); ospRelease(models); // put the group into an instance (give the group a world transform) static OSPInstance instance; instance = ospNewInstance(group); ospCommit(instance); ospRelease(group); // put the instance in the world *world = ospNewWorld(); OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1); ospSetObject(*world, "instance", instances); // create and setup light for Ambient Occlusion static OSPLight light; light = ospNewLight("ambient"); ospCommit(light); OSPData lights = ospNewSharedData1D(&light, OSP_LIGHT, 1); ospCommit(lights); ospSetObject(*world, "light", lights); ospCommit(*world); ospRelease(instance); ospRelease(instances); // create renderer *renderer = ospNewRenderer("scivis"); // choose Scientific Visualization renderer // complete setup of renderer ospSetInt(*renderer, "aoSamples", 1); ospSetFloat(*renderer, "backgroundColor", 1.0f); // white, transparent ospCommit(*renderer); ospRelease(light); ospRelease(lights); // create and setup framebuffer *framebuffer = ospNewFrameBuffer(imgSize.x, imgSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM | OSP_FB_VARIANCE); } void buildScene2(OSPCamera *camera, OSPWorld *world, OSPRenderer *renderer, OSPFrameBuffer *framebuffer, vec2i imgSize) { // camera float cam_pos[] = {2.0f, -1.f, -4.f}; float cam_up[] = {0.f, 1.f, 0.f}; float cam_view[] = {-0.2f, 0.25f, 1.f}; // triangle mesh data static float vertex[] = {-2.0f, -2.0f, 2.0f, -2.0f, 3.0f, 2.0f, 2.0f, -2.0f, 2.0f, 0.1f, -0.1f, 1.f}; static float color[] = {0.0f, 0.1f, 0.8f, 1.0f, 0.8f, 0.8f, 0.0f, 1.0f, 0.8f, 0.8f, 0.0f, 1.0f, 0.9f, 0.1f, 0.0f, 1.0f}; static int32_t index[] = {0, 1, 2, 1, 2, 3}; // create and setup camera *camera = ospNewCamera("perspective"); ospSetFloat(*camera, "aspect", imgSize.x / (float)imgSize.y); ospSetParam(*camera, "pos", OSP_VEC3F, cam_pos); ospSetParam(*camera, "dir", OSP_VEC3F, cam_view); ospSetParam(*camera, "up", OSP_VEC3F, cam_up); ospCommit(*camera); // commit each object to indicate modifications are done // create and setup model and mesh OSPGeometry mesh = ospNewGeometry("mesh"); OSPData data = ospNewSharedData1D(vertex, OSP_VEC3F, 4); ospCommit(data); ospSetObject(mesh, "vertex.position", data); ospRelease(data); data = ospNewSharedData1D(color, OSP_VEC4F, 4); ospCommit(data); ospSetObject(mesh, "vertex.color", data); ospRelease(data); data = ospNewSharedData1D(index, OSP_VEC3UI, 2); ospCommit(data); ospSetObject(mesh, "index", data); ospRelease(data); ospCommit(mesh); // put the mesh into a model static OSPGeometricModel model; model = ospNewGeometricModel(NULL); ospSetObject(model, "geometry", mesh); ospCommit(model); ospRelease(mesh); // put the model into a group (collection of models) OSPGroup group = ospNewGroup(); OSPData models = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1); ospSetObject(group, "geometry", models); ospCommit(group); ospRelease(model); ospRelease(models); // put the group into an instance (give the group a world transform) static OSPInstance instance; instance = ospNewInstance(NULL); ospSetObject(instance, "group", group); ospCommit(instance); ospRelease(group); // put the instance in the world *world = ospNewWorld(); OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1); ospSetObject(*world, "instance", instances); // create and setup light for Ambient Occlusion static OSPLight light; light = ospNewLight("ambient"); ospCommit(light); OSPData lights = ospNewSharedData1D(&light, OSP_LIGHT, 1); ospCommit(lights); ospSetObject(*world, "light", lights); ospCommit(*world); ospRelease(instances); ospRelease(instance); // create renderer *renderer = ospNewRenderer("scivis"); // choose Scientific Visualization renderer // complete setup of renderer ospSetInt(*renderer, "aoSamples", 4); ospSetFloat(*renderer, "backgroundColor", 0.2f); // gray, transparent ospCommit(*renderer); ospRelease(light); ospRelease(lights); // create and setup framebuffer *framebuffer = ospNewFrameBuffer(imgSize.x, imgSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM | OSP_FB_VARIANCE); } RenderKit-ospray-85af292/apps/ospTutorial/ospTutorialFindospray/000077500000000000000000000000001464752671100251475ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/ospTutorial/ospTutorialFindospray/CMakeLists.txt000066400000000000000000000017771464752671100277230ustar00rootroot00000000000000## Copyright 2019 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # NOTE: This CMakeLists.txt is intended to be used to exercise an OSPRay # install and demonstrate how external applications can build against # OSPRay using CMake. # # Once you have done a 'make install' of an existing OSPRay # build (will install to CMAKE_INSTALL_PREFIX), create a separate build # directory and invoke CMake on this directory. If you have 'ospray_DIR' # setup correctly to point to where you just installed OSPRay, then this # should build the ospTutorial app from that install and NOT use your # local build. cmake_minimum_required(VERSION 3.5) project(ospTutorialFindospray LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) find_package(ospray 3.0.0 REQUIRED) add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../ospTutorial.c) target_link_libraries(${PROJECT_NAME} ospray::ospray) RenderKit-ospray-85af292/apps/ospTutorial/ospTutorialGLM.cpp000066400000000000000000000105321464752671100241550ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial how to use OSPRay in an application using GLM instead of rkcommon for math types. */ #include #include #include #ifdef _WIN32 #define NOMINMAX #include #else #include #endif #include #include #include #include "ospray/ospray_cpp.h" #define OSPRAY_GLM_DEFINITIONS #include "ospray/ospray_cpp/ext/glm.h" #include "rkcommon/utility/SaveImage.h" int main(int argc, const char **argv) { // image size glm::ivec2 imgSize; imgSize.x = 1024; // width imgSize.y = 768; // height // camera glm::vec3 cam_pos{0.f, 0.f, 0.f}; glm::vec3 cam_up{0.f, 1.f, 0.f}; glm::vec3 cam_view{0.1f, 0.f, 1.f}; // triangle mesh data std::vector vertex = {glm::vec3(-1.0f, -1.0f, 3.0f), glm::vec3(-1.0f, 1.0f, 3.0f), glm::vec3(1.0f, -1.0f, 3.0f), glm::vec3(0.1f, 0.1f, 0.3f)}; std::vector color = {glm::vec4(0.9f, 0.5f, 0.5f, 1.0f), glm::vec4(0.8f, 0.8f, 0.8f, 1.0f), glm::vec4(0.8f, 0.8f, 0.8f, 1.0f), glm::vec4(0.5f, 0.9f, 0.5f, 1.0f)}; std::vector index = {glm::uvec3(0, 1, 2), glm::uvec3(1, 2, 3)}; // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, // e.g. "--osp:debug" OSPError init_error = ospInit(&argc, argv); if (init_error != OSP_NO_ERROR) return init_error; // use scoped lifetimes of wrappers to release everything before ospShutdown() { // create and setup camera ospray::cpp::Camera camera("perspective"); camera.setParam("aspect", imgSize.x / (float)imgSize.y); camera.setParam("position", cam_pos); camera.setParam("direction", cam_view); camera.setParam("up", cam_up); camera.commit(); // commit each object to indicate modifications are done // create and setup model and mesh ospray::cpp::Geometry mesh("mesh"); mesh.setParam("vertex.position", ospray::cpp::CopiedData(vertex)); mesh.setParam("vertex.color", ospray::cpp::CopiedData(color)); mesh.setParam("index", ospray::cpp::CopiedData(index)); mesh.commit(); // put the mesh into a model ospray::cpp::GeometricModel model(mesh); model.commit(); // put the model into a group (collection of models) ospray::cpp::Group group; group.setParam("geometry", ospray::cpp::CopiedData(model)); group.commit(); // put the group into an instance (give the group a world transform) ospray::cpp::Instance instance(group); instance.commit(); // put the instance in the world ospray::cpp::World world; world.setParam("instance", ospray::cpp::CopiedData(instance)); // create and setup light for Ambient Occlusion ospray::cpp::Light light("ambient"); light.commit(); world.setParam("light", ospray::cpp::CopiedData(light)); world.commit(); // create renderer, choose Scientific Visualization renderer ospray::cpp::Renderer renderer("scivis"); // complete setup of renderer renderer.setParam("aoSamples", 1); renderer.setParam("backgroundColor", 1.0f); // white, transparent renderer.commit(); // create and setup framebuffer ospray::cpp::FrameBuffer framebuffer( imgSize.x, imgSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); framebuffer.clear(); // render one frame framebuffer.renderFrame(renderer, camera, world); // access framebuffer and write its content as PPM file uint32_t *fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); rkcommon::utility::writePPM("firstFrameCpp.ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); // render 10 more frames, which are accumulated to result in a better // converged image for (int frames = 0; frames < 10; frames++) framebuffer.renderFrame(renderer, camera, world); fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); rkcommon::utility::writePPM( "accumulatedFrameCpp.ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); ospray::cpp::PickResult res = framebuffer.pick(renderer, camera, world, 0.5f, 0.5f); if (res.hasHit) { std::cout << "Picked geometry [inst: " << res.instance.handle() << ", model: " << res.model.handle() << ", prim: " << res.primID << "]" << std::endl; } } ospShutdown(); return 0; } RenderKit-ospray-85af292/apps/utility/000077500000000000000000000000001464752671100177415ustar00rootroot00000000000000RenderKit-ospray-85af292/apps/utility/CMakeLists.txt000066400000000000000000000006301464752671100225000ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 if (NOT OSPRAY_ENABLE_APPS_TESTING) return() endif() add_executable(ospConvertRawToAMR ${OSPRAY_RESOURCE} ospConvertRawToAMR.cpp) target_link_libraries(ospConvertRawToAMR PRIVATE raw_to_amr ospray) ospray_sign_target(ospConvertRawToAMR) install(TARGETS ospConvertRawToAMR DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) RenderKit-ospray-85af292/apps/utility/ospConvertRawToAMR.cpp000066400000000000000000000126301464752671100241260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "rawToAMR.h" static const std::string description = R"description( Creates an adaptive mesh refinement (AMR) representation of the provided structured volume data. The input structured volume data is used as the highest refinement level (i.e. the finest resolution data). From this level, data that does not meet the user-provided variance threshold is discarded. The average of the discarded block is used in the next level down. This simulates the effect that an adaptive simulation would have created regions of higher refinement in the highly varying portions of the volume. )description"; static const std::string usage = R"usage([-h | --help] input_volume variable_type x_dim y_dim z_dim num_levels block_size refinement_factor threshold output_basename )usage"; static const std::string help = R"help( input_volume Structured volume in binary brick-of-data format (string filepath) variable_type Type of structured volume, must be exactly one of: float (string) x_dim X dimensions of the structured volume grid (int) y_dim Y dimensions of the structured volume grid (int) z_dim Z dimensions of the structured volume grid (int) num_levels Number of refinement levels to simulate (int) block_size Size of blocks at each level in terms of cells. Blocks are defined as cubes with this number of cells per edge. Note that refinement levels change the width of the cells, NOT the width of the blocks. Blocks will always be this provided size in cell extents, but the width of the cells will be smaller/larger depending on level. For example, a block of 4x4x4 cells at the highest refinement level will be converted into a single cell at the next lower level, which would be part of that level's block of 4x4x4 cells. (int) refinement_factor How much larger/smaller, in terms of cell extents, each level's grid will be. Note that this is independent of block_size above! For example, if the input data is a 512^3 grid, and block_size is 4^3, the highest refinement level will have a 128^3 block grid. If this value is 2, the next level will have a 64^3 block grid, but will still be comprised of 4^3 blocks. That is, the number of cells decreases from 512^3 to 256^3, and the cell width increases to accommodate. (int) threshold Variance threshold used to determine whether a block belongs to a higher refinement level. If the variance within a block is above this threshold, it remains at the current level. Otherwise, if the variance is low, this block would have not have been selected for mesh refinement by a numerical simulation, so this block is discarded at this level. (variable_type, converted to float) output_basename Basename for the output files. This application creates three files with different extensions, with this basename in common. (string) )help"; using namespace rkcommon::math; static std::string inFileName; static std::string format; static vec3i inDims; static int numLevels; static int blockSize; static int refinementLevel; static float threshold; static std::string outFileBase; bool parseArguments(int argc, char **argv) { if (argc != 11) { if (argc > 1 && (std::string(argv[1]) == "-h" || std::string(argv[1]) == "--help")) { std::cerr << description << std::endl; std::cerr << "Usage: " << argv[0] << " " << usage << std::endl; std::cerr << help << std::endl; } else { std::cerr << argc - 1 << " argument" << ((argc == 1 || argc > 2) ? "s " : " "); std::cerr << "provided, but 10 are needed" << std::endl; std::cerr << "Usage: " << argv[0] << " " << usage << std::endl; } return false; } inFileName = argv[1]; format = argv[2]; inDims.x = atoi(argv[3]); inDims.y = atoi(argv[4]); inDims.z = atoi(argv[5]); numLevels = atoi(argv[6]); blockSize = atoi(argv[7]); refinementLevel = atoi(argv[8]); threshold = atof(argv[9]); outFileBase = argv[10]; return true; } int main(int argc, char **argv) { bool parseSucceed = parseArguments(argc, argv); if (!parseSucceed) { return 1; } // ALOK: TODO: // support more than float std::vector in; if (format == "float") { in = ospray::amr::mmapRAW(inFileName, inDims); } else { throw std::runtime_error("unsupported input voxel format"); } std::vector blockBounds; std::vector refinementLevels; std::vector cellWidths; std::vector> brickData; ospray::amr::makeAMR(in, inDims, numLevels, blockSize, refinementLevel, threshold, blockBounds, refinementLevels, cellWidths, brickData); ospray::amr::outputAMR(outFileBase, blockBounds, refinementLevels, cellWidths, brickData, blockSize); return 0; } RenderKit-ospray-85af292/cmake/000077500000000000000000000000001464752671100163535ustar00rootroot00000000000000RenderKit-ospray-85af292/cmake/clang-format.cmake000066400000000000000000000013331464752671100217270ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # additional target to run clang-format on all source files set (EXCLUDE_DIRS ${CMAKE_SOURCE_DIR}/apps/external ${CMAKE_SOURCE_DIR}/build ${CMAKE_SOURCE_DIR}/ospray-doc ) # get all project files file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h *.hpp *.ih *.isph *.ispc) foreach (SOURCE_FILE ${ALL_SOURCE_FILES}) foreach (EXCLUDE_DIR ${EXCLUDE_DIRS}) string(FIND ${SOURCE_FILE} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND) if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1) list(REMOVE_ITEM ALL_SOURCE_FILES ${SOURCE_FILE}) endif() endforeach() endforeach() add_custom_target( format COMMAND clang-format -style=file -i ${ALL_SOURCE_FILES} ) RenderKit-ospray-85af292/cmake/compiler/000077500000000000000000000000001464752671100201655ustar00rootroot00000000000000RenderKit-ospray-85af292/cmake/compiler/clang.cmake000066400000000000000000000071051464752671100222560ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(OSPRAY_CXX_FLAGS "-fno-strict-aliasing -Wno-narrowing") if(OSPRAY_STRICT_BUILD) # OK to turn off. set(OSPRAY_CXX_FLAGS "-Wno-c++98-compat-pedantic ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-documentation ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-documentation-unknown-command ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-zero-as-null-pointer-constant ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-newline-eof ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-keyword-macro ${OSPRAY_CXX_FLAGS}") #useful for unit testing set(OSPRAY_CXX_FLAGS "-Wno-undef ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-header-hygiene ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-covered-switch-default ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-date-time ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-unsafe-buffer-usage ${OSPRAY_CXX_FLAGS}") #we use pointer arithmetic on buffers set(OSPRAY_CXX_FLAGS "-Wno-reserved-identifier ${OSPRAY_CXX_FLAGS}") #used in autogenerated ISPC headers # Should try to fix and remove... set(OSPRAY_CXX_FLAGS "-Wno-unknown-warning-option ${OSPRAY_CXX_FLAGS}") #don't warn if pragmas are unknown set(OSPRAY_CXX_FLAGS "-Wno-conversion ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-reserved-id-macro ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-double-promotion ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-used-but-marked-unused ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-old-style-cast ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-missing-noreturn ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-missing-prototypes ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-shift-sign-overflow ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-padded ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-shadow-field-in-constructor ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-weak-template-vtables ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-weak-vtables ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-exit-time-destructors ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-global-constructors ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-unused-template ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-switch-enum ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-float-equal ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-cast-align ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-deprecated ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-mismatched-tags ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-disabled-macro-expansion ${OSPRAY_CXX_FLAGS}") #pesky 'stb_image.h'... set(OSPRAY_CXX_FLAGS "-Wno-over-aligned ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-shadow ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-format-nonliteral ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-cast-qual ${OSPRAY_CXX_FLAGS}") #Embree v3.x issue set(OSPRAY_CXX_FLAGS "-Wno-extra-semi-stmt ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-shadow-field ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-alloca ${OSPRAY_CXX_FLAGS}") set(OSPRAY_CXX_FLAGS "-Wno-cast-function-type-strict ${OSPRAY_CXX_FLAGS}") #ISPC exported functions casts # Options selected for Clang 5.0+ set(OSPRAY_CXX_FLAGS "-Weverything ${OSPRAY_CXX_FLAGS}") endif() if(OSPRAY_WARN_AS_ERRORS) set(OSPRAY_CXX_FLAGS "-Werror ${OSPRAY_CXX_FLAGS}") endif() set(CMAKE_CXX_FLAGS "${OSPRAY_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") if (APPLE) set(CMAKE_CXX_FLAGS "-mmacosx-version-min=10.9 ${CMAKE_CXX_FLAGS}") # we only use MacOSX 10.9 features endif() RenderKit-ospray-85af292/cmake/compiler/dpcpp.cmake000066400000000000000000000112741464752671100223020ustar00rootroot00000000000000## Copyright 2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # FIXME CMake does not always set "-x c++" to compile .ispc files as C++ (SYCL) # code, despite LANGUAGE is set for them set(OSPRAY_COMPILER_NEEDS_X_CPP TRUE) get_filename_component(SYCL_COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME_WE) if (WIN32 AND (SYCL_COMPILER_NAME STREQUAL "icx" OR SYCL_COMPILER_NAME STREQUAL "icpx")) include(msvc) # icx on Windows behaves like msvc set(CMAKE_CXX_FLAGS "/fp:precise ${CMAKE_CXX_FLAGS}") set(OSPRAY_COMPILER_NEEDS_X_CPP FALSE) # icx on Win does not support "-x" set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /Qoption,link,/DEPENDENTLOADFLAG:0x2000") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /Qoption,link,/DEPENDENTLOADFLAG:0x2000") else() include(clang) # DPCPP compiler is based on Clang, so bring in clang options set(CMAKE_CXX_FLAGS "-ffp-model=precise ${CMAKE_CXX_FLAGS}") endif() # enable -static-intel # Note: this doesn't seem to be used/relevant to the DPC++ compiler? Maybe just the # DPCPP release one? The nightly clang compiler doesn't recognize this flag #set(CMAKE_EXE_LINKER_FLAGS "-static-intel ${CMAKE_EXE_LINKER_FLAGS}") #set(CMAKE_SHARED_LINKER_FLAGS "-static-intel ${CMAKE_SHARED_LINKER_FLAGS}") #set(CMAKE_MODULE_LINKER_FLAGS "-static-intel ${CMAKE_MODULE_LINKER_FLAGS}") # SYCL flags to match Embree list(APPEND OSPRAY_CXX_FLAGS_SYCL -fsycl -fsycl-unnamed-lambda -Xclang -fsycl-allow-func-ptr -Wno-mismatched-tags -Wno-pessimizing-move -Wno-reorder -Wno-unneeded-internal-declaration -Wno-delete-non-abstract-non-virtual-dtor -Wno-dangling-field -Wno-unknown-pragmas -Wno-logical-op-parentheses ) # IGC options from Embree # This works around some IGC bug in spill compression # TODO: Still true? list(APPEND OSPRAY_IGC_OPTIONS "VISAOptions=-scratchAllocForStackInKB 128") # Allow printf inside indirectly callable function, right now I have this in all for testing # TODO: Should only enable for debug builds, and this needs to be done using a generator expression # if we want to support it in VS #list(APPEND OSPRAY_IGC_OPTIONS "ForceInlineStackCallWithImplArg=0" "EnableGlobalStateBuffer=1") option(OSPRAY_IGC_ENABLE_ZE_BINARY "Enable ZEBinary (for GTPin)" OFF) mark_as_advanced(OSPRAY_IGC_ENABLE_ZE_BINARY) if (OSPRAY_IGC_ENABLE_ZE_BINARY) list(APPEND OSPRAY_IGC_OPTIONS "EnableZEBinary=1") endif() # This significantly improves compile times on 17028 and up, though also impacts performance some option(OSPRAY_IGC_FAST_COMPILE "Pass flags to improve compilation speed at the cost of some optimization" OFF) mark_as_advanced(OSPRAY_IGC_FAST_COMPILE) if (OSPRAY_IGC_FAST_COMPILE) set(OSPRAY_IGC_FAST_COMPILE_UNIT_SIZE_THRESHOLD "18000" CACHE STRING "Set the partition unit unit size threshold (default 18000)") list(APPEND OSPRAY_IGC_OPTIONS "PartitionUnit=1") list(APPEND OSPRAY_IGC_OPTIONS "UnitSizeThreshold=${OSPRAY_IGC_FAST_COMPILE_UNIT_SIZE_THRESHOLD}") endif() #list(APPEND OSPRAY_IGC_OPTIONS "ForceOCLSIMDWidth=8") # Development option to dump shaders, when we compile AOT this has to be done at build time option(OSPRAY_IGC_DUMP_SHADERS "Dump IGC shaders during build" OFF) mark_as_advanced(OSPRAY_IGC_DUMP_SHADERS) if (OSPRAY_IGC_DUMP_SHADERS) list(APPEND OSPRAY_IGC_OPTIONS "ShaderDumpEnable=1" "ShowFullVectorsInShaderDumps=1" "DumpToCustomDir=${PROJECT_BINARY_DIR}/ospray_igc_shader_dump") endif() # enables support for buffers larger than 4GB list(APPEND OSPRAY_OCL_OPTIONS -cl-intel-greater-than-4GB-buffer-required) list(APPEND OSPRAY_OCL_OTHER_OPTIONS -cl-intel-force-global-mem-allocation -cl-intel-no-local-to-generic) if (CMAKE_BUILD_TYPE MATCHES "Release") list(APPEND OSPRAY_OCL_OTHER_OPTIONS -O2) elseif (CMAKE_BUILD_TYPE MATCHES "Debug") # SYCL applies some optimization flags by default, make sure we're # really building with no optimizations for debug builds. RelWithDebInfo # builds currently hit a compiler crash. list(APPEND OSPRAY_OCL_OTHER_OPTIONS -O0) endif() # Large GRF mode option(OSPRAY_SYCL_LARGEGRF "Enable SYCL Large GRF Support" ON) mark_as_advanced(OSPRAY_SYCL_LARGEGRF) if (OSPRAY_SYCL_LARGEGRF) list(APPEND OSPRAY_OCL_OTHER_OPTIONS "-ze-opt-large-register-file") endif() string(REPLACE ";" "," OSPRAY_IGC_OPTIONS_STR "${OSPRAY_IGC_OPTIONS}") set(OSPRAY_OCL_OPTIONS_STR "${OSPRAY_OCL_OPTIONS}") string(REPLACE ";" " " OSPRAY_OCL_OPTIONS_STR "${OSPRAY_OCL_OPTIONS}") set(OSPRAY_OCL_OTHER_OPTIONS_STR "${OSPRAY_OCL_OTHER_OPTIONS}") string(REPLACE ";" " " OSPRAY_OCL_OTHER_OPTIONS_STR "${OSPRAY_OCL_OTHER_OPTIONS}") set(OSPRAY_LINKER_FLAGS_SYCL -fsycl -Xsycl-target-backend=spir64 "${OSPRAY_OCL_OPTIONS_STR} -options \"${OSPRAY_OCL_OTHER_OPTIONS_STR} -igc_opts='${OSPRAY_IGC_OPTIONS_STR}'\"") RenderKit-ospray-85af292/cmake/compiler/gcc.cmake000066400000000000000000000012151464752671100217220ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(OSPRAY_CXX_FLAGS "-fno-strict-aliasing -Wno-narrowing -Wno-unknown-pragmas") if(OSPRAY_STRICT_BUILD) # Should try to fix and remove... set(OSPRAY_CXX_FLAGS "-Wno-aligned-new ${OSPRAY_CXX_FLAGS}") # Options selected for GCC 7.1+ set(OSPRAY_CXX_FLAGS "-Wall ${OSPRAY_CXX_FLAGS}") endif() if(OSPRAY_WARN_AS_ERRORS) set(OSPRAY_CXX_FLAGS "-Werror ${OSPRAY_CXX_FLAGS}") endif() set(CMAKE_CXX_FLAGS "${OSPRAY_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") if (APPLE) set(CMAKE_CXX_FLAGS "-mmacosx-version-min=10.9 ${CMAKE_CXX_FLAGS}") # we only use MacOSX 10.9 features endif() RenderKit-ospray-85af292/cmake/compiler/icc.cmake000066400000000000000000000014721464752671100217310ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(OSPRAY_CXX_FLAGS "-fno-strict-aliasing -no-ansi-alias -Wno-unknown-pragmas") if (OSPRAY_STRICT_BUILD) set(OSPRAY_CXX_FLAGS "-Wall ${OSPRAY_CXX_FLAGS}") endif() set(CMAKE_CXX_FLAGS "${OSPRAY_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") if (APPLE) set(CMAKE_SHARED_LINKER_FLAGS "-dynamiclib ${CMAKE_SHARED_LINKER_FLAGS_INIT}") set(CMAKE_CXX_FLAGS "-mmacosx-version-min=10.8 ${CMAKE_CXX_FLAGS}") # we only use MacOSX 10.8 features set(CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}") # link against C++11 stdlib else() # avoid exporting ICC specific symbols from OSPRay set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--exclude-libs=ALL ${CMAKE_SHARED_LINKER_FLAGS}") endif() # enable -static-intel set(CMAKE_CXX_FLAGS "-static-intel ${CMAKE_CXX_FLAGS}") RenderKit-ospray-85af292/cmake/compiler/ispc.cmake000066400000000000000000000255411464752671100221340ustar00rootroot00000000000000## Copyright 2024 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ############################################################################### ## Generic ISPC macros/options ################################################ ############################################################################### set(ISPC_INCLUDE_DIR "") macro (include_directories_ispc) list(APPEND ISPC_INCLUDE_DIR ${ARGN}) endmacro () set(ISPC_DEFINITIONS "") macro (add_definitions_ispc) list(APPEND ISPC_DEFINITIONS ${ARGN}) endmacro () ############################################################################### ## CPU specific macros/options ################################################ ############################################################################### ## Find ISPC ## find_program(ISPC_EXECUTABLE ispc HINTS ${ISPC_DIR_HINT} DOC "Path to the ISPC executable.") if (NOT ISPC_EXECUTABLE) message(FATAL_ERROR "Could not find ISPC. Exiting.") else() # Execute "ispc --version" and parse the version execute_process(COMMAND ${ISPC_EXECUTABLE} "--version" OUTPUT_VARIABLE ISPC_INFO) string(REGEX MATCH "(.*), ([0-9]*\.[0-9]*\.[0-9]*[a-z]*) (.*)" _ ${ISPC_INFO}) set(ISPC_VERSION ${CMAKE_MATCH_2}) message(STATUS "Found ISPC v${ISPC_VERSION}: ${ISPC_EXECUTABLE}") # Execute "ispc --help" and parse supported archs execute_process(COMMAND ${ISPC_EXECUTABLE} "--help" OUTPUT_VARIABLE ISPC_HELP) string(REGEX MATCH "--arch={((([a-z,0-9,-])+, |([a-z,0-9,-])+)+)}" _ ${ISPC_HELP}) set(ISPC_ARCHS ${CMAKE_MATCH_1}) if ("${ISPC_ARCHS}" STREQUAL "") message(WARNING "Can't determine ISPC supported architectures.") else() message(STATUS "ISPC supports: ${ISPC_ARCHS}") string(REPLACE ", " ";" ISPC_ARCHS_LIST ${ISPC_ARCHS}) endif() endif() ## ISPC config options ## set(ISPC_ADDRESSING 32 CACHE STRING "32 vs 64 bit addressing in ispc") set_property(CACHE ISPC_ADDRESSING PROPERTY STRINGS 32 64) mark_as_advanced(ISPC_ADDRESSING) macro(define_ispc_supported_arch ARCH_NAME ARCH_FILTER) set(ISPC_ARCHS_${ARCH_NAME}_LIST ${ISPC_ARCHS_LIST}) list(FILTER ISPC_ARCHS_${ARCH_NAME}_LIST INCLUDE REGEX ${ARCH_FILTER}) list(LENGTH ISPC_ARCHS_${ARCH_NAME}_LIST ARCH_LENGTH) if (${ARCH_LENGTH} GREATER 0) set(ISPC_${ARCH_NAME}_ENABLED TRUE) endif() endmacro() define_ispc_supported_arch(X86 "x86|x86-64") define_ispc_supported_arch(ARM "arm|aarch64") define_ispc_supported_arch(XE "xe64") macro(define_ispc_isa_options ISA_NAME) set(ISPC_TARGET_${ISA_NAME} ${ARGV1} CACHE STRING "ispc target used for ${ISA_NAME} ISA") set_property(CACHE ISPC_TARGET_${ISA_NAME} PROPERTY STRINGS ${ARGN} NONE) #mark_as_advanced(ISPC_TARGET_${ISA_NAME}) endmacro() if (ISPC_X86_ENABLED) define_ispc_isa_options(SSE4 sse4-i32x4 sse4-i32x8 sse4-i16x8 sse4-i8x16) define_ispc_isa_options(AVX avx1-i32x8 avx1-i32x4 avx1-i32x16 avx1-i64x4) define_ispc_isa_options(AVX2 avx2-i32x8 avx2-i32x4 avx2-i32x16 avx2-i64x4) define_ispc_isa_options(AVX512KNL avx512knl-x16) define_ispc_isa_options(AVX512SKX avx512skx-x16 avx512skx-x8) define_ispc_isa_options(AVX512SPR avx512spr-x16 avx512spr-x8) endif() macro(append_ispc_target_list ISA_NAME) set(_TARGET_NAME ISPC_TARGET_${ISA_NAME}) if (NOT ${_TARGET_NAME} STREQUAL "NONE") list(APPEND ISPC_TARGET_LIST ${${_TARGET_NAME}}) endif() unset(_TARGET_NAME) endmacro() unset(ISPC_TARGET_LIST) if (ISPC_X86_ENABLED) append_ispc_target_list(SSE4) append_ispc_target_list(AVX) append_ispc_target_list(AVX2) append_ispc_target_list(AVX512KNL) append_ispc_target_list(AVX512SKX) if (NOT APPLE) append_ispc_target_list(AVX512SPR) endif() endif() ## Macros ## macro (ispc_read_dependencies ISPC_DEPENDENCIES_FILE) set(ISPC_DEPENDENCIES "") if (EXISTS ${ISPC_DEPENDENCIES_FILE}) file(READ ${ISPC_DEPENDENCIES_FILE} contents) string(REPLACE " " ";" contents "${contents}") string(REPLACE ";" "\\\\;" contents "${contents}") string(REPLACE "\n" ";" contents "${contents}") foreach(dep ${contents}) if (EXISTS ${dep}) set(ISPC_DEPENDENCIES ${ISPC_DEPENDENCIES} ${dep}) endif (EXISTS ${dep}) endforeach(dep ${contents}) endif () endmacro() macro (ispc_compile) cmake_parse_arguments(ISPC_COMPILE "" "TARGET" "" ${ARGN}) set(ISPC_ADDITIONAL_ARGS "") if (OSPRAY_STRICT_BUILD) list(APPEND ISPC_ADDITIONAL_ARGS --wno-perf) else() list(APPEND ISPC_ADDITIONAL_ARGS --woff) endif() # Check if CPU target is passed externally if (NOT ISPC_TARGET_CPU) set(ISPC_TARGETS ${ISPC_TARGET_LIST}) else() set(ISPC_TARGETS ${ISPC_TARGET_CPU}) endif() set(ISPC_TARGET_EXT ${CMAKE_CXX_OUTPUT_EXTENSION}) string(REPLACE ";" "," ISPC_TARGET_ARGS "${ISPC_TARGETS}") if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(ISPC_ARCHITECTURE "aarch64") else() set(ISPC_ARCHITECTURE "x86-64") endif() else() set(ISPC_ARCHITECTURE "x86") endif() file(RELATIVE_PATH ISPC_TARGET_DIR_RELATIVE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) set(ISPC_TARGET_DIR ${CMAKE_BINARY_DIR}/${ISPC_TARGET_DIR_RELATIVE}) include_directories(${ISPC_TARGET_DIR}) if(ISPC_INCLUDE_DIR) string(REPLACE ";" ";-I;" ISPC_INCLUDE_DIR_PARMS "${ISPC_INCLUDE_DIR}") set(ISPC_INCLUDE_DIR_PARMS "-I" ${ISPC_INCLUDE_DIR_PARMS}) endif() if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE "Release") endif() #CAUTION: -O0/1 -g with ispc seg faults set(ISPC_FLAGS_DEBUG "-g" CACHE STRING "ISPC Debug flags") mark_as_advanced(ISPC_FLAGS_DEBUG) set(ISPC_FLAGS_RELEASE "-O3" CACHE STRING "ISPC Release flags") mark_as_advanced(ISPC_FLAGS_RELEASE) set(ISPC_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "ISPC Release with Debug symbols flags") mark_as_advanced(ISPC_FLAGS_RELWITHDEBINFO) if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") set(ISPC_OPT_FLAGS ${ISPC_FLAGS_RELEASE}) elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(ISPC_OPT_FLAGS ${ISPC_FLAGS_DEBUG}) elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") set(ISPC_OPT_FLAGS ${ISPC_FLAGS_RELWITHDEBINFO}) else () message(FATAL_ERROR "CMAKE_BUILD_TYPE (${CMAKE_BUILD_TYPE}) allows only the following values: Debug;Release;RelWithDebInfo") endif() # turn space separated list into ';' separated list string(REPLACE " " ";" ISPC_OPT_FLAGS "${ISPC_OPT_FLAGS}") if (NOT WIN32) list(APPEND ISPC_ADDITIONAL_ARGS --pic) endif() if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") list(APPEND ISPC_ADDITIONAL_ARGS --opt=disable-assertions) endif() # Also set the target-local include directories and defines if # we were given a target name set(ISPC_INCLUDE_DIRS_EXPR "") set(ISPC_COMPILE_DEFINITIONS_EXPR "") if (NOT "${ISPC_COMPILE_TARGET}" STREQUAL "") set(ISPC_INCLUDE_DIRS_EXPR "$") set(ISPC_COMPILE_DEFINITIONS_EXPR "$") endif() set(ISPC_OBJECTS "") foreach(src ${ISPC_COMPILE_UNPARSED_ARGUMENTS}) get_filename_component(fname ${src} NAME_WE) # The src_relpath will usually be the same as getting the DIRECTORY # component of the src file name, but we go through the full path # computation path to handle cases where the src name is an absolute # file path in some other location, where we need to compute a path to get_filename_component(src_dir ${src} ABSOLUTE) file(RELATIVE_PATH src_relpath ${CMAKE_CURRENT_LIST_DIR} ${src_dir}) get_filename_component(src_relpath ${src_relpath} DIRECTORY) # Remove any relative paths up from the relative path string(REPLACE "../" "_/" src_relpath "${src_relpath}") set(outdir "${ISPC_TARGET_DIR}/${src_relpath}") set(outdir_relative "${ISPC_TARGET_DIR_RELATIVE}/${src_relpath}") set(input ${CMAKE_CURRENT_SOURCE_DIR}/${src}) set(ISPC_DEPENDENCIES_FILE ${outdir}/${fname}.dev.idep) ispc_read_dependencies(${ISPC_DEPENDENCIES_FILE}) set(results "${outdir}/${fname}.dev${ISPC_TARGET_EXT}") # if we have multiple targets add additional object files list(LENGTH ISPC_TARGETS NUM_TARGETS) if (NUM_TARGETS GREATER 1) foreach(target ${ISPC_TARGETS}) string(REGEX REPLACE "-(i(8|16|32|64))?x(4|8|16|32|64)" "" target ${target}) string(REPLACE "avx1" "avx" target ${target}) list(APPEND results "${outdir}/${fname}.dev_${target}${ISPC_TARGET_EXT}") endforeach() endif() # use relative path for generated header file, because the path is # included as comment and the header will be distributed set(headerfile "${outdir}/${fname}_ispc.h") file(RELATIVE_PATH headerfile ${CMAKE_CURRENT_BINARY_DIR} ${headerfile}) add_custom_command( OUTPUT ${results} ${outdir}/${fname}_ispc.h COMMAND ${CMAKE_COMMAND} -E make_directory ${outdir} COMMAND ${ISPC_EXECUTABLE} ${ISPC_DEFINITIONS} -I ${CMAKE_CURRENT_SOURCE_DIR} "$<$:-I$>" ${ISPC_INCLUDE_DIR_PARMS} "$<$:-D$>" --arch=${ISPC_ARCHITECTURE} --addressing=${ISPC_ADDRESSING} ${ISPC_OPT_FLAGS} --target=${ISPC_TARGET_ARGS} --opt=fast-math ${ISPC_ADDITIONAL_ARGS} -h ${headerfile} -MMM ${ISPC_DEPENDENCIES_FILE} -o ${outdir}/${fname}.dev${ISPC_TARGET_EXT} ${input} DEPENDS ${input} ${ISPC_DEPENDENCIES} COMMENT "Building ISPC object ${outdir_relative}/${fname}.dev${ISPC_TARGET_EXT}" COMMAND_EXPAND_LISTS VERBATIM ) list(APPEND ISPC_OBJECTS ${results}) # avoid race conditions if multiple targets compile the same ispc source file string(REPLACE "/" "_" dep_target "compile__${src}") if (NOT TARGET ${dep_target}) add_custom_target(${dep_target} DEPENDS ${results}) endif() list(APPEND ISPC_DEPENDENCY_TARGETS ${dep_target}) endforeach() endmacro() ############################################################################### ## Generic kernel compilation ################################################# ############################################################################### # Kept for backwards compatibility with existing CPU projects function(ispc_target_add_sources name) ## Split-out C/C++ from ISPC files ## set(ISPC_SOURCES "") get_property(TARGET_SOURCES TARGET ${name} PROPERTY SOURCES) foreach(src ${ARGN}) get_filename_component(ext ${src} EXT) if (ext STREQUAL ".ispc") list(APPEND ISPC_SOURCES ${src}) else() list(APPEND TARGET_SOURCES ${src}) endif() endforeach() if (ISPC_SOURCES) ispc_compile(${ISPC_SOURCES}) list(APPEND TARGET_SOURCES ${ISPC_OBJECTS}) add_dependencies(${name} ${ISPC_DEPENDENCY_TARGETS}) endif() set_target_properties(${name} PROPERTIES SOURCES "${TARGET_SOURCES}") endfunction() RenderKit-ospray-85af292/cmake/compiler/msvc.cmake000066400000000000000000000040261464752671100221410ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMMON_CXX_FLAGS "/EHsc /MP /GR /bigobj") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS} /Ox /fp:fast /Oi /Gy ") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS} /Ox /fp:fast /Oi /Gy ") # optionally use static runtime library option(USE_STATIC_RUNTIME "Use the static version of the C/C++ runtime library.") mark_as_advanced(USE_STATIC_RUNTIME) if (USE_STATIC_RUNTIME) foreach(FLAG CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO ) string(REPLACE "/MD" "/MT" ${FLAG} ${${FLAG}}) endforeach() else() # remove libmmd dependency if (OSPRAY_COMPILER_ICC) # prevents sin(x),cos(x) -> sincos(x) optimization, which is only present in libmmd foreach(FLAG CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO ) string(APPEND ${FLAG} " /Qfast-transcendentals-") endforeach() # use default math lib instead of libmmd[d] string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /nodefaultlib:libmmdd.lib") string(APPEND CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO " /nodefaultlib:libmmd.lib") string(APPEND CMAKE_EXE_LINKER_FLAGS_RELEASE " /nodefaultlib:libmmd.lib") string(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG " /nodefaultlib:libmmdd.lib") string(APPEND CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO " /nodefaultlib:libmmd.lib") string(APPEND CMAKE_SHARED_LINKER_FLAGS_RELEASE " /nodefaultlib:libmmd.lib") endif() endif() if (OSPRAY_COMPILER_MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEPENDENTLOADFLAG:0x2000") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEPENDENTLOADFLAG:0x2000") endif() RenderKit-ospray-85af292/cmake/ospray_cmake_config.cmake000066400000000000000000000034401464752671100233600ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # Version header configure_file( ${CMAKE_SOURCE_DIR}/ospray/version.h.in ${CMAKE_BINARY_DIR}/ospray/version.h @ONLY ) install(FILES ${CMAKE_BINARY_DIR}/ospray/version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray COMPONENT devel ) # CMake config module set(OSPRAY_MODULE_CONFIG_INPUT_DIR ${CMAKE_SOURCE_DIR}/cmake/ospray_cmake_config) set(OSPRAY_MODULE_CONFIG_OUTPUT_DIR ${CMAKE_BINARY_DIR}/cmake) set(OSPRAY_MODULE_FILES osprayConfig.cmake osprayConfigVersion.cmake osprayUse.cmake ) ## find relative path to make package relocatable # this is a bit involved to handle these cases: # - CMAKE_INSTALL_LIBDIR is overridden by the user # - CMAKE_INSTALL_LIBDIR contains multiple levels for Debian multiarch support if (IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") set(ABS_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") else() get_filename_component(ABS_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) endif() if (IS_ABSOLUTE "${OSPRAY_CMAKECONFIG_DIR}") MESSAGE(WARNING "CMAKE_INSTALL_LIBDIR needs to be a relative path!") set(ABS_CMAKECONFIG_DIR "${OSPRAY_CMAKECONFIG_DIR}") else() set(ABS_CMAKECONFIG_DIR "${ABS_INSTALL_PREFIX}/${OSPRAY_CMAKECONFIG_DIR}") endif() file(RELATIVE_PATH OSPRAY_RELATIV_ROOT_DIR "${ABS_CMAKECONFIG_DIR}" "${ABS_INSTALL_PREFIX}" ) foreach(MODULE_FILE ${OSPRAY_MODULE_FILES}) LIST(APPEND OSPRAY_MODULE_INSTALL_FILES ${OSPRAY_MODULE_CONFIG_OUTPUT_DIR}/${MODULE_FILE} ) configure_file( ${OSPRAY_MODULE_CONFIG_INPUT_DIR}/${MODULE_FILE}.in ${OSPRAY_MODULE_CONFIG_OUTPUT_DIR}/${MODULE_FILE} @ONLY ) endforeach() install(FILES ${OSPRAY_MODULE_INSTALL_FILES} ${CMAKE_SOURCE_DIR}/cmake/ospray_macros.cmake DESTINATION ${OSPRAY_CMAKECONFIG_DIR} COMPONENT devel ) RenderKit-ospray-85af292/cmake/ospray_cmake_config/000077500000000000000000000000001464752671100223555ustar00rootroot00000000000000RenderKit-ospray-85af292/cmake/ospray_cmake_config/osprayConfig.cmake.in000066400000000000000000000176071464752671100264420ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # Called if we failed to find OSPRay or any of it's required dependencies, # unsets all public (designed to be used externally) variables and reports # error message at priority depending upon [REQUIRED/QUIET/] argument. macro(ospray_report_not_found REASON_MSG) unset(OSPRAY_FOUND) unset(OSPRAY_INCLUDE_DIRS) unset(OSPRAY_LIBRARIES) # Reset the CMake module path to its state when this script was called. set(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH}) # Note _FIND_[REQUIRED/QUIETLY] variables defined by FindPackage() # use the camelcase library name, not uppercase. if (OSPRAY_FIND_QUIETLY) set(MSG_TYPE STATUS) elseif(OSPRAY_FIND_REQUIRED) set(MSG_TYPE FATAL_ERROR) else() # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error # that prevents generation, but continues configuration. set(MSG_TYPE SEND_ERROR) endif() message(${MSG_TYPE} "Failed to find OSPRay - " ${REASON_MSG} ${ARGN}) return() endmacro() ############################################################################### # Attempt to find OSPRay # Get the (current, i.e. installed) directory containing this file. set(CURRENT_CONFIG_INSTALL_DIR ${CMAKE_CURRENT_LIST_DIR}) # Record the state of the CMake module path when this script was called so # that we can ensure that we leave it in the same state on exit as it was # on entry, but modify it locally. set(OSPRAY_CALLERS_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) # Reset CMake module path to the installation directory of this script, # thus we will use the FindPackage() scripts shipped with OSPRay to find # OSPRay's dependencies, even if the user has equivalently named FindPackage() # scripts in their project. set(CMAKE_MODULE_PATH ${CURRENT_CONFIG_INSTALL_DIR}) # Build the absolute root install directory as a relative path (determined when # OSPRay was configured & built) from the current install directory for this # this file. This allows for the install tree to be relocated, after OSPRay # was built, outside of CMake. get_filename_component(CURRENT_ROOT_INSTALL_DIR ${CURRENT_CONFIG_INSTALL_DIR}/@OSPRAY_RELATIV_ROOT_DIR@ ABSOLUTE ) if (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR}) ospray_report_not_found( "OSPRay install root: ${CURRENT_ROOT_INSTALL_DIR}, " "determined from relative path from osprayConfig.cmake install location: " "${CURRENT_CONFIG_INSTALL_DIR}, does not exist. Either the install " "directory was deleted, or the install tree was only partially relocated " "outside of CMake after OSPRay was built.") endif() set(OSPRAY_ROOT ${CURRENT_ROOT_INSTALL_DIR}) # Set the include directories for OSPRay (itself). set(OSPRAY_INCLUDE_DIR "${OSPRAY_ROOT}/include") if (NOT EXISTS ${OSPRAY_INCLUDE_DIR}/ospray/version.h) ospray_report_not_found( "OSPRay install root: ${OSPRAY_ROOT}, " "determined from relative path from osprayConfg.cmake install location: " "${CURRENT_CONFIG_INSTALL_DIR}, does not contain OSPRay headers. " "Either the install directory was deleted, or the install tree was only " "partially relocated outside of CMake after OSPRay was built.") endif() ############################################################################### # OSPRay build configuration set(OSPRAY_VERSION @OSPRAY_VERSION@) set(OSPRAY_SOVERSION @OSPRAY_SOVERSION@) set(OSPRAY_INSTALL_DEPENDENCIES @OSPRAY_INSTALL_DEPENDENCIES@) set(OSPRAY_BUILD_DEBUG @OSPRAY_BUILD_DEBUG@) set(OSPRAY_BUILD_RELWITHDEBINFO @OSPRAY_BUILD_RELWITHDEBINFO@) set(OSPRAY_BUILD_RELEASE @OSPRAY_BUILD_RELEASE@) set(OSPRAY_COMPILER_ICC @OSPRAY_COMPILER_ICC@) set(OSPRAY_COMPILER_GCC @OSPRAY_COMPILER_GCC@) set(OSPRAY_COMPILER_CLANG @OSPRAY_COMPILER_CLANG@) set(OSPRAY_COMPILER_MSVC @OSPRAY_COMPILER_MSVC@) set(OSPRAY_COMPILER_DPCPP @OSPRAY_COMPILER_DPCPP@) set(OSPRAY_ISPC_TARGET_LIST @OSPRAY_ISPC_TARGET_LIST@) set(OSPRAY_ISPC_ADDRESSING @OSPRAY_ISPC_ADDRESSING@) set(OSPRAY_ENABLE_VOLUMES @OSPRAY_ENABLE_VOLUMES@) set(OSPRAY_TILE_SIZE @OSPRAY_TILE_SIZE@) set(RKCOMMON_VERSION_REQUIRED @RKCOMMON_VERSION_REQUIRED@) set(EMBREE_VERSION_REQUIRED @EMBREE_VERSION_REQUIRED@) if (OSPRAY_ENABLE_VOLUMES) set(OPENVKL_VERSION_REQUIRED @OPENVKL_VERSION_REQUIRED@) endif() if (OSPRAY_MODULE_DENOISER) set(OIDN_VERSION_REQUIRED @OIDN_VERSION_REQUIRED@) endif() ############################################################################### # OSPRay dependencies # Save state set(OSPRAY_CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}) set(OSPRAY_CURRENT_CONFIG_INSTALL_DIR ${CURRENT_CONFIG_INSTALL_DIR}) set(OSPRAY_CURRENT_ROOT_INSTALL_DIR ${CURRENT_ROOT_INSTALL_DIR}) # Setup library path vars if (WIN32) set(LIBRARY_PATH_PREFIX ${OSPRAY_ROOT}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_IMPORT_LIBRARY_PREFIX}) set(LIBRARY_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX}) else() set(LIBRARY_PATH_PREFIX ${OSPRAY_ROOT}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}) set(LIBRARY_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) endif() # Include macros for finding embree include(ospray_macros) if (OSPRAY_INSTALL_DEPENDENCIES) # Dependencies installed with OSPRay if (WIN32) file(GLOB_RECURSE EMBREE_LIBRARY ${LIBRARY_PATH_PREFIX}embree*.lib) file(GLOB_RECURSE RKCOMMON_LIBRARY ${LIBRARY_PATH_PREFIX}rkcommon*.lib) if (OSPRAY_ENABLE_VOLUMES) file(GLOB_RECURSE OPENVKL_LIBRARY ${LIBRARY_PATH_PREFIX}openvkl*.lib) endif() if (OSPRAY_MODULE_DENOISER) file(GLOB_RECURSE OIDN_LIBRARY ${LIBRARY_PATH_PREFIX}OpenImageDenoise*.lib) endif() else() file(GLOB_RECURSE EMBREE_LIBRARY ${LIBRARY_PATH_PREFIX}embree*) file(GLOB_RECURSE RKCOMMON_LIBRARY ${LIBRARY_PATH_PREFIX}rkcommon*) if (OSPRAY_MODULE_DENOISER) file(GLOB_RECURSE OIDN_LIBRARY ${LIBRARY_PATH_PREFIX}OpenImageDenoise*) endif() endif() else() # Find existing Dependencies on the machine if (NOT TARGET embree) ospray_find_embree(${EMBREE_VERSION_REQUIRED} TRUE) ospray_verify_embree_features() endif() if (NOT TARGET rkcommon::rkcommon) find_dependency(rkcommon ${RKCOMMON_VERSION_REQUIRED}) get_target_property(RKCOMMON_INCLUDE_DIRS rkcommon::rkcommon INTERFACE_INCLUDE_DIRECTORIES) endif() if (OSPRAY_ENABLE_VOLUMES) if (NOT TARGET openvkl::openvkl) ospray_find_openvkl(${OPENVKL_VERSION_REQUIRED} TRUE) endif() set(OPENVKL_LIBRARY openvkl::openvkl) endif() if (OSPRAY_MODULE_DENOISER) if (NOT TARGET OpenImageDenoise) find_dependency(OpenImageDenoise ${OIDN_VERSION_REQUIRED} TRUE) endif() set(OIDN_LIBRARY OpenImageDenoise) endif() set(EMBREE_LIBRARY embree) set(RKCOMMON_LIBRARY rkcommon::rkcommon) endif() # Restore state set(CMAKE_CURRENT_LIST_DIR ${OSPRAY_CMAKE_CURRENT_LIST_DIR}) set(CURRENT_CONFIG_INSTALL_DIR ${OSPRAY_CURRENT_CONFIG_INSTALL_DIR}) set(CURRENT_ROOT_INSTALL_DIR ${OSPRAY_CURRENT_ROOT_INSTALL_DIR}) ############################################################################### # Finish OSPRay # Include target exports include(${CMAKE_CURRENT_LIST_DIR}/ospray_Exports.cmake) # Add missing targets to libraries set_target_properties(ospray::ospray PROPERTIES INTERFACE_LINK_LIBRARIES "${RKCOMMON_LIBRARY}") set_target_properties(ospray::ospray_module_cpu PROPERTIES INTERFACE_LINK_LIBRARIES "ospray::ospray;${OPENVKL_LIBRARY};${EMBREE_LIBRARY}") # Reset CMake module path to its state when this script was called. set(CMAKE_MODULE_PATH ${OSPRAY_CALLERS_CMAKE_MODULE_PATH}) set(OSPRAY_CMAKE_ROOT ${OSPRAY_ROOT}/@CMAKE_INSTALL_LIBDIR@/cmake/ospray-@OSPRAY_VERSION@) # Include definitions for clients to use ospray header files set(OSPRAY_USE_FILE ${OSPRAY_CMAKE_ROOT}/osprayUse.cmake) set(OSPRAY_SDK_USE_FILE ${OSPRAY_USE_FILE}) # OSPRAY_REPORT_NOT_FOUND() aborts, so if we made it this far, # we have found ospray and all required dependencies. include(FindPackageMessage) find_package_MESSAGE(ospray "Found OSPRay: ${OSPRAY_ROOT}" "[${OSPRAY_ROOT}]") RenderKit-ospray-85af292/cmake/ospray_cmake_config/osprayConfigVersion.cmake.in000066400000000000000000000012171464752671100277760ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(PACKAGE_VERSION "@OSPRAY_VERSION@") set(PACKAGE_VERSION_MAJOR "@OSPRAY_VERSION_MAJOR@") # Check whether the requested PACKAGE_FIND_VERSION is compatible if (PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() # Major version needs to be the same if (PACKAGE_FIND_VERSION_MAJOR STREQUAL PACKAGE_VERSION_MAJOR) set(PACKAGE_VERSION_COMPATIBLE TRUE) else() set(PACKAGE_VERSION_COMPATIBLE FALSE) endif() if (PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_EXACT TRUE) endif() endif() RenderKit-ospray-85af292/cmake/ospray_cmake_config/osprayUse.cmake.in000066400000000000000000000017061464752671100257620ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # NOTE(jda) - Add CMake commands which will be invoked when find_package(ospray) # is called by client applications. For example, it may be useful # to automatically have an add_definitions(...) call for clients # which need certain preprocessor definitions based on how ospray # was built. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${OSPRAY_CMAKE_ROOT}) include(ispc) message(STATUS "Using found OSPRay ISA targets: ${OSPRAY_ISPC_TARGET_LIST}") if (NOT TARGET openvkl::openvkl OR NOT TARGET embree) message(FATAL_ERROR "OSPRay pre-built binary redistributables cannot be extended with the SDK. Please build OSPRay from source to enable extending OSPRay!") endif() include_directories_ispc( ${OSPRAY_INCLUDE_DIR} ${OSPRAY_INCLUDE_DIR}/ospray/SDK ${RKCOMMON_INCLUDE_DIRS} ${EMBREE_INCLUDE_DIRS} ${OPENVKL_INCLUDE_DIRS} ) RenderKit-ospray-85af292/cmake/ospray_macros.cmake000066400000000000000000000364041464752671100222450ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 include(CMakeFindDependencyMacro) ## Macro for printing CMake variables ## macro(print var) message("${var} = ${${var}}") endmacro() ## Get a list of subdirectories (single level) under a given directory macro(get_subdirectories result curdir) file(GLOB children RELATIVE ${curdir} ${curdir}/*) set(dirlist "") foreach(child ${children}) if(IS_DIRECTORY ${curdir}/${child}) list(APPEND dirlist ${child}) endif() endforeach() set(${result} ${dirlist}) endmacro() ## Get all subdirectories and call add_subdirectory() if it has a CMakeLists.txt macro(add_all_subdirectories_except except) set(e ${except}) file(GLOB dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ *) foreach(dir ${dirs}) if (NOT "${dir}X" STREQUAL "${except}X" AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/CMakeLists.txt) add_subdirectory(${dir}) endif() endforeach() endmacro() macro(add_all_subdirectories) add_all_subdirectories_except("") endmacro() ## Setup CMAKE_BUILD_TYPE to have a default + cycle between options in UI macro(ospray_configure_build_type) set(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the build type." FORCE) endif() 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 (${CMAKE_BUILD_TYPE} STREQUAL "Release") set(OSPRAY_BUILD_RELEASE TRUE ) set(OSPRAY_BUILD_DEBUG FALSE) set(OSPRAY_BUILD_RELWITHDEBINFO FALSE) elseif (${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(OSPRAY_BUILD_RELEASE FALSE) set(OSPRAY_BUILD_DEBUG TRUE ) set(OSPRAY_BUILD_RELWITHDEBINFO FALSE) else() set(OSPRAY_BUILD_RELEASE FALSE) set(OSPRAY_BUILD_DEBUG FALSE) set(OSPRAY_BUILD_RELWITHDEBINFO TRUE ) endif() endmacro() # workaround link issues to Embree ISPC exports # ISPC only adds the ISA suffix during name mangling (and dynamic dispatch # code) when compiling for multiple targets. Thus, when only one OSPRay ISA is # selected, but Embree was compiled for multiple ISAs, we need to add a # second, different, supported dummy target. macro(ospray_fix_ispc_target_list) list(LENGTH OSPRAY_ISPC_TARGET_LIST NUM_TARGETS) if (NUM_TARGETS EQUAL 1 AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "neon-i32x4" AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "neon-i32x8") if (EMBREE_ISA_SSE42 AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "sse4") list(APPEND OSPRAY_ISPC_TARGET_LIST sse4) elseif (EMBREE_ISA_AVX AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "avx") list(APPEND OSPRAY_ISPC_TARGET_LIST avx) elseif (EMBREE_ISA_AVX2 AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "avx2") list(APPEND OSPRAY_ISPC_TARGET_LIST avx2) elseif (EMBREE_ISA_AVX512 AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "avx512skx-i32x16") list(APPEND OSPRAY_ISPC_TARGET_LIST avx512skx-i32x16) elseif (EMBREE_ISA_NEON AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "neon-i32x4") list(APPEND OSPRAY_ISPC_TARGET_LIST neon-i32x4) elseif (EMBREE_ISA_NEON2X AND NOT OSPRAY_ISPC_TARGET_LIST STREQUAL "neon-i32x8") list(APPEND OSPRAY_ISPC_TARGET_LIST neon-i32x8) endif() endif() endmacro() ## Macro configure ISA targets for ispc ## macro(ospray_configure_ispc_isa) set(OSPRAY_BUILD_ISA "ALL" CACHE STRING "Target ISA (SSE4, AVX, AVX2, AVX512SKX, NEON, NEON2X, or ALL)") string(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) if(EMBREE_ISA_SSE42 AND OPENVKL_ISA_SSE4) set(OSPRAY_SUPPORTED_ISAS ${OSPRAY_SUPPORTED_ISAS} SSE4) endif() if(EMBREE_ISA_AVX AND OPENVKL_ISA_AVX) set(OSPRAY_SUPPORTED_ISAS ${OSPRAY_SUPPORTED_ISAS} AVX) endif() if(EMBREE_ISA_AVX2 AND OPENVKL_ISA_AVX2) set(OSPRAY_SUPPORTED_ISAS ${OSPRAY_SUPPORTED_ISAS} AVX2) endif() if(EMBREE_ISA_AVX512 AND OPENVKL_ISA_AVX512SKX) set(OSPRAY_SUPPORTED_ISAS ${OSPRAY_SUPPORTED_ISAS} AVX512SKX) endif() if(EMBREE_ISA_NEON AND OPENVKL_ISA_NEON) set(OSPRAY_SUPPORTED_ISAS ${OSPRAY_SUPPORTED_ISAS} NEON) endif() if(EMBREE_ISA_NEON2X AND OPENVKL_ISA_NEON2X) set(OSPRAY_SUPPORTED_ISAS ${OSPRAY_SUPPORTED_ISAS} NEON2X) endif() set_property(CACHE OSPRAY_BUILD_ISA PROPERTY STRINGS ALL ${OSPRAY_SUPPORTED_ISAS}) unset(OSPRAY_ISPC_TARGET_LIST) if (OSPRAY_BUILD_ISA STREQUAL "ALL") if(EMBREE_ISA_SSE42 AND OPENVKL_ISA_SSE4) set(OSPRAY_ISPC_TARGET_LIST ${OSPRAY_ISPC_TARGET_LIST} sse4) message(STATUS "OSPRay SSE4 ISA target enabled.") endif() if(EMBREE_ISA_AVX AND OPENVKL_ISA_AVX) set(OSPRAY_ISPC_TARGET_LIST ${OSPRAY_ISPC_TARGET_LIST} avx) message(STATUS "OSPRay AVX ISA target enabled.") endif() if(EMBREE_ISA_AVX2 AND OPENVKL_ISA_AVX2) set(OSPRAY_ISPC_TARGET_LIST ${OSPRAY_ISPC_TARGET_LIST} avx2) message(STATUS "OSPRay AVX2 ISA target enabled.") endif() if(EMBREE_ISA_AVX512 AND OPENVKL_ISA_AVX512SKX) set(OSPRAY_ISPC_TARGET_LIST ${OSPRAY_ISPC_TARGET_LIST} avx512skx-i32x16) message(STATUS "OSPRay AVX512SKX ISA target enabled.") endif() if(EMBREE_ISA_NEON AND OPENVKL_ISA_NEON) set(OSPRAY_ISPC_TARGET_LIST ${OSPRAY_ISPC_TARGET_LIST} neon-i32x4) message(STATUS "OSPRay NEON ISA target enabled.") endif() if(EMBREE_ISA_NEON2X AND OPENVKL_ISA_NEON2X) set(OSPRAY_ISPC_TARGET_LIST ${OSPRAY_ISPC_TARGET_LIST} neon-i32x8) message(STATUS "OSPRay NEON2X ISA target enabled.") endif() elseif (OSPRAY_BUILD_ISA STREQUAL "AVX512SKX") if(NOT EMBREE_ISA_AVX512) message(FATAL_ERROR "Your Embree build does not support AVX512SKX!") endif() if(NOT OPENVKL_ISA_AVX512SKX) message(FATAL_ERROR "Your Open VKL build does not support AVX512SKX!") endif() set(OSPRAY_ISPC_TARGET_LIST avx512skx-i32x16) elseif (OSPRAY_BUILD_ISA STREQUAL "AVX2") if(NOT EMBREE_ISA_AVX2) message(FATAL_ERROR "Your Embree build does not support AVX2!") endif() if(NOT OPENVKL_ISA_AVX2) message(FATAL_ERROR "Your Open VKL build does not support AVX2!") endif() set(OSPRAY_ISPC_TARGET_LIST avx2) elseif (OSPRAY_BUILD_ISA STREQUAL "AVX") if(NOT EMBREE_ISA_AVX) message(FATAL_ERROR "Your Embree build does not support AVX!") endif() if(NOT OPENVKL_ISA_AVX) message(FATAL_ERROR "Your Open VKL build does not support AVX!") endif() set(OSPRAY_ISPC_TARGET_LIST avx) elseif (OSPRAY_BUILD_ISA STREQUAL "SSE4") if(NOT EMBREE_ISA_SSE42) message(FATAL_ERROR "Your Embree build does not support SSE4!") endif() if(NOT OPENVKL_ISA_SSE4) message(FATAL_ERROR "Your Open VKL build does not support SSE4!") endif() set(OSPRAY_ISPC_TARGET_LIST sse4) elseif (OSPRAY_BUILD_ISA STREQUAL "NEON") if (NOT EMBREE_ISA_NEON) message(FATAL_ERROR "Your Embree build does not support NEON!") endif() if (NOT OPENVKL_ISA_NEON) message(FATAL_ERROR "Your OpenVKL build does not support NEON!") endif() set(OSPRAY_ISPC_TARGET_LIST neon-i32x4) elseif (OSPRAY_BUILD_ISA STREQUAL "NEON2X") if (NOT EMBREE_ISA_NEON2X) message(FATAL_ERROR "Your Embree build does not support NEON2X!") endif() if (NOT OPENVKL_ISA_NEON2X) message(FATAL_ERROR "Your OpenVKL build does not support NEON2X!") endif() set(OSPRAY_ISPC_TARGET_LIST neon-i32x8) else() message(FATAL_ERROR "Invalid OSPRAY_BUILD_ISA value. " "Please select one of ${OSPRAY_SUPPORTED_ISAS}, or ALL.") endif() ospray_fix_ispc_target_list() endmacro() macro(ospray_add_sycl_target target) target_compile_features(${target} PUBLIC cxx_std_17) target_compile_options(${target} PUBLIC ${OSPRAY_CXX_FLAGS_SYCL}) target_link_options(${target} PUBLIC ${OSPRAY_LINKER_FLAGS_SYCL}) endmacro() ## Target creation macros ## macro(ospray_sign_target name) if (OSPRAY_SIGN_FILE AND NOT APPLE) add_custom_command(TARGET ${name} POST_BUILD COMMAND ${OSPRAY_SIGN_FILE} -q $ COMMENT "Signing target" VERBATIM ) endif() endmacro() macro(ospray_install_library name component) set_target_properties(${name} PROPERTIES VERSION ${OSPRAY_VERSION} SOVERSION ${OSPRAY_SOVERSION}) ospray_install_target(${name} ${component}) ospray_sign_target(${name}) if (${ARGN}) # Install the namelink in the devel component. This command also includes the # RUNTIME and ARCHIVE components a second time to prevent an "install TARGETS # given no ARCHIVE DESTINATION for static library target" error. Installing # these components twice doesn't hurt anything. install(TARGETS ${name} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel NAMELINK_ONLY RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${component} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel ) endif() endmacro() macro(ospray_install_target name component) install(TARGETS ${name} EXPORT ospray_Exports LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${component} NAMELINK_SKIP # on Windows put the dlls into bin RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${component} # ... and the import lib into the devel package ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel ) install(EXPORT ospray_Exports DESTINATION ${OSPRAY_CMAKECONFIG_DIR} NAMESPACE ospray:: COMPONENT devel ) endmacro() ## Compiler configuration macros ## macro(ospray_configure_compiler) # unhide compiler to make it easier for users to see what they are using mark_as_advanced(CLEAR CMAKE_CXX_COMPILER) option(OSPRAY_STRICT_BUILD "Build with additional warning flags" ON) mark_as_advanced(OSPRAY_STRICT_BUILD) option(OSPRAY_WARN_AS_ERRORS "Treat warnings as errors" OFF) mark_as_advanced(OSPRAY_WARN_AS_ERRORS) set(OSPRAY_COMPILER_ICC FALSE) set(OSPRAY_COMPILER_GCC FALSE) set(OSPRAY_COMPILER_CLANG FALSE) set(OSPRAY_COMPILER_MSVC FALSE) set(OSPRAY_COMPILER_DPCPP FALSE) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "IntelLLVM" OR OSPRAY_MODULE_GPU) set(OSPRAY_COMPILER_DPCPP TRUE) include(dpcpp) if(WIN32) set(CMAKE_NINJA_CMCLDEPS_RC OFF) # workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/18311 endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") set(OSPRAY_COMPILER_ICC TRUE) if(WIN32) set(CMAKE_NINJA_CMCLDEPS_RC OFF) # workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/18311 include(msvc) # icc on Windows behaves like msvc else() include(icc) endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(OSPRAY_COMPILER_GCC TRUE) include(gcc) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set(OSPRAY_COMPILER_CLANG TRUE) include(clang) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(OSPRAY_COMPILER_MSVC TRUE) include(msvc) else() message(FATAL_ERROR "Unsupported compiler specified: '${CMAKE_CXX_COMPILER_ID}'") endif() set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG ${CMAKE_CXX_FLAGS_DEBUG}") if (WIN32) # increase stack to 8MB (the default size of 1MB is too small for our apps) if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker") endif() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608") endif() endmacro() macro(ospray_disable_compiler_warnings) if (NOT OSPRAY_COMPILER_MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") endif() endmacro() ## Embree functions/macros ## function(ospray_check_embree_feature FEATURE VALUE DESC) set(FEATURE EMBREE_${FEATURE}) if (${ARGN}) if (${FEATURE} STREQUAL ${VALUE}) return() endif() else() if ((${VALUE} AND ${FEATURE}) OR (NOT ${VALUE} AND NOT ${FEATURE})) return() endif() endif() message(FATAL_ERROR "OSPRay requires Embree to ${DESC} (compiled with ${FEATURE}=${VALUE}).") endfunction() function(ospray_verify_embree_features) ospray_check_embree_feature(ISPC_SUPPORT ON "support ISPC") ospray_check_embree_feature(FILTER_FUNCTION ON "support intersection filter") ospray_check_embree_feature(GEOMETRY_TRIANGLE ON "support triangle geometries") ospray_check_embree_feature(GEOMETRY_CURVE ON "support spline curve geometries") ospray_check_embree_feature(GEOMETRY_USER ON "support user geometries") ospray_check_embree_feature(RAY_PACKETS ON "support ray packets") ospray_check_embree_feature(BACKFACE_CULLING OFF "have backface culling disabled") ospray_check_embree_feature(GEOMETRY_INSTANCE ON "support instances") ospray_check_embree_feature(MAX_INSTANCE_LEVEL_COUNT 1 "only support single-level instancing" ON) if (OSPRAY_MODULE_GPU) ospray_check_embree_feature(SYCL_SUPPORT ON "support DPC++/SYCL") endif() endfunction() macro(ospray_find_embree EMBREE_VERSION_REQUIRED FIND_AS_DEPENDENCY) if (${FIND_AS_DEPENDENCY}) find_dependency(embree ${EMBREE_VERSION_REQUIRED}) else() find_package(embree ${EMBREE_VERSION_REQUIRED}) endif() if (NOT embree_FOUND) message(FATAL_ERROR "We did not find Embree installed on your system. OSPRay requires" " an Embree installation >= v${EMBREE_VERSION_REQUIRED}, please" " download and extract Embree (or compile Embree from source), then" " set the 'embree_DIR' variable to the installation (or build)" " directory.") endif() # Get Embree CPU info get_target_property(EMBREE_INCLUDE_DIRS embree INTERFACE_INCLUDE_DIRECTORIES) get_target_property(CONFIGURATIONS embree IMPORTED_CONFIGURATIONS) list(GET CONFIGURATIONS 0 CONFIGURATION) get_target_property(EMBREE_LIBRARY embree IMPORTED_LOCATION_${CONFIGURATION}) # Get Embree SYCL info if DPCPP was enabled if (EMBREE_SYCL_SUPPORT) get_target_property(CONFIGURATIONS embree_sycl IMPORTED_CONFIGURATIONS) list(GET CONFIGURATIONS 0 CONFIGURATION) get_target_property(EMBREE_SYCL_LIBRARY embree_sycl IMPORTED_LOCATION_${CONFIGURATION}) endif() message(STATUS "Found Embree v${embree_VERSION}: ${EMBREE_LIBRARY}") endmacro() macro(ospray_find_openvkl OPENVKL_VERSION_REQUIRED FIND_AS_DEPENDENCY) if (${FIND_AS_DEPENDENCY}) find_dependency(openvkl ${OPENVKL_VERSION_REQUIRED}) else() find_package(openvkl ${OPENVKL_VERSION_REQUIRED}) endif() if (openvkl_FOUND) get_target_property(OPENVKL_INCLUDE_DIRS openvkl::openvkl INTERFACE_INCLUDE_DIRECTORIES) get_target_property(OPENVKL_CPU_DEVICE_INCLUDE_DIRS openvkl::openvkl_module_cpu_device INTERFACE_INCLUDE_DIRECTORIES) get_target_property(CONFIGURATIONS openvkl::openvkl IMPORTED_CONFIGURATIONS) list(GET CONFIGURATIONS 0 CONFIGURATION) get_target_property(OPENVKL_LIBRARY openvkl::openvkl IMPORTED_LOCATION_${CONFIGURATION}) message(STATUS "Found Open VKL v${openvkl_VERSION}: ${OPENVKL_LIBRARY}") endif() endmacro() RenderKit-ospray-85af292/cmake/ospray_options.cmake000066400000000000000000000074671464752671100224630ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ############################################################## # Global configuration options ############################################################## include(GNUInstallDirs) include(CMakeDependentOption) set(OSPRAY_CMAKECONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/ospray-${OSPRAY_VERSION}") set(ISPC_VERSION_REQUIRED 1.23.0) set(RKCOMMON_VERSION_REQUIRED 1.14.0) set(EMBREE_VERSION_REQUIRED 4.3.3) set(OPENVKL_VERSION_REQUIRED 2.0.1) set(OIDN_VERSION_REQUIRED 2.3.0) set(OSPRAY_IMGUI_GIT_TAG cb16be3a3fc1f9cd146ae24d52b615f8a05fa93d) # v1.90.9 set(OSPRAY_STB_GIT_TAG 013ac3beddff3dbffafd5177e7972067cd2b5083) # v2.30 / v1.16 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) ospray_configure_build_type() ospray_configure_compiler() ########################################################### # OSPRay specific build options ########################################################### option(OSPRAY_ENABLE_APPS "Enable the 'apps' subtree in the build." ON) option(OSPRAY_ENABLE_TARGET_CLANGFORMAT "Enable 'format' target, requires clang-format too") mark_as_advanced(OSPRAY_ENABLE_TARGET_CLANGFORMAT) # Dependent options cmake_dependent_option( OSPRAY_ENABLE_APPS_BENCHMARK "Enable building, installing, and packaging of benchmark tools." ON OSPRAY_ENABLE_APPS OFF ) cmake_dependent_option( OSPRAY_ENABLE_APPS_EXAMPLES "Enable building, installing, and packaging of ospExamples." ON OSPRAY_ENABLE_APPS OFF ) cmake_dependent_option( OSPRAY_ENABLE_APPS_TUTORIALS "Enable building, installing, and packaging of tutorial apps." ON OSPRAY_ENABLE_APPS OFF ) cmake_dependent_option( OSPRAY_ENABLE_APPS_TESTING "Enable building, installing, and packaging of test tools." ON OSPRAY_ENABLE_APPS OFF ) option(OSPRAY_ENABLE_VOLUMES "Enable volume rendering using OpenVKL." ON) ########################################################### # OSPRay's dependencies and configuration selection ########################################################### # rkcommon find_package(rkcommon ${RKCOMMON_VERSION_REQUIRED} EXACT REQUIRED) get_target_property(RKCOMMON_INCLUDE_DIRS rkcommon::rkcommon INTERFACE_INCLUDE_DIRECTORIES) # Embree ospray_find_embree(${EMBREE_VERSION_REQUIRED} FALSE) ospray_verify_embree_features() # Open VKL if (OSPRAY_ENABLE_VOLUMES) ospray_find_openvkl(${OPENVKL_VERSION_REQUIRED} FALSE) if (NOT openvkl_FOUND) message(FATAL_ERROR "We did not find Open VKL installed on your system. OSPRay requires" " an Open VKL installation >= v${OPENVKL_VERSION_REQUIRED}, please" " download and extract Open VKL (or compile from source), then" " set the 'openvkl_DIR' variable to the installation directory.") endif() else() set(OPENVKL_ISA_SSE4 TRUE) set(OPENVKL_ISA_AVX TRUE) set(OPENVKL_ISA_AVX2 TRUE) set(OPENVKL_ISA_AVX512SKX TRUE) set(OPENVKL_ISA_NEON TRUE) set(OPENVKL_ISA_NEON2X TRUE) endif() # OpenImageDenoise if (OSPRAY_MODULE_DENOISER) find_package(OpenImageDenoise ${OIDN_VERSION_REQUIRED} REQUIRED) endif() # Configure OSPRay ISA last after we've detected what we got w/ Embree ospray_configure_ispc_isa() set(ISPC_TARGET_CPU ${OSPRAY_ISPC_TARGET_LIST}) ##################################################################### # Binary package options, before any install() invocation/definition ##################################################################### option(OSPRAY_ZIP_MODE "Use tarball/zip CPack generator instead of RPM" ON) mark_as_advanced(OSPRAY_ZIP_MODE) option(OSPRAY_INSTALL_DEPENDENCIES "Install OSPRay dependencies in binary packages and install") mark_as_advanced(OSPRAY_INSTALL_DEPENDENCIES) RenderKit-ospray-85af292/cmake/ospray_redistribute_deps.cmake000066400000000000000000000121421464752671100244720ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 macro(ospray_get_target_configuration TARGET_NAME) set(TARGETName ${TARGET_NAME}) get_target_property(CONFIGURATIONS ${TARGET_NAME} IMPORTED_CONFIGURATIONS) string(TOUPPER ${CMAKE_BUILD_TYPE} CONFIGURATION) list(FIND CONFIGURATIONS ${CONFIGURATION} IDX) if (IDX LESS 0) set(IDX 0) # first/default configuration endif() list(GET CONFIGURATIONS ${IDX} CONFIGURATION) endmacro() macro(ospray_add_dependent_lib TARGET_NAME) if (TARGET ${TARGET_NAME}) ospray_get_target_configuration(${TARGET_NAME}) get_target_property(LIBRARY ${TARGET_NAME} IMPORTED_LOCATION_${CONFIGURATION}) get_target_property(LIBRARY_SO ${TARGET_NAME} IMPORTED_SONAME_${CONFIGURATION}) if (LIBRARY_SO) get_filename_component(LIBRARY_DIR ${LIBRARY} DIRECTORY) get_filename_component(LIBRARY_NAME ${LIBRARY_SO} NAME) set(LIBRARY "${LIBRARY_DIR}/${LIBRARY_NAME}") endif() list(APPEND DEPENDENT_LIBS ${LIBRARY}) else() message(STATUS "Skipping target '${TARGET_NAME}'") endif() endmacro() macro(ospray_add_dependent_lib_plugins TARGET_NAME PLUGINS_PATTERN VER_PATTERN) if (TARGET ${TARGET_NAME}) ospray_get_target_configuration(${TARGET_NAME}) # retrieve library directory get_target_property(LIBRARY ${TARGET_NAME} IMPORTED_LOCATION_${CONFIGURATION}) get_filename_component(LIBRARY_DIR ${LIBRARY} DIRECTORY) # search for plugins with given file pattern if (WIN32) file(GLOB LIBRARY_PLUGINS LIST_DIRECTORIES FALSE "${LIBRARY_DIR}/${PLUGINS_PATTERN}.dll" ) elseif (APPLE) file(GLOB LIBRARY_PLUGINS LIST_DIRECTORIES FALSE "${LIBRARY_DIR}/lib${PLUGINS_PATTERN}${VER_PATTERN}.dylib" ) else() file(GLOB LIBRARY_PLUGINS LIST_DIRECTORIES FALSE "${LIBRARY_DIR}/lib${PLUGINS_PATTERN}.so${VER_PATTERN}" ) endif() list(APPEND DEPENDENT_LIBS ${LIBRARY_PLUGINS}) else() message(STATUS "Skipping target '${TARGET_NAME}' plugins") endif() endmacro() ospray_add_dependent_lib(rkcommon::rkcommon) if (RKCOMMON_TASKING_TBB) ospray_add_dependent_lib(TBB::tbb) ospray_add_dependent_lib(TBB::tbbmalloc) if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(TBB_DEBUG_SUFFIX "_debug") endif() ospray_add_dependent_lib_plugins(TBB::tbb "tbbbind${TBB_DEBUG_SUFFIX}" ".[0-9]") ospray_add_dependent_lib_plugins(TBB::tbb "tbbbind_?_?${TBB_DEBUG_SUFFIX}" ".[0-9]") endif() ospray_add_dependent_lib(embree) ospray_add_dependent_lib(openvkl::openvkl) ospray_add_dependent_lib(openvkl::openvkl_module_cpu_device) ospray_add_dependent_lib(openvkl::openvkl_module_cpu_device_4) ospray_add_dependent_lib(openvkl::openvkl_module_cpu_device_8) ospray_add_dependent_lib(openvkl::openvkl_module_cpu_device_16) if (OSPRAY_MODULE_DENOISER) ospray_add_dependent_lib(OpenImageDenoise) ospray_add_dependent_lib(OpenImageDenoise_core) ospray_add_dependent_lib_plugins(OpenImageDenoise "OpenImageDenoise_device_*" ".[0-9].[0-9].[0-9]") endif() if (OSPRAY_MODULE_GPU OR OSPRAY_MODULE_DENOISER) if (OSPRAY_MODULE_GPU) get_filename_component(SYCL_DIR ${CMAKE_CXX_COMPILER} DIRECTORY) if (NOT WIN32) set(SYCL_DIR "${SYCL_DIR}/../lib") endif() else() get_target_property(CONFIGURATIONS OpenImageDenoise IMPORTED_CONFIGURATIONS) list(GET CONFIGURATIONS 0 CONFIGURATION) # use first/default configuration get_target_property(OIDN_LIB OpenImageDenoise IMPORTED_LOCATION_${CONFIGURATION}) get_filename_component(SYCL_DIR ${OIDN_LIB} DIRECTORY) endif() if (WIN32) file(GLOB SYCL_LIB LIST_DIRECTORIES FALSE "${SYCL_DIR}/sycl?.dll" "${SYCL_DIR}/pi_level_zero.dll" "${SYCL_DIR}/pi_win_proxy_loader.dll" "${SYCL_DIR}/win_proxy_loader.dll" ) else() file(GLOB SYCL_LIB LIST_DIRECTORIES FALSE "${SYCL_DIR}/libsycl.so.?" "${SYCL_DIR}/libpi_level_zero.so" ) endif() list(APPEND DEPENDENT_LIBS ${SYCL_LIB}) endif() if (WIN32) set(INSTALL_DIR ${CMAKE_INSTALL_BINDIR}) else() set(INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) endif() if (OSPRAY_SIGN_FILE) add_custom_target(sign_files COMMAND ${OSPRAY_SIGN_FILE} -q ${DEPENDENT_LIBS} COMMENT "Signing files" VERBATIM ) else() add_custom_target(sign_files COMMENT "Not signing files") endif() foreach(LIB ${DEPENDENT_LIBS}) install(CODE "file(INSTALL \"${LIB}\" DESTINATION \${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR} FOLLOW_SYMLINK_CHAIN)" COMPONENT redist ) endforeach() # Install MSVC runtime if (WIN32) set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE) include(InstallRequiredSystemLibraries) # FIXME WA for OSPRay to build with GNU-style options file(TO_CMAKE_PATH ${OSPRAY_MODULE_PATH} OSPRAY_MODULE_PATH) list(APPEND CMAKE_MODULE_PATH ${OSPRAY_MODULE_PATH}) include(ospray_system_runtime OPTIONAL) list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${OSPRAY_INSTALL_SYSTEM_RUNTIME_LIBS}") list(FILTER CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS INCLUDE REGEX ".*msvcp[0-9]+\.dll|.*vcruntime[0-9]+\.dll|.*vcruntime[0-9]+_[0-9]+\.dll") install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT redist) endif() RenderKit-ospray-85af292/cmake/ospray_version.cmake000066400000000000000000000024341464752671100224420ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(OSPRAY_VERSION_MAJOR 3) set(OSPRAY_VERSION_MINOR 2) set(OSPRAY_VERSION_PATCH 0) set(OSPRAY_SOVERSION 3) set(OSPRAY_VERSION_GITHASH 0) set(OSPRAY_VERSION_NOTE "") if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.git) find_package(Git) if (GIT_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE "OSPRAY_VERSION_GITHASH" OUTPUT_STRIP_TRAILING_WHITESPACE) string(SUBSTRING ${OSPRAY_VERSION_GITHASH} 0 8 OSPRAY_VERSION_GITHASH_SHORT) execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE "OSPRAY_VERSION_GITBRANCH" OUTPUT_STRIP_TRAILING_WHITESPACE) if (NOT OSPRAY_VERSION_GITBRANCH MATCHES "^master$|^release-") if (NOT OSPRAY_VERSION_GITBRANCH STREQUAL "HEAD") set(OSPRAY_VERSION_NOTE "-${OSPRAY_VERSION_GITBRANCH}") endif() set(OSPRAY_VERSION_NOTE "${OSPRAY_VERSION_NOTE} (${OSPRAY_VERSION_GITHASH_SHORT})") endif() endif() endif() set(OSPRAY_VERSION ${OSPRAY_VERSION_MAJOR}.${OSPRAY_VERSION_MINOR}.${OSPRAY_VERSION_PATCH} ) RenderKit-ospray-85af292/cmake/package.cmake000066400000000000000000000155231464752671100207560ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(CMAKE_INSTALL_SCRIPTDIR scripts) if (OSPRAY_ZIP_MODE) # in tgz / zip let's have relative RPath set(CMAKE_SKIP_INSTALL_RPATH OFF) if (APPLE) set(CMAKE_MACOSX_RPATH ON) 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: #set_TARGET_PROPERTIES(apps INSTALL_RPATH "$ORIGIN:$ORIGIN/../lib") #set_TARGET_PROPERTIES(libs INSTALL_RPATH "$ORIGIN") endif() else() set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}) if (APPLE) # use RPath on OSX set(CMAKE_SKIP_INSTALL_RPATH OFF) else() # we do not want any RPath for installed binaries set(CMAKE_SKIP_INSTALL_RPATH ON) endif() if (NOT WIN32) # for RPMs install docu in versioned folder set(CMAKE_INSTALL_DOCDIR ${CMAKE_INSTALL_DOCDIR}-${OSPRAY_VERSION}) set(CMAKE_INSTALL_SCRIPTDIR ${CMAKE_INSTALL_DATAROOTDIR}/OSPRay-${OSPRAY_VERSION}/scripts) endif() endif() ############################################################## # install headers ############################################################## install(DIRECTORY ${PROJECT_SOURCE_DIR}/ospray/include/ospray DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT devel FILES_MATCHING PATTERN "*.h" ) ############################################################## # install documentation ############################################################## install(FILES ${PROJECT_SOURCE_DIR}/third-party-programs.txt ${PROJECT_SOURCE_DIR}/third-party-programs-oneTBB.txt ${PROJECT_SOURCE_DIR}/third-party-programs-Embree.txt ${PROJECT_SOURCE_DIR}/third-party-programs-OpenVKL.txt ${PROJECT_SOURCE_DIR}/third-party-programs-OIDN.txt ${PROJECT_SOURCE_DIR}/third-party-programs-oneDNN.txt ${PROJECT_SOURCE_DIR}/third-party-programs-DPCPP.txt ${PROJECT_SOURCE_DIR}/third-party-programs-oneAPI-DPCPP.txt ${PROJECT_SOURCE_DIR}/third-party-programs-ISPC.txt ${PROJECT_SOURCE_DIR}/CHANGELOG.md ${PROJECT_SOURCE_DIR}/README.md DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT lib) install(FILES ${PROJECT_SOURCE_DIR}/readme.pdf DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT lib OPTIONAL) if (OSPRAY_INSTALL_DEPENDENCIES AND OSPRAY_MODULE_DENOISER AND OIDN_DEVICE_CUDA) install(FILES ${PROJECT_SOURCE_DIR}/doc/BINARY-LICENSE.txt RENAME LICENSE.txt DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT lib) else() install(FILES ${PROJECT_SOURCE_DIR}/LICENSE.txt DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT lib) endif() ############################################################## # CPack specific stuff ############################################################## set(CPACK_PACKAGE_NAME "OSPRay") set(CPACK_PACKAGE_FILE_NAME "ospray-${OSPRAY_VERSION}") #set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/ospray-doc/images/icon.png) #set(CPACK_PACKAGE_RELOCATABLE TRUE) # do not disable, stripping symbols is important for security reasons # except on Windows, where stripping is usually not supported/required; but on # some systems it is done via llvm-strip, which only slightly changes the # binary, enough to invalidate code signatures if (NOT WIN32) set(CPACK_STRIP_FILES TRUE) endif() set(CPACK_PACKAGE_VERSION_MAJOR ${OSPRAY_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${OSPRAY_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${OSPRAY_VERSION_PATCH}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OSPRay: A Ray Tracing Based Rendering Engine for High-Fidelity Visualization") set(CPACK_PACKAGE_VENDOR "Intel Corporation") set(CPACK_PACKAGE_CONTACT ospray@googlegroups.com) set(CPACK_COMPONENT_LIB_DISPLAY_NAME "Library") set(CPACK_COMPONENT_LIB_DESCRIPTION "The OSPRay library including documentation.") set(CPACK_COMPONENT_DEVEL_DISPLAY_NAME "Development") set(CPACK_COMPONENT_DEVEL_DESCRIPTION "Header files for C and C++ required to develop applications with OSPRay.") set(CPACK_COMPONENT_APPS_DISPLAY_NAME "Applications") set(CPACK_COMPONENT_APPS_DESCRIPTION "Example, viewer and test applications as well as tutorials demonstrating how to use OSPRay.") set(CPACK_COMPONENT_MPI_DISPLAY_NAME "MPI Module") set(CPACK_COMPONENT_MPI_DESCRIPTION "OSPRay module for MPI-based distributed rendering.") set(CPACK_COMPONENT_GPU_DISPLAY_NAME "GPU Module") set(CPACK_COMPONENT_GPU_DESCRIPTION "OSPRay module for Intel Xe GPU-based rendering.") set(CPACK_COMPONENT_REDIST_DISPLAY_NAME "Redistributables") set(CPACK_COMPONENT_REDIST_DESCRIPTION "Dependencies of OSPRay (such as Embree, TBB, imgui) that may or may not be already installed on your system.") # dependencies between components set(CPACK_COMPONENT_DEVEL_DEPENDS lib) set(CPACK_COMPONENT_APPS_DEPENDS lib) set(CPACK_COMPONENT_MPI_DEPENDS lib) set(CPACK_COMPONENT_GPU_DEPENDS lib) set(CPACK_COMPONENT_LIB_REQUIRED ON) # always install the libs # point to readme and license files set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE.txt) if (OSPRAY_ZIP_MODE) set(CPACK_MONOLITHIC_INSTALL ON) else() set(CPACK_COMPONENTS_ALL lib devel apps) endif() if (WIN32) # Windows specific settings if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "Only 64bit architecture supported.") endif() set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.windows") if (OSPRAY_ZIP_MODE) set(CPACK_GENERATOR ZIP) else() set(CPACK_GENERATOR WIX) set(CPACK_WIX_ROOT_FEATURE_DESCRIPTION "OSPRay is an open source, scalable, and portable ray tracing engine for high-performance, high-fidelity visualization.") set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT http://www.ospray.org/) set(CPACK_PACKAGE_NAME "OSPRay v${OSPRAY_VERSION}") list(APPEND CPACK_COMPONENTS_ALL redist) if (OSPRAY_MODULE_MPI) list(APPEND CPACK_COMPONENTS_ALL mpi) endif() if (OSPRAY_MODULE_GPU) list(APPEND CPACK_COMPONENTS_ALL gpu) endif() set(CPACK_PACKAGE_INSTALL_DIRECTORY "Intel\\\\OSPRay v${OSPRAY_VERSION_MAJOR}") math(EXPR OSPRAY_VERSION_NUMBER "10000*${OSPRAY_VERSION_MAJOR} + 100*${OSPRAY_VERSION_MINOR} + ${OSPRAY_VERSION_PATCH}") set(CPACK_WIX_PRODUCT_GUID "9D64D525-2603-4E8C-9108-845A146${OSPRAY_VERSION_NUMBER}") set(CPACK_WIX_UPGRADE_GUID "9D64D525-2603-4E8C-9108-845A146${OSPRAY_VERSION_MAJOR}0000") # upgrade as long as major version is the same set(CPACK_WIX_CMAKE_PACKAGE_REGISTRY TRUE) endif() elseif(APPLE) # MacOSX specific settings configure_file(${PROJECT_SOURCE_DIR}/README.md ${PROJECT_BINARY_DIR}/ReadMe.txt COPYONLY) set(CPACK_RESOURCE_FILE_README ${PROJECT_BINARY_DIR}/ReadMe.txt) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${CMAKE_SYSTEM_PROCESSOR}.macosx") set(CPACK_GENERATOR ZIP) else() # Linux specific settings set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${CMAKE_SYSTEM_PROCESSOR}.linux") set(CPACK_GENERATOR TGZ) endif() RenderKit-ospray-85af292/doc/000077500000000000000000000000001464752671100160405ustar00rootroot00000000000000RenderKit-ospray-85af292/doc/.gitignore000066400000000000000000000001021464752671100200210ustar00rootroot00000000000000# generated files&folders changelog.md www tmp __pycache__ images RenderKit-ospray-85af292/doc/BINARY-LICENSE.txt000066400000000000000000000435661464752671100206630ustar00rootroot00000000000000INTEL® OSPRAY SOFTWARE BINARY SOFTWARE LICENSE AGREEMENT IMPORTANT NOTICE – PLEASE READ AND AGREE BEFORE DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE This agreement (the "Agreement") is between you, or the company or other legal entity that you represent and warrant you have the legal authority to bind, (each, "You" or "Your") and Intel Corporation and its subsidiaries (collectively, "Intel") regarding Your use of the Software. By downloading, installing, copying or otherwise using the Software, You agree to be bound by the terms of this Agreement. If You do not agree to the terms of this Agreement, or do not have legal authority or required age to agree to them, do not download, install, copy or otherwise use the Software. 1. DEFINITIONS. "Derivative Works" means derivative works of the Software as defined in 17 U.S.C. § 101 et seq. "Reciprocal Open Source Software" means any software that is subject to a license which requires that (a) it must be distributed in source code form; (b) it must be licensed under the same open source license terms; and (c) its Derivative Works must be licensed under the same open source license terms. Examples of this type of license are the GNU General Public License or the Mozilla Public License. "Software" means the Intel® Open Image Denoise software in binary form, printed or electronic documentation, and any other collateral including any updates and upgrades that are made available to You by Intel under this Agreement. The Software does not include Third Party Software. "Third Party Software" mean the third party software (if any) listed in the "third-party-programs.txt" or other similarly-named text file that may be included in the Software. 2. LIMITED LICENSE. Subject to compliance with the terms and conditions of this Agreement, Intel grants You a limited, nonexclusive, nontransferable, revocable, worldwide, no fee license during the term of this Agreement, without the right to sublicense, under Intel’s copyrights, for Your (a) reasonable internal reproduction and internal use, and (b) redistribution of the Software to end users provided that: (i) the Software is provided under a written, legally enforceable end user license agreement that has the effect of protecting the Software and the rights of Intel and its licensors under terms no less restrictive than this Agreement, and (ii) You indemnify, defend, and hold harmless Intel and its licensors from any claims, including attorneys’ fees, related to the Your redistribution or use of the Software. 3. OWNERSHIP/LICENSE RESTRICTIONS. All right, title and interest in and to the Software are and will remain the exclusive property of Intel and its licensors. Unless expressly permitted under the Agreement, You will not, and will not allow any third party to (i) use, copy, distribute, transfer, sublicense, rent, sell or offer to sell the Software or associated documentation; (ii) modify, adapt, enhance, disassemble, decompile, reverse engineer, change or create Derivative Works from the Software except and only to the extent as specifically required by mandatory applicable laws; (iii) use or make the Software available for the use or benefit of third parties; (iv) modify, create a Derivative Work, link, or distribute the Software so that any part of it becomes subject to the license requirements of Reciprocal Open Source Software; (v) remove or alter any copyright, trademark or patent notice in the Software or any portion; (vi) use Intel’s or its licensors’ trademarks in Your distribution names or in a way that suggests Your distributions comes from or is endorsed by Intel or its licensors; (vii) bypass, disable, or circumvent any encryption, security, digital rights management or authentication mechanism in the Software; (viii) include the Software in malicious, deceptive or unlawful programs; (ix) distribute the Software in source code form; (x) grant the right to modify the Software; or (xi) reverse engineer, decompile or disassemble any portion of the output generated using the Software for the purpose of translating such output artifacts to target a non-NVIDIA platform if the output is intended for use on an NVIDIA platform. Furthermore, You: (a) acknowledge that an essential basis of the bargain in this Agreement is that Intel grants You no licenses or other rights including, but not limited to, patent, copyright, and trade secret, or other intellectual property licenses or rights to the Software, by implication, estoppel or otherwise, except for the licenses expressly granted above; (b) acknowledge there are significant uses of the Software in its original, unmodified and uncombined form. You may not remove any copyright notices from the Software; (c) agree to notify Intel in writing of any known or suspected distribution or use of the Software not in compliance with the requirements of this Agreement, and to enforce the terms of your agreements with respect to distributed Software; (d) agree to cooperate with Intel and provide reasonably requested information to verify your compliance with this Agreement; and (e) are solely responsible for ensuring that any product or service developed with the Software includes sufficient features to comply with all applicable legal and regulatory standards and requirements. 4. THIRD PARTY SOFTWARE. Third Party Software, even if included with the distribution of the Software, may be governed by separate license terms, including without limitation, open source software notices and terms, third party license terms, other Intel software license terms. Such separate license terms (and not this Agreement) govern Your use of the Third Party Programs. 5. Media Format Codecs and Digital Rights Management. You acknowledge and agree that Your use of the Software as permitted by this Agreement may require You to procure license(s) from third parties that may hold intellectual property rights applicable to any media decoding, encoding or transcoding technology (e.g., the use of an audio or video codec) or software, content, and/or digital rights management capabilities (the "Technology") of the Software, if any. Should any such additional licenses be required, You are solely responsible for obtaining any such licenses and agree to obtain any such licenses at Your own expense. Intel does not grant any necessary patent or other rights with respect to the Technology. 6. LICENSE TO FEEDBACK. This Agreement does not obligate You to provide Intel with materials, information, comments, suggestions, or other communication regarding the features, functions, performance or use of the Software ("Feedback"). To the extent You provide Intel with Feedback in a tangible form, You grant to Intel and its affiliates a non-exclusive, perpetual, sublicensable, irrevocable, worldwide, royalty-free, fully paid-up and transferable license, to and under all of Your intellectual property rights, whether perfected or not, to publicly perform, publicly display, reproduce, use, make, have made, sell, offer for sale, distribute, import, create Derivative Works of and otherwise exploit any comments, suggestions, descriptions, ideas or other feedback regarding the Software provided by You or on Your behalf. 7. SAFETY-CRITICAL, AND LIFE-SAVING APPLICATIONS; INDEMNITY. The Software may provide information relevant to safety-critical applications ("Safety-Critical Applications") to allow compliance with functional safety standards or requirements. You acknowledge and agree that safety is Your responsibility. To the extent You use the Software to create, or as part of, products used in Safety-Critical Applications, it is Your responsibility to design, manage, and ensure that there are system-level safeguards to anticipate, monitor, and control system failures, and You agree that You are solely responsible for all applicable regulatory standards and safety-related requirements concerning Your use of the Software in Safety Critical Applications. Should You use the Software for Safety-Critical Applications or in any type of a system or application in which the failure of the Software could create a situation where personal injury or death may occur (e.g., medical systems, life-sustaining or life-saving systems) ("Life-Saving Applications"), You agree to indemnify, defend, and hold Intel and its representatives harmless against any claims or lawsuits, costs, damages, and expenses, including reasonable attorney fees, arising in any way out of Your use of the Software in Safety-Critical Applications or Life-Saving Applications and claims of product liability, personal injury or death associated with those applications; even if such claims allege that Intel was negligent or strictly liable regarding the design or manufacture of the Software or its failure to warn regarding the Software. 8. NO OBLIGATION; NO AGENCY. Intel may make changes to the Software, or items referenced therein, at any time without notice. Intel is not obligated to support, update, provide training for, or develop any further versions of the Software or to grant any license thereto. No agency, franchise, partnership, joint venture, or employee-employer relationship is intended or created by this Agreement. 9. NO WARRANTY. DISCLAIMER. THE SOFTWARE IS PROVIDED "AS IS" AND "WITH ALL FAULTS.’ INTEL AND ITS LICENSORS EXPRESSLY DISCLAIM ALL WARRANTIES OF ANY KIND OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, TITLE, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, OR THE ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT. NO WARRANTY IS MADE ON THE BASIS OF TRADE USAGE, COURSE OF DEALING OR COURSE OF TRADE. Intel does not assume, and does not authorize any person to assume on its behalf, any other liability. Intel may make changes to the Software, or to items referenced therein, at any time without notice, but is not obligated to support, update or provide training for the Software under the terms of this Agreement. 10. LIMITATION OF LIABILITY. IN NO EVENT WILL INTEL OR ITS AFFILIATES, LICENSORS OR SUPPLIERS (INCLUDING THEIR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AND AGENTS) BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, LOSS OF USE, LOSS OF GOODWILL, BUSINESS INTERRUPTION, COSTS OF PROCURING SUBSTITUTE PRODUCTS OR LOST DATA) ARISING OUT OF OR IN RELATION TO THIS AGREEMENT, INCLUDING THE USE OF OR INABILITY TO USE THE SOFTWARE, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON BREACH OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF LIABILITY, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE LIMITATION MAY IN PART NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY FROM JURISDICTION TO JURISDICTION. IN NO EVENT WILL INTEL’S, ITS AFFILIATES’ AND LICENSORS’ TOTAL CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS AGREEMENT EXCEED US$10.00. THE LIMITED REMEDIES, WARRANTY DISCLAIMER AND LIMITED LIABILITY ARE FUNDAMENTAL ELEMENTS OF THE BASIS OF THE BARGAIN BETWEEN INTEL AND YOU. YOU ACKNOWLEDGE INTEL WOULD BE UNABLE TO PROVIDE THE SOFTWARE WITHOUT SUCH LIMITATIONS. 11. TERMINATION AND SURVIVAL. This Agreement will terminate immediately if You violate any of its terms or conditions. Intel may, at any time, terminate this Agreement if (i) you commence or participate in any legal proceeding against Intel or its licensors with respect to the Software; (ii) if Intel decides to no longer provide the Software in a particular country; or (iii) if Intel, in its sole discretion, decides to no longer make the Software commercially available. Upon any termination of this Agreement, all licenses granted to You hereunder terminate immediately. Upon termination, You will immediately stop use of the Software, permanently remove the Software from your systems, destroy the Software, and keep no copies. If requested in writing, you will certify in writing that you have complied with your obligations under this Section. The following sections will survive termination of this Agreement: Section 1, 3 (only with respect to the first sentence), 4, 5, 6, 7, 9, 10, 11, 12, 16, 17, 18 and 19. 12. GOVERNING LAW AND JURISDICTION. This Agreement and any dispute arising out of or relating to it will be governed by the laws of the U.S.A. and Delaware, without regard to conflict of laws principles. The parties exclude the application of the United Nations Convention on Contracts for the International Sale of Goods (1980). The state and federal courts sitting in Delaware, U.S.A. will have exclusive jurisdiction over any dispute arising out of or relating to this Agreement. The parties consent to personal jurisdiction and venue in those courts. A party that obtains a judgment against the other party in the courts identified in this Section may enforce that judgment in any court that has jurisdiction over the parties. 13. EXPORT. You acknowledge that the Software and all related technical information are subject to export controls and You agree to comply with all laws and regulations of the United States and other applicable governments governing export, re-export, import, transfer, distribution, and use of the Software. In particular, but without limitation, the Software may not be exported or re-exported (a) into any U.S. embargoed countries or (b) to any person or entity listed on a denial order published by the U.S. government or any other applicable governments. By using the Software, You represent and warrant that You are not located in any such country or on any such list. You also agree that You will not use the Software for, or sell or transfer them to a third party who is known or suspected to be involved in, any purposes prohibited by the U.S. government or other applicable governments, including, without limitation, the development, design, manufacture, or production of nuclear, missile, chemical or biological weapons. 14. GOVERNMENT RESTRICTED RIGHTS. The technical data and computer software covered by this license is a "Commercial Item," as such term is defined by the FAR 2.101 (48 C.F.R. 2.101) and is "commercial computer software" and "commercial computer software documentation" as specified under FAR 12.212 (48 C.F.R. 12.212) or DFARS 227.7202 (48 C.F.R. 227.7202), as applicable. This commercial computer software and related documentation is provided to end users for use by and on behalf of the U.S. Government, with only those rights as are granted to all other end users pursuant to the terms and conditions herein. 15. ASSIGNMENT. You may not delegate, assign or transfer this Agreement, the license(s) granted or any of Your rights or duties hereunder, expressly, by implication, by operation of law, or otherwise and any attempt to do so, without Intel’s express prior written consent, will be null and void. Intel may assign, delegate and transfer this Agreement, and its rights and obligations hereunder, in its sole discretion. 16. ENTIRE AGREEMENT. This Agreement contains the complete and exclusive agreement and understanding between the parties concerning the subject matter of this Agreement, and supersedes all prior and contemporaneous proposals, agreements, understanding, negotiations, representations, warranties, conditions, and communications, oral or written, between the parties relating to the same subject matter. You acknowledge and agree that in entering into this Agreement You have not relied on, and will not be entitled to rely on, any oral or written representations, warranties, conditions, understanding, or communications that are not expressly set forth in this Agreement. The express provisions of this Agreement control over any course of performance, course of dealing, or usage of the trade inconsistent with any of the provisions of this Agreement. The provisions of this Agreement will prevail notwithstanding any different, conflicting, or additional provisions that may appear on any purchase order, acknowledgement, invoice, or other writing issued by either party in connection with this Agreement. No modification or amendment to this Agreement will be effective unless in writing and signed by authorized representatives of each party, and must specifically identify this Agreement by its title and version; , except that Intel may make changes to the Agreement as it distributes new versions of the Software. If You received a copy of this Agreement translated into another language, the English language version of this Agreement will prevail in the event of any conflict between versions. 17. SEVERABILITY AND WAIVER. The parties intend that if a court holds that any provision or part of this Agreement is invalid or unenforceable under applicable law, the court will modify the provision to the minimum extent necessary to make it valid and enforceable, or if it cannot be made valid and enforceable, the parties intend that the court will sever and delete the provision or part from this Agreement. Any change to or deletion of a provision or part of this Agreement under this Section will not affect the validity or enforceability of the remainder of this Agreement, which will continue in full force and effect. The failure of a party to require performance by the other party of any provision hereof will not affect the full right to require such performance at any time thereafter; nor will waiver by a party of a breach of any provision hereof constitute a waiver of the provision itself. 18. PRIVACY. YOUR PRIVACY RIGHTS ARE SET FORTH IN INTEL’S PRIVACY NOTICE, WHICH FORMS A PART OF THIS AGREEMENT. PLEASE REVIEW THE PRIVACY NOTICE AT HTTP://WWW.INTEL.COM/PRIVACY TO LEARN HOW INTEL COLLECTS, USES AND SHARES INFORMATION ABOUT YOU. 19. THIRD PARTY BENEFICIARIES. The Software includes software and materials from Intel’s licensors. These licensors are intended third party beneficiaries that may enforce this Agreement with respect to their intellectual property rights. RenderKit-ospray-85af292/doc/Makefile000066400000000000000000000222351464752671100175040ustar00rootroot00000000000000SHELL := /bin/bash webpages := $(addprefix www/, $(addsuffix .html, index tutorials documentation gallery downloads related_projects displaywall ospray2_porting_guide legal)) process_version := $(addprefix tmp/, $(addsuffix .md, tutorials getting_ospray readme_head)) tmptexfiles := $(addprefix tmp/, $(addsuffix .tex, overview changelog compilation api tutorials)) images_jpg := $(addprefix images/, $(addsuffix .jpg, exampleViewer $(addprefix camera_, perspective architectural stereo orthographic panoramic) $(addprefix material_, OBJ Principled CarPaint Metal Alloy Glass ThinGlass MetallicPaint Luminous) ColoredWindow $(addprefix ospMPIDistribTutorial, Volume Spheres _firstFrame _accumulatedFrame))) images_png := $(addprefix images/, $(addsuffix .png, diffuse_rooms normalmap_frustum tutorial_accumulatedframe tutorial_firstframe ospExamples renderSunSky)) images_fig := spot_light c-gamma_coords quad_light hdri_light images_svg := structured_spherical_coords vdb_structure images_fig2pdf := $(addprefix tmp/, $(addsuffix .pdf, $(images_fig))) images_svg2pdf := $(addprefix images/, $(addsuffix .pdf, $(images_svg))) images_fig2png := $(addprefix images/, $(addsuffix .png, $(images_fig))) webimages := $(addprefix www/, $(images_jpg) $(images_png) $(images_fig2png) $(addprefix images/, vdb_structure.png $(addsuffix .svg, $(images_svg)))) pdfimages := $(images_jpg) $(images_png) $(images_fig2pdf) $(images_svg2pdf) PANDOC := pandoc PDMINVERSION := 2000000 PDVERSION := $(shell $(PANDOC) --version|head -n 1) $(info Using $(PDVERSION)) PDOK := $(shell expr `$(PANDOC) --version|head -n 1|cut -d' ' -f 2| sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/' -e 's/^[0-9]\{5,6\}$$/&00/'` \>= $(PDMINVERSION)) ifneq "$(PDOK)" "1" $(error You need at least pandoc v2.0) endif all: www doc pdf www: $(webpages) www/stylesheet.css $(webimages) | wwwscripts doc: ../README.md pdf: ../readme.pdf spec: ospray-spec.html ospray-spec.rst $(webimages) checklinks: tmp/brokenlinks.txt @if [[ -s $^ ]] ; then \ echo "Found broken link:" ;\ cat $^ ;\ exit 1 ;\ else \ echo "All links good." ;\ fi .PHONY: all www doc pdf clean realclean submodule checklinks spec submodule: git submodule update --init --remote if_is_devel_then = if [[ "${CI_BUILD_REF_NAME}" == *"devel" || (-d ../.git && "`git rev-parse --abbrev-ref HEAD`" == *"devel") ]] ; then tmp/version: ../cmake/ospray_version.cmake $(wildcard ../.git/HEAD) sed -n $< -e "s/^set(OSPRAY_VERSION_MAJOR \([0-9]\+\))/\1./ip" | tr -d '\n' > $@ sed -n $< -e "s/^set(OSPRAY_VERSION_MINOR \([0-9]\+\))/\1./ip" | tr -d '\n' >> $@ sed -n $< -e "s/^set(OSPRAY_VERSION_PATCH \([0-9]\+\))/\1/ip" | tr -d '\n' >> $@ sed -n $< -e 's/^set(OSPRAY_VERSION_NOTE "")//;t;s/^set(OSPRAY_VERSION_NOTE "\([^"]\+\)")/ (\1)/ip' | tr -d '\n' >> $@ $(if_is_devel_then) echo " (devel)"; else echo; fi >> $@ replace_version = sed -e "s//`cat tmp/version`/g" $< > $@ tmp/%.md: %.md tmp/version tmp/links_local.md tmp/images_web.md $(replace_version) $(PANDOC) $@ tmp/links_local.md tmp/images_web.md -o $@ tmp/links.md: links.md $(wildcard ../.git/HEAD) $(if_is_devel_then) \ sed -e "s/OSPRay_readme.pdf/OSPRay_readme_devel.pdf/g" $< > $@;\ else cp $< $@ ;\ fi tmp/links_local.md: tmp/links.md sed -e "s@: [a-z]\+\.html#@: #@" $< > $@ tmp/images_web.md: images.md sed -e "s/\.fig/.png/" -e "s/vdb_structure\.svg/vdb_structure.png/" -e "s@: @: https://ospray.github.io/images/@" $< > $@ tmp/images_local_png.md: images.md sed -e "s@: @: images/@" -e "s/vdb_structure\.svg/vdb_structure.png/" -e "s/\.fig/.png/" $< > $@ tmp/images_local_pdf.md: images.md sed -e "s@: @: images/@" -e "s@images/\(.*\)\.fig@tmp/\1.pdf@" -e "s@\.svg@.pdf@" $< > $@ ### directories ######################################################################## $(webpages) www/stylesheet.css: | wwwdir wwwdir: @mkdir -p www $(webimages): | wwwimgdir wwwimgdir: @mkdir -p www/images wwwscripts: | wwwdir if [[ -d ospray-doc/scripts ]] ; then \ cp -r ospray-doc/scripts/ www ;\ fi $(process_version) tmp/version ../readme.pdf $(tmptexfiles) $(images_fig2pdf) tmp/api.md tmp/api_web.md tmp/changelog.md tmp/compilation.md tmp/compilation_web.md tmp/links.md tmp/links_local.md tmp/images_web.md tmp/images_local_png.md tmp/images_local_pdf.md: | tmpdir tmpdir: @mkdir -p tmp ### spec ######################################################################## ospray-spec.rst: api.md tmp/links_local.md tmp/images_local_png.md $(PANDOC) --wrap=none --indented-code-classes=cpp --email-obfuscation=none $+ -t rst | sed -e 's@½@\\frac{1}{2}@g' > $@ ospray-spec.html: ospray-spec.rst rst2html $+ $@ ### webpages ######################################################################## markdown2web = $(PANDOC) --email-obfuscation=none -f markdown $(filter-out webtemplate.html,$+) --template webtemplate -V select_$(basename $(@F)) -o $@ $(webpages): tmp/links.md tmp/images_local_png.md webtemplate.html www/%.html: $(markdown2web) www/stylesheet.css: stylesheet.css cp $< $@ tmp/api_web.md: api.md tmp/links.md tmp/images_local_png.md $(PANDOC) $+ --indented-code-classes=cpp -t markdown-fenced_code_attributes -o $@ tmp/compilation_web.md: prerequisites.md ../scripts/superbuild/README.md compilation.md tmp/links.md $(PANDOC) $+ --indented-code-classes=sh -t markdown-fenced_code_attributes -o $@ tmp/changelog.md: filter-sectionnumbers.py ../CHANGELOG.md $(PANDOC) --top-level-division=chapter --filter $+ -o $@ echo -e '\nFor the complete history of changes have a look at the [CHANGELOG](https://github.com/ospray/ospray/blob/master/CHANGELOG.md).' >> $@ www/index.html: teaser.html overview.md tmp/changelog.md www/tutorials.html: tutorials.md $(markdown2web) --indented-code-classes=sh www/gallery.html: gallery.md www/downloads.html: tmp/getting_ospray.md tmp/compilation_web.md www/related_projects.html: related_projects.md www/displaywall.html: displaywall.md www/legal.html: legal.md www/documentation.html: documentation.md tmp/api_web.md $(markdown2web) --toc www/ospray2_porting_guide.html: ospray2_porting_guide.md $(markdown2web) --indented-code-classes=cpp ### images ######################################################################## www/images/%.png: %.fig fig2dev -L png -S 4 $+ $@ www/images/%.svg: %.svg cp $+ $@ tmp/%.pdf: %.fig fig2dev -L pdf $+ $@ www/images/%: images/% cp $< $@ # try to download images if not linked; images may not be up to date images/%: if [[ -d ospray-doc/images ]] ; then \ ln -fs ospray-doc/images ;\ else \ if [[ -x "`which wget 2> /dev/null`" ]] ; then \ mkdir -p images ;\ wget https://ospray.github.io/$@ -O $@ ;\ else \ curl https://ospray.github.io/$@ --create-dirs -Lo $@ ;\ fi \ fi ### markdown ######################################################################## # also works around pandoc #5121, should be fixed in v2.5.1 convert_nbsp_width = sed -e 's@\\ @ @g' -e 's/" style="width:/" width="/g' -e "s@^@\0\n\n@" tmp/api.md: api.md tmp/links_local.md tmp/images_web.md $(PANDOC) $+ --indented-code-classes=cpp -t markdown-fenced_code_attributes -o $@ tmp/compilation.md: prerequisites.md ../scripts/superbuild/README.md compilation.md tmp/links_local.md $(PANDOC) $+ --indented-code-classes=sh -t markdown-fenced_code_attributes -o $@ tmp/tutorials.md: tutorials.md tmp/links_local.md tmp/images_web.md $(PANDOC) $+ --indented-code-classes=sh -t markdown-fenced_code_attributes -o $@ ../README.md: tmp/readme_head.md tmp/overview.md tmp/compilation.md tmp/documentation.md tmp/api.md tmp/tutorials.md $(PANDOC) --file-scope $+ --markdown-headings=setext -t gfm | $(convert_nbsp_width) > $@ ### pdf ######################################################################## markdown2tex = $(PANDOC) --columns=72 --top-level-division=chapter --filter $+ -o $@ tmp/%.tex: filter-latex.py %.md tmp/links_local.md tmp/images_local_pdf.md $(markdown2tex) tmp/api.tex: filter-latex.py api.md tmp/links_local.md tmp/images_local_pdf.md $(markdown2tex) --indented-code-classes=cpp tmp/compilation.tex: filter-latex.py prerequisites.md ../scripts/superbuild/README.md compilation.md tmp/links_local.md tmp/images_local_pdf.md $(markdown2tex) --indented-code-classes=sh tmp/tutorials.tex: filter-latex.py tutorials.md tmp/links_local.md tmp/images_local_pdf.md $(markdown2tex) --indented-code-classes=sh tmp/changelog.tex: filter-latex.py tmp/changelog.md tmp/links_local.md tmp/images_local_pdf.md $(markdown2tex) ../readme.pdf: readme.tex $(tmptexfiles) $(wildcard ospray-doc/intel-spec.cls) preamble.tex tmp/version $(pdfimages) md5s=0;\ auxf="tmp/`basename $< tex`aux";\ newmd5s=`md5sum $$auxf 2> /dev/null`;\ until [[ $$md5s == $$newmd5s ]]; do \ md5s=$$newmd5s;\ xelatex -halt-on-error -output-directory=tmp $< || exit 2;\ newmd5s=`md5sum $$auxf`;\ done cp tmp/$(basename $<).pdf $@ # crude way to detect broken pdf links tmp/%.txt: $(tmptexfiles) fgrep -h $* $^ | sed -e 's@.*$*{\([^}]*\)}.*@\1@'|sort -u > $@ tmp/brokenlinks.txt: tmp/hypertarget.txt tmp/hyperlink.txt -diff -u $^ | grep "^+[^+]" > $@ ### clean ######################################################################## clean: rm -rf www tmp __pycache__ ospray-spec.html ospray-spec.rst realclean: clean rm -irf images RenderKit-ospray-85af292/doc/api.md000066400000000000000000005353151464752671100171470ustar00rootroot00000000000000OSPRay API ========== To access the OSPRay API you first need to include the OSPRay header #include "ospray/ospray.h" where the API is compatible with C99 and C++. Initialization and Shutdown --------------------------- To use the API, OSPRay must be initialized with a "device". A device is the object which implements the API. Creating and initializing a device can be done in either of two ways: command line arguments using `ospInit` or manually instantiating a device and setting parameters on it. ### Command Line Arguments The first is to do so by giving OSPRay the command line from `main()` by calling OSPError ospInit(int *argc, const char **argv); OSPRay parses (and removes) its known command line parameters from your application's `main` function. For an example see the [tutorial]. For possible error codes see section [Error Handling and Status Messages]. It is important to note that the arguments passed to `ospInit` are processed in order they are listed. The following parameters (which are prefixed by convention with "`--osp:`") are understood: -------------------------------------------- ----------------------------------------------------- Parameter Description -------------------------------------------- ----------------------------------------------------- `--osp:debug` enables various extra checks and debug output, and disables multi-threading `--osp:num-threads=` use `n` threads instead of per default using all detected hardware threads `--osp:log-level=` set logging level; valid values (in order of severity) are `none`, `error`, `warning`, `info`, and `debug` `--osp:warn-as-error` send `warning` and `error` messages through the error callback, otherwise send `warning` messages through the message callback; must have sufficient `logLevel` to enable warnings `--osp:verbose` shortcut for `--osp:log-level=info` and enable debug output on `cout`, error output on `cerr` `--osp:vv` shortcut for `--osp:log-level=debug` and enable debug output on `cout`, error output on `cerr` `--osp:load-modules=[,...]` load one or more modules during initialization; equivalent to calling `ospLoadModule(name)` `--osp:log-output=` convenience for setting where status messages go; valid values for `dst` are `cerr` and `cout` `--osp:error-output=` convenience for setting where error messages go; valid values for `dst` are `cerr` and `cout` `--osp:device=` use `name` as the type of device for OSPRay to create; e.g., `--osp:device=cpu` gives you the default `cpu` device; Note if the device to be used is defined in a module, remember to pass `--osp:load-modules=` first `--osp:set-affinity=` if `1`, bind software threads to hardware threads; `0` disables binding; default is `0` `--osp:device-params=:[,...]` set one or more other device parameters; equivalent to calling `ospDeviceSet*(param, value)` -------------------------------------------- ----------------------------------------------------- : Command line parameters accepted by OSPRay's `ospInit`. ### Manual Device Instantiation The second method of initialization is to explicitly create the device and possibly set parameters. This method looks almost identical to how other [objects] are created and used by OSPRay (described in later sections). The first step is to create the device with OSPDevice ospNewDevice(const char *type); where the `type` string maps to a specific device implementation. OSPRay always provides the "`cpu`" device, which maps to a fast, local CPU implementation. Other devices can also be added through additional modules, such as distributed MPI device implementations. See next Chapter for details. Once a device is created, you can call void ospDeviceSetParam(OSPObject, const char *id, OSPDataType type, const void *mem); to set parameters on the device. The semantics of setting parameters is exactly the same as `ospSetParam`, which is documented below in the [parameters] section. The following parameters can be set on all devices: ------ ------------------------ ---------------------------------------------- Type Name Description ------ ------------------------ ---------------------------------------------- int numThreads number of threads which OSPRay should use bool disableMipMapGeneration disable the default generation of MIP maps for textures (e.g., to save the additional memory needed) uint logLevel logging level; valid values (in order of severity) are `OSP_LOG_NONE`, `OSP_LOG_ERROR`, `OSP_LOG_WARNING`, `OSP_LOG_INFO`, and `OSP_LOG_DEBUG` string logOutput convenience for setting where status messages go; valid values are `cerr` and `cout` string errorOutput convenience for setting where error messages go; valid values are `cerr` and `cout` bool debug set debug mode; equivalent to `logLevel=debug` and `numThreads=1` bool warnAsError send `warning` and `error` messages through the error callback, otherwise send `warning` messages through the message callback; must have sufficient `logLevel` to enable warnings bool setAffinity bind software threads to hardware threads if set to 1; 0 disables binding omitting the parameter will let OSPRay choose ------ ------------------------ ---------------------------------------------- : Parameters shared by all devices. Once parameters are set on the created device, the device must be committed with void ospDeviceCommit(OSPDevice); To use the newly committed device, you must call void ospSetCurrentDevice(OSPDevice); This then sets the given device as the object which will respond to all other OSPRay API calls. Device handle lifetimes are managed with two calls, the first which increments the internal reference count to the given `OSPDevice` void ospDeviceRetain(OSPDevice) and the second which decrements the reference count void ospDeviceRelease(OSPDevice) Users can change parameters on the device after initialization (from either method above), by calling OSPDevice ospGetCurrentDevice(); This function returns the handle to the device currently used to respond to OSPRay API calls, where users can set/change parameters and recommit the device. If changes are made to the device that is already set as the current device, it does not need to be set as current again. Note this API call will increment the ref count of the returned device handle, so applications must use `ospDeviceRelease` when finished using the handle to avoid leaking the underlying device object. If there is no current device set, this will return an invalid `NULL` handle. When a device is created, its reference count is initially `1`. When a device is set as the current device, it internally has its reference count incremented. Note that `ospDeviceRetain` and `ospDeviceRelease` should only be used with reference counts that the application tracks: removing reference held by the current set device should be handled by `ospShutdown`. Thus, `ospDeviceRelease` should only decrement the reference counts that come from `ospNewDevice`, `ospGetCurrentDevice`, and the number of explicit calls to `ospDeviceRetain`. OSPRay allows applications to query runtime properties of a device in order to do enhanced validation of what device was loaded at runtime. The following function can be used to get these device-specific properties (attributes about the device, not parameter values) int64_t ospDeviceGetProperty(OSPDevice, OSPDeviceProperty); It returns an integer value of the queried property and the following properties can be provided as parameter: OSP_DEVICE_VERSION OSP_DEVICE_VERSION_MAJOR OSP_DEVICE_VERSION_MINOR OSP_DEVICE_VERSION_PATCH OSP_DEVICE_SO_VERSION ### Environment Variables OSPRay's generic device parameters can be overridden via environment variables for easy changes to OSPRay's behavior without needing to change the application (variables are prefixed by convention with "`OSPRAY_`"): --------------------- -------------------------------------------------------- Variable Description --------------------- -------------------------------------------------------- OSPRAY_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. Note that these environment variables take precedence over values specified through `ospInit` or manually set device parameters. ### Error Handling and Status Messages 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 ---------------------- ------------------------------------------------------- : Possible error codes, i.e., valid named constants of type `OSPError`. These error codes are either directly return by some API functions, or are recorded to be later queried by the application via OSPError ospDeviceGetLastErrorCode(OSPDevice); A more descriptive error message can be queried by calling const char* ospDeviceGetLastErrorMsg(OSPDevice); Alternatively, the application can also register a callback function of type typedef void (*OSPErrorCallback)(void *userData, OSPError, const char* errorDetails); via void ospDeviceSetErrorCallback(OSPDevice, OSPErrorCallback, void *userData); to get notified when errors occur. Applications may be interested in messages which OSPRay emits, whether for debugging or logging events. Applications can call void ospDeviceSetStatusCallback(OSPDevice, OSPStatusCallback, void *userData); in order to register a callback function of type typedef void (*OSPStatusCallback)(void *userData, const char* messageText); which OSPRay will use to emit status messages. By default, OSPRay uses a callback which does nothing, so any output desired by an application will require that a callback is provided. Note that callbacks for C++ `std::cout` and `std::cerr` can be alternatively set through `ospInit` or the `OSPRAY_LOG_OUTPUT` environment variable. Applications can clear either callback by passing `NULL` instead of an actual function pointer. ### Loading OSPRay Extensions at Runtime OSPRay's functionality can be extended via plugins (which we call "modules"), which are implemented in shared libraries. To load module `name` from `libospray_module_.so` (on Linux and Mac OS\ X) or `ospray_module_.dll` (on Windows) use OSPError ospLoadModule(const char *name); Modules are searched in OS-dependent paths. `ospLoadModule` returns `OSP_NO_ERROR` if the plugin could be successfully loaded. ### Shutting Down OSPRay When the application is finished using OSPRay (typically on application exit), the OSPRay API should be finalized with void ospShutdown(); This API call ensures that the current device is cleaned up appropriately. Due to static object allocation having non-deterministic ordering, it is recommended that applications call `ospShutdown` before the calling application process terminates. Objects ------- All entities of OSPRay (the [renderer], [volumes], [geometries], [lights], [cameras], ...) are a logical specialization of `OSPObject` and share common mechanism to deal with parameters and lifetime. An important aspect of object parameters is that parameters do not get passed to objects immediately. Instead, parameters are not visible at all to objects until they get explicitly committed to a given object via a call to void ospCommit(OSPObject); at which time all previously additions or changes to parameters are visible at the same time. If a user wants to change the state of an existing object (e.g., to change the origin of an already existing camera) it is perfectly valid to do so, as long as the changed parameters are recommitted. The commit semantic allow for batching up multiple small changes, and specifies exactly when changes to objects will occur. This can impact performance and consistency for devices crossing a PCI bus or across a network. Note that OSPRay uses reference counting to manage the lifetime of all objects, so one cannot explicitly "delete" any object. Instead, to indicate that the application does not need and does not access the given object anymore, call void ospRelease(OSPObject); This decreases its reference count and if the count reaches `0` the object will automatically get deleted. Passing `NULL` is not an error. Note that every handle returned via the API needs to be released when the object is no longer needed, to avoid memory leaks. Sometimes applications may want to have more than one reference to an object, where it is desirable for the application to increment the reference count of an object. This is done with void ospRetain(OSPObject); It is important to note that this is only necessary if the application wants to call `ospRelease` on an object more than once: objects which contain other objects as parameters internally increment/decrement ref counts and should not be explicitly done by the application. ### Parameters Parameters allow to configure the behavior of and to pass data to objects. However, objects do _not_ have an explicit interface for reasons of high flexibility and a more stable compile-time API. Instead, parameters are passed separately to objects in an arbitrary order, and unknown parameters will simply be ignored (though a warning message will be posted). The following function allows adding various types of parameters with name `id` to a given object: void ospSetParam(OSPObject, const char *id, OSPDataType type, const void *mem); The valid parameter names for all `OSPObject`s and what types are valid are discussed in future sections. Note that `mem` must always be a pointer _to_ the object, otherwise accidental type casting can occur. This is especially true for pointer types (`OSP_VOID_PTR` and `OSPObject` handles), as they will implicitly cast to `void\ *`, but be incorrectly interpreted. To help with some of these issues, there also exist variants of `ospSetParam` for specific types, such as `ospSetInt` and `ospSetVec3f` in the OSPRay utility library (found in `ospray_util.h`). Note that half precision float parameters `OSP_HALF, OSP_VEC[234]H` are not supported. Users can also remove parameters that have been explicitly set from `ospSetParam`. Any parameters which have been removed will go back to their default value during the next commit unless a new parameter was set after the parameter was removed. To remove a parameter, use void ospRemoveParam(OSPObject, const char *id); ### Data OSPRay consumes data arrays from the application using a specific object type, `OSPData`. There are several components to describing a data array: element type, 1/2/3 dimensional striding, and whether the array is shared with the application or copied into opaque, OSPRay-owned memory. Shared data arrays require that the application's array memory outlives the lifetime of the created `OSPData`, as OSPRay is referring to application memory. Where this is not preferable, applications use opaque arrays to allow the `OSPData` to own the lifetime of the array memory. However, opaque arrays dictate the cost of copying data into it, which should be kept in mind. Thus, the most efficient way to specify a data array from the application is to created a shared data array, which is done with OSPData ospNewSharedData(const void *sharedData, OSPDataType, uint64_t numItems1, int64_t byteStride1 = 0, uint64_t numItems2 = 1, int64_t byteStride2 = 0, uint64_t numItems3 = 1, int64_t byteStride3 = 0, OSPDeleterCallback = NULL, void *userData = NULL); The call returns an `OSPData` handle to the created array. The calling program guarantees that the `sharedData` pointer will remain valid for the duration that this data array is being used. The number of elements `numItems` must be positive (there cannot be an empty data object). The data is arranged in three dimensions, with specializations to two or one dimension (if some `numItems` are 1). The distance between consecutive elements (per dimension) is given in bytes with `byteStride` and can also be negative. If `byteStride` is zero it will be determined automatically (e.g., as `sizeof(type)`). Strides do not need to be ordered, i.e., `byteStride2` can be smaller than `byteStride1`, which is equivalent to a transpose. However, if the stride should be calculated, then an ordering in dimensions is assumed to disambiguate, i.e., `byteStride1 < byteStride2 < byteStride3`. An application can pass ownership of shared data to OSPRay (for example, when it temporarily created a modified version of its data only to make it compatible with OSPRay) by providing a deleter function that OSPRay will call whenever the time comes to deallocate the shared buffer. The deleter function has the following signature: typedef void (*OSPDeleterCallback)(const void *userData, const void *sharedData); where `sharedData` will receive the address of the buffer and `userData` will receive whatever additional state the function needs to perform the deletion (both provided to `ospNewSharedData` when sharing the data with OSPRay). 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_FUTURE future 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_GROUP group object reference OSP_INSTANCE instance object reference OSP_GEOMETRY geometry object reference OSP_GEOMETRIC_MODEL geometric model object reference OSP_VOLUME volume object reference OSP_VOLUMETRIC_MODEL volumetric model 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_BOOL 8\ bit boolean 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`. If the elements of the array are handles to objects, then their reference counter is incremented. An opaque `OSPData` with memory allocated by OSPRay is created with OSPData ospNewData(OSPDataType, uint64_t numItems1, uint64_t numItems2 = 1, uint64_t numItems3 = 1); To allow for (partial) copies or updates of data arrays use void ospCopyData(const OSPData source, OSPData destination, uint64_t destinationIndex1 = 0, uint64_t destinationIndex2 = 0, uint64_t destinationIndex3 = 0); which will copy the whole^[The number of items to be copied is defined by the size of the source array.] content of the `source` array into `destination` at the given location `destinationIndex`. The `OSPDataType`s of the data objects must match. The region to be copied must be valid inside the destination, i.e., in all dimensions, `destinationIndex + sourceSize <= destinationSize`. The affected region `[destinationIndex, destinationIndex + sourceSize)` is marked as dirty, which may be used by OSPRay to only process or update that sub-region (e.g., updating an acceleration structure). If the destination array is shared with OSPData by the application (created with `ospNewSharedData`), then - the source array must be shared as well (thus `ospCopyData` cannot be used to read opaque data) - if source and destination memory overlaps (aliasing), then behavior is undefined - except if source and destination regions are identical (including matching strides), which can be used by application to mark that region as dirty (instead of the whole `OSPData`) To add a data array as parameter named `id` to another object call also use void ospSetObject(OSPObject, const char *id, OSPData); Volumes ------- Volumes are volumetric data sets with discretely sampled values in 3D space, typically a 3D scalar field. To create a new volume object of given type `type` use OSPVolume ospNewVolume(const char *type); Note that OSPRay's implementation forwards `type` directly to Open VKL, allowing new Open VKL volume types to be usable within OSPRay without the need to change (or even recompile) OSPRay. ### Structured Regular Volume Structured volumes only need to store the values of the samples, because their addresses in memory can be easily computed from a 3D position. A common type of structured volumes are regular grids. Structured regular volumes are created by passing the type string "`structuredRegular`" to `ospNewVolume`. Structured volumes are represented through an `OSPData` 3D array `data` (which may or may not be shared with the application). The voxel data must be laid out in xyz-order^[For consecutive memory addresses the x-index of the corresponding voxel changes the quickest.] and can be compact (best for performance) or can have a stride between voxels, specified through the `byteStride1` parameter when creating the `OSPData`. Only 1D strides are supported, additional strides between scanlines (2D, `byteStride2`) and slices (3D, `byteStride3`) are not. The parameters understood by structured volumes are summarized in the 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 OSPData data the actual voxel 3D [data] bool cellCentered false whether the data is provided per cell (as opposed to per vertex) uint filter `OSP_VOLUME_FILTER_LINEAR` filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` and `OSP_VOLUME_FILTER_CUBIC` uint gradientFilter same as `filter` filter used during gradient computations float background `NaN` value that is used when sampling an undefined region outside the volume domain ------- -------------- ----------------------------- -------------------------- : Configuration parameters for structured regular volumes. The size of the volume is 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`). Data can be provided either per cell or per vertex (the default), selectable via the `cellCentered` parameter (which will also affect the computed bounding box). ### Structured Spherical Volume Structured spherical volumes are also supported, which are created by passing a type string of "`structuredSpherical`" to `ospNewVolume`. The grid dimensions and parameters are defined in terms of radial distance $r$, inclination angle $\theta$, and azimuthal angle $\phi$, conforming with the ISO convention for spherical coordinate systems. The coordinate system and parameters understood by structured spherical volumes are summarized below. ![Coordinate system of structured spherical volumes.][imgStructuredSphericalCoords] ------- -------------- ----------------------------- -------------------------- Type Name Default Description ------- -------------- ----------------------------- -------------------------- vec3f gridOrigin $(0, 0, 0)$ origin of the grid in units of $(r, \theta, \phi)$; angles in degrees vec3f gridSpacing $(1, 180/dim.y, 360/dim.z)$ size of the grid cells in units of $(r, \theta, \phi)$, per default covering the full sphere; angles in degrees OSPData data the actual voxel 3D [data] uint filter `OSP_VOLUME_FILTER_LINEAR` filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` uint gradientFilter same as `filter` filter used during gradient computations float background `NaN` value that is used when sampling an undefined region outside the volume domain ------- -------------- ----------------------------- -------------------------- : Configuration parameters for structured spherical volumes. The dimensions $(r, \theta, \phi)$ 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`). These grid parameters support flexible specification of spheres, hemispheres, spherical shells, spherical wedges, and so forth. The grid extents (computed as `[gridOrigin, gridOrigin + (dimensions - 1) * gridSpacing]`) however must be constrained such that: * $r \geq 0$ * $0 \leq \theta \leq 180$ * $0 \leq \phi \leq 360$ ### Adaptive Mesh Refinement (AMR) Volume OSPRay currently supports block-structured (Berger-Colella) AMR volumes. Volumes are specified as a list of blocks, which exist at levels of refinement in potentially overlapping regions. Blocks exist in a tree structure, with coarser refinement level blocks containing finer blocks. The cell width is equal for all blocks at the same refinement level, though blocks at a coarser level have a larger cell width than finer levels. There can be any number of refinement levels and any number of blocks at any level of refinement. An AMR volume type is created by passing the type string "`amr`" to `ospNewVolume`. Blocks are defined by three parameters: their bounds, the refinement level in which they reside, and the scalar data contained within each block. Note that cell widths are defined _per refinement level_, not per block. -------------- --------------- ----------------- ----------------------------------- Type Name Default Description -------------- --------------- ----------------- ----------------------------------- uint method `OSP_AMR_CURRENT` `OSPAMRMethod` sampling method. Supported methods are: `OSP_AMR_CURRENT` `OSP_AMR_FINEST` `OSP_AMR_OCTANT` float[] cellWidth NULL array of each level's cell width box3i[] block.bounds NULL [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] 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 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. Lastly, note that the `gridOrigin` and `gridSpacing` parameters act just like the structured volume equivalent, but they only modify the root (coarsest level) of refinement. In particular, OSPRay's / Open VKL's AMR implementation was designed to 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 : finds the finest refinement level at that cell and interpolates through this "current" level 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 : interpolates through all available refinement levels at that cell. This method avoids discontinuities at refinement level boundaries at the cost of performance Details and more information can be found in the publication for the implementation\ [3]. 1. M.J. Berger and P. Colella, "Local adaptive mesh refinement for shock hydrodynamics." Journal of Computational Physics 82.1 (1989): 64-84. DOI: 10.1016/0021-9991(89)90035-1 2. M. Adams, P. Colella, D.T. Graves, J.N. Johnson, N.D. Keen, T.J. Ligocki, D.F. Martin. P.W. McCorquodale, D. Modiano. P.O. Schwartz, T.D. Sternberg, and B. Van Straalen, "Chombo Software Package for AMR Applications – Design Document", Lawrence Berkeley National Laboratory Technical Report LBNL-6616E. 3. I. Wald, C. Brownlee, W. Usher, and A. Knoll, "CPU volume rendering of adaptive mesh refinement data". SIGGRAPH Asia 2017 Symposium on Visualization – SA ’17, 18(8), 1–8. DOI: 10.1145/3139295.3139305 ### Unstructured Volume Unstructured volumes can have their topology and geometry freely defined. Geometry can be composed of tetrahedral, hexahedral, wedge or pyramid cell types. The data format used is compatible with VTK and consists of multiple arrays: vertex positions and values, vertex indices, cell start indices, cell types, and cell values. An unstructured volume type is created by passing the type string "`unstructured`" to `ospNewVolume`. Sampled cell values can be specified either per-vertex (`vertex.data`) or per-cell (`cell.data`). If both arrays are set, `cell.data` takes precedence. Similar to a mesh, each cell is formed by a group of indices into the vertices. For each vertex, the corresponding (by array index) data value will be used for sampling when rendering, if specified. The index order for a tetrahedron is the same as `VTK_TETRA`: bottom triangle counterclockwise, then the top vertex. For hexahedral cells, each hexahedron is formed by a group of eight indices into the vertices and data values. Vertex ordering is the same as `VTK_HEXAHEDRON`: four bottom vertices counterclockwise, then top four counterclockwise. For wedge cells, each wedge is formed by a group of six indices into the vertices and data values. Vertex ordering is the same as `VTK_WEDGE`: three bottom vertices counterclockwise, then top three counterclockwise. For pyramid cells, each cell is formed by a group of five indices into the vertices and data values. Vertex ordering is the same as `VTK_PYRAMID`: four bottom vertices counterclockwise, then the top vertex. To maintain VTK data compatibility, the `index` array may be specified with cell sizes interleaved with vertex indices in the following format: $n, id_1, ..., id_n, m, id_1, ..., id_m$. This alternative `index` array layout can be enabled through the `indexPrefixed` flag (in which case, the `cell.type` parameter must be omitted). ------------------- ------------------ -------- --------------------------------------- Type Name Default Description ------------------- ------------------ -------- --------------------------------------- vec3f[] vertex.position [data] array of vertex positions float[] vertex.data [data] array of vertex data values to be sampled uint32[] / uint64[] index [data] array of indices (into the vertex array(s)) that form cells bool indexPrefixed false indicates that the `index` array is compatible to VTK, where the indices of each cell are prefixed with the number of vertices uint32[] / uint64[] cell.index [data] array of locations (into the index array), specifying the first index of each cell float[] cell.data [data] array of cell data values to be sampled uint8[] cell.type [data] array of cell types (VTK compatible), only set if `indexPrefixed = false`. Supported types are: `OSP_TETRAHEDRON` `OSP_HEXAHEDRON` `OSP_WEDGE` `OSP_PYRAMID` bool hexIterative false hexahedron interpolation method, defaults to fast non-iterative version which could have rendering inaccuracies may appear if hex is not parallelepiped bool precomputedNormals false whether to accelerate by precomputing, at a cost of 12 bytes/face float background `NaN` value that is used when sampling an undefined region outside the volume domain ------------------- ------------------ -------- --------------------------------------- : Configuration parameters for unstructured volumes. ### VDB Volume VDB volumes implement a data structure that is very similar to the data structure outlined in Museth\ [1], they are created by passing the type string "`vdb`" to `ospNewVolume`. The data structure is a hierarchical regular grid at its core: Nodes are regular grids, and each grid cell may either store a constant value (this is called a tile), or child pointers. Nodes in VDB trees are wide: Nodes on the first level have a resolution of 32^3^ voxels, on the next level 16^3^, and on the leaf level 8^3^ voxels. All nodes on a given level have the same resolution. This makes it easy to find the node containing a coordinate using shift operations (see\ [1]). VDB leaf nodes are implicit in OSPRay / Open VKL: they are stored as pointers to user-provided data. ![Topology of VDB volumes.][imgVdbStructure] VDB volumes interpret input data as constant cells (which are then potentially filtered). This is in contrast to `structuredRegular` volumes, which have a vertex-centered interpretation. The VDB implementation in OSPRay / Open VKL follows the following goals: - Efficient data structure traversal on vector architectures. - Enable the use of industry-standard `.vdb` files created through the OpenVDB library. - Compatibility with OpenVDB on a leaf data level, so that `.vdb` file may be loaded with minimal overhead. VDB volumes have the following parameters: ---------- ----------------- ------------------------------------------------- Type Name Description ---------- ----------------- ------------------------------------------------- int maxSamplingDepth do not descend further than to this depth during sampling, the maximum value and the default is 3 uint32[] node.level level on which each input node exists, may be 1, 2 or 3 (levels are counted from the root level = 0 down) vec3i[] node.origin the node origin index (per input node) OSPData[] node.data [data] arrays with the node data (per input node). Nodes that are tiles are expected to have single-item arrays. Leaf-nodes with grid data expected to have compact 3D arrays in zyx layout (z changes most quickly) with the correct number of voxels for the `level`. Only `OSP_FLOAT` is supported as field `OSPDataType`. OSPData nodesPackedDense optionally provided instead of `node.data`, a single array of all dense node data in a contiguous zyx layout, provided in the same order as the corresponding `node.*` parameters OSPData nodesPackedTile optionally provided instead of `node.data`, a single array of all tile node data in a contiguous layout, provided in the same order as the corresponding `node.*` parameters uint32[] node.format for each input node, whether it is of format `OSP_VOLUME_FORMAT_DENSE_ZYX` (and thus stored in `nodesPackedDense`), or `OSP_VOLUME_FORMAT_TILE` (stored in `nodesPackedTile`) uint filter filter used for reconstructing the field, default is `OSP_VOLUME_FILTER_LINEAR`, alternatively `OSP_VOLUME_FILTER_NEAREST`, or `OSP_VOLUME_FILTER_CUBIC`. uint gradientFilter filter used for reconstructing the field during gradient computations, default same as `filter` float background value that is used when sampling an undefined region outside the volume domain, default `NaN` ---------- ----------------- ------------------------------------------------- : Configuration parameters for VDB volumes. The `nodesPackedDense` and `nodesPackedTile` together with `node.format` parameters may be provided instead of `node.data`; this packed data layout may provide better performance. 1. Museth, K. VDB: High-Resolution Sparse Volumes with Dynamic Topology. ACM Transactions on Graphics 32(3), 2013. DOI: 10.1145/2487228.2487235 ### Particle Volume Particle volumes consist of a set of points in space. Each point has a position, a radius, and a weight typically associated with an attribute. Particle volumes are created by passing the type string "`particle`" to `ospNewVolume`. A radial basis function defines the contribution of that particle. Currently, we use the Gaussian radial basis function $$\phi(P) = w \exp\left(-\frac{(P - p)^2}{2 r^2}\right),$$ where $P$ is the particle position, $p$ is the sample position, $r$ is the radius and $w$ is the weight. At each sample, the scalar field value is then computed as the sum of each radial basis function $\phi$, for each particle that overlaps it. The OSPRay / Open VKL implementation is similar to direct evaluation of samples in Reda et al.\ [2]. It uses an Embree-built BVH with a custom traversal, similar to the method in\ [1]. -------- ----------------------- -------- --------------------------------------- Type Name Default Description -------- ----------------------- -------- --------------------------------------- vec3f[] particle.position [data] array of particle positions float[] particle.radius [data] array of particle radii float[] particle.weight NULL optional [data] array of particle weights, specifying the height of the kernel. float radiusSupportFactor 3.0 The multiplier of the particle radius required for support. Larger radii ensure smooth results at the cost of performance. In the Gaussian kernel, the radius is one standard deviation ($\sigma$), so a value of 3 corresponds to $3 \sigma$. float clampMaxCumulativeValue 0 The maximum cumulative value possible, set by user. All cumulative values will be clamped to this, and further traversal (RBF summation) of particle contributions will halt when this value is reached. A value of zero or less turns this off. bool estimateValueRanges true Enable heuristic estimation of value ranges which are used in internal acceleration structures as well as for determining the volume's overall value range. When set to `false`, the user *must* specify `clampMaxCumulativeValue`, and all value ranges will be assumed [0–`clampMaxCumulativeValue`]. Disabling this switch may improve volume commit time, but will make volume rendering less efficient. -------- ----------------------- -------- --------------------------------------- : Configuration parameters for particle volumes. 1. A. Knoll, I. Wald, P. Navratil, A. Bowen, K. Reda, M.E., Papka, and K. Gaither, "RBF Volume Ray Casting on Multicore and Manycore CPUs", 2014, Computer Graphics Forum, 33: 71–80. doi:10.1111/cgf.12363 2. K. Reda, A. Knoll, K. Nomura, M. E. Papka, A. E. Johnson and J. Leigh, "Visualizing large-scale atomistic simulations in ultra-resolution immersive environments", 2013 IEEE Symposium on Large-Scale Data Analysis and Visualization (LDAV), Atlanta, GA, 2013, pp. 59–65. ### Transfer Function Transfer functions map the scalar values of volumes to color and opacity and thus they can be used to visually emphasize certain features of the volume. To create a new transfer function of given type `type` use OSPTransferFunction ospNewTransferFunction(const char *type); The returned handle can be assigned to a volumetric model (described below) as parameter "`transferFunction`" using `ospSetObject`. One type of transfer function that is supported by OSPRay is the linear transfer function, which interpolates between given equidistant colors and opacities. It is create by passing the string "`piecewiseLinear`" to `ospNewTransferFunction` and it is controlled by these parameters: Type Name Description ------------ ----------- ---------------------------------------------- vec3f[] color [data] array of colors (linear RGB) float[] opacity [data] array of opacities box1f value domain (scalar range) this function maps from ------------ ----------- ---------------------------------------------- : Parameters accepted by the linear transfer function. The arrays `color` and `opacity` can be of different length. ### VolumetricModels Volumes in OSPRay are given volume rendering appearance information through VolumetricModels. This decouples the physical representation of the volume (and possible acceleration structures it contains) to rendering-specific parameters (where more than one set may exist concurrently). To create a volume instance, call OSPVolumetricModel ospNewVolumetricModel(OSPVolume); The passed volume can be `NULL` as long as the volume to be used is passed as a parameter. If both a volume is specified on object creation and as a parameter, the parameter value is used. If the parameter value is later removed, the volume object passed on object creation is again used. -------------------- ----------------- -------- -------------------------------------- Type Name Default Description -------------------- ----------------- -------- -------------------------------------- OSPVolume volume optional [volume] object this model references OSPTransferFunction transferFunction [transfer function] to use float densityScale 1.0 makes volumes uniformly thinner or thicker float anisotropy 0.0 anisotropy of the (Henyey-Greenstein) phase function in [-1–1] ([path tracer] only), default to isotropic scattering uint32 id -1u optional user ID, for [framebuffer] channel `OSP_FB_ID_OBJECT` -------------------- ----------------- -------- --------------------------------------- : Parameters understood by VolumetricModel. Geometries ---------- Geometries in OSPRay are objects that describe intersectable surfaces. To create a new geometry object of given type `type` use OSPGeometry ospNewGeometry(const char *type); Note that in the current implementation geometries are limited to a maximum of 2^32^ primitives. ### Mesh A mesh consisting of either triangles or quads is created by calling `ospNewGeometry` with type string "`mesh`". Once created, a mesh recognizes the following parameters: -------------------- ----------------------- --------------------------------- Type Name Description -------------------- ----------------------- --------------------------------- vec3f[] vertex.position [data] array of vertex positions, overridden by `motion.*` arrays vec3f[] normal [data] array of face-varying normals, overridden by `motion.*` arrays vec3f[] vertex.normal [data] array of vertex-varying normals, overridden by `motion.*` arrays vec4f[] / vec3f[] color [data] array of face-varying colors (linear RGBA/RGB) vec4f[] / vec3f[] vertex.color [data] array of vertex-varying colors (linear RGBA/RGB) vec2f[] texcoord [data] array of face-varying texture coordinates vec2f[] vertex.texcoord [data] array of vertex-varying texture coordinates vec3ui[] / vec4ui[] index [data] array of (either triangle or quad) indices (into the vertex array(s)) bool quadSoup when no explicit `index` is given, indicates whether to assume a 'soup' of quads instead of triangles, default false vec3f[][] motion.vertex.position [data] array of vertex position arrays (uniformly distributed keys for deformation motion blur) vec3f[][] motion.normal [data] array of face-varying normal arrays (uniformly distributed keys for deformation motion blur) vec3f[][] motion.vertex.normal [data] array of vertex-varying normal arrays (uniformly distributed keys for deformation motion blur) box1f time time associated with first and last key in `motion.*` arrays (for deformation motion blur), default [0, 1] -------------------- ----------------------- --------------------------------- : Parameters defining a mesh geometry. The data type of index arrays differentiates between the underlying geometry, triangles are used for a index with `vec3ui` type and quads for `vec4ui` type. Quads are internally handled as a pair of two triangles, thus mixing triangles and quads is supported by encoding some triangle as a quad with the last two vertex indices being identical (`w=z`). The `vertex.position` array is mandatory to create a valid mesh. The `index` array is optional. If none is provided, a 'triangle soup' is assumed, i.e., each three consecutive vertices form one triangle; unless the boolean `quadSoup` is set to true, then a 'quad soup' is assumed i.e., each four subsequent vertices form one quad. If the size of the `vertex.position` array is not a multiple of three for triangles or four for quads, the remainder vertices are ignored. Face-varying attributes (`normal`, `motion.normal`, `color`, `texcoord`) map unique values to each vertex of a primitive/face (triangle or quad), thus attributes can be different for the same vertex that is shared by multiple primitives. Essentially, face-varying attributes are a 'attribute soup' and behave similar to the implicit index, the size of the array must be at least three times the number of triangles or four times the number of quads, respectively. Face-varying attributes take precedence over the respective vertex attributes (`vertex.normal`, `motion.vertex.normal`, `vertex.color`, `vertex.texcoord`) when both arrays of the same attribute are present. ### Subdivision A mesh consisting of subdivision surfaces, created by specifying a geometry of type "`subdivision`". Once created, a subdivision recognizes the following parameters: ------- ------------------- -------------------------------------------------- Type Name Description ------- ------------------- -------------------------------------------------- vec3f[] vertex.position [data] array of vertex positions vec4f[] color optional [data] array of face-varying colors (linear RGBA) vec4f[] vertex.color optional [data] array of vertex-varying colors (linear RGBA) vec2f[] texcoord optional [data] array of vertex-varying texture coordinates vec2f[] vertex.texcoord optional [data] array of vertex-varying texture coordinates float level global level of tessellation, default 5 uint[] index [data] array of indices (into the vertex array(s)) float[] index.level optional [data] array of per-edge levels of tessellation, overrides global level uint[] face optional [data] array holding the number of indices/edges (3 to 15) per face, defaults to 4 (a pure quad mesh) vec2i[] edgeCrease.index optional [data] array of edge crease indices float[] edgeCrease.weight optional [data] array of edge crease weights uint[] vertexCrease.index optional [data] array of vertex crease indices float[] vertexCrease.weight optional [data] array of vertex crease weights uint mode `OSPSubdivisionMode` subdivision edge boundary mode, supported modes are: `OSP_SUBDIVISION_NO_BOUNDARY` `OSP_SUBDIVISION_SMOOTH_BOUNDARY` (default) `OSP_SUBDIVISION_PIN_CORNERS` `OSP_SUBDIVISION_PIN_BOUNDARY` `OSP_SUBDIVISION_PIN_ALL` ------- ------------------- -------------------------------------------------- : Parameters defining a Subdivision geometry. The `vertex` and `index` arrays are mandatory to create a valid subdivision surface. If no `face` array is present then a pure quad mesh is assumed (the number of indices must be a multiple of 4). Optionally supported are edge and vertex creases. ### Spheres A geometry consisting of individual spheres, each of which can have an own radius, is created by calling `ospNewGeometry` with type string "`sphere`". The spheres will not be tessellated but rendered procedurally and are thus perfectly round. To allow a variety of sphere representations in the application this geometry allows a flexible way of specifying the data of center position and radius within a [data] array: -------- ---------------- -------- --------------------------------------- Type Name Default Description -------- ---------------- -------- --------------------------------------- vec3f[] sphere.position [data] array of center positions float[] sphere.radius NULL optional [data] array of the per-sphere radius vec3f[] sphere.normal NULL optional [data](#data) array of normals (only for “oriented discâ€) vec2f[] sphere.texcoord NULL optional [data] array of texture coordinates (constant per sphere) float radius 0.01 default radius for all spheres (if `sphere.radius` is not set) uint type `OSPSphereType` for rendering the sphere. Supported types are: `OSP_SPHERE` (default) `OSP_DISC` `OSP_ORIENTED_DISC` -------- ---------------- -------- --------------------------------------- : Parameters defining a spheres geometry. ### Curves 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] array of vertex position and per-vertex radius vec2f[] vertex.texcoord [data] array of per-vertex texture coordinates vec4f[] vertex.color [data] array of corresponding vertex colors (linear RGBA) vec3f[] vertex.normal [data] array of curve normals (only for "ribbon" curves) vec4f[] vertex.tangent [data] array of curve tangents (only for "hermite" curves) uint32[] index [data] array of indices to the first vertex or tangent of a curve segment uint type `OSPCurveType` for rendering the curve. Supported types are: `OSP_FLAT` `OSP_ROUND` `OSP_RIBBON` `OSP_DISJOINT` uint 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. Positions in `vertex.position_radius` parameter supports per-vertex varying radii with data type `vec4f[]` and instantiate Embree curves 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 : 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 : 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 : 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 $(p0, p1, p2, p3)$ and $(p1, p2, p3, p4)$ 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 : 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 tangent buffer. This basis is interpolating, thus does exactly go through the first and second control point, and the first order 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 : The indices point to the first of 4 consecutive control points in the vertex buffer. If $(p0, p1, p2, p3)$ represent the points then this basis goes through $p1$ and $p2$, with tangents as $(p2-p0)/2$ and $(p3-p1)/2$. The following section describes the properties of different curve types' and how they define the geometry of a curve: OSP_FLAT : This type enables faster rendering as the curve is rendered as a connected sequence of ray facing quads. 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 : 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 : 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. ### Boxes OSPRay can directly render axis-aligned bounding boxes without the need to convert them to quads or triangles. To do so create a boxes geometry by calling `ospNewGeometry` with type string "`box`". Type Name Description ---------- ---------- ------------------------------------------------------ box3f[] box [data] array of boxes ---------- ---------- ------------------------------------------------------ : Parameters defining a boxes geometry. ### Planes OSPRay can directly render planes defined by plane equation coefficients in its implicit form $ax + by + cz + d = 0$. By default 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] array of plane coefficients $(a, b, c, d)$ box3f[] plane.bounds optional [data] array of bounding boxes ---------- ------------------ ------------------------------------------------- : Parameters defining a planes geometry. ### Isosurfaces OSPRay can directly render multiple isosurfaces of a volume without first tessellating them. To do so create an isosurfaces geometry by calling `ospNewGeometry` with type string "`isosurface`". The appearance information of the surfaces is set through the Geometric Model. Per-isosurface colors can be set by passing per-primitive colors to the Geometric Model, in order of the isosurface array. Type Name Description ------------------ --------- -------------------------------------------------- float isovalue single isovalues float[] isovalue [data] array of isovalues OSPVolume volume handle of the [Volume] to be isosurfaced ------------------ --------- -------------------------------------------------- : Parameters defining an isosurfaces geometry. ### GeometricModels Geometries are matched with surface appearance information through GeometricModels. These take a geometry, which defines the surface representation, and applies either full-object or per-primitive color and material information. To create a geometric model, call OSPGeometricModel ospNewGeometricModel(OSPGeometry); The passed geometry can be `NULL` as long as the geometry to be used is passed as a parameter. If both a geometry is specified on object creation and as a parameter, the parameter value is used. If the parameter value is later removed, the geometry object passed on object creation is again used. Color and material are fetched with the primitive ID of the hit (clamped to the valid range, thus a single color or material is fine), or mapped first via the `index` array (if present). All parameters are optional, however, some renderers (notably the [path tracer]) require a material to be set. Materials are either handles of `OSPMaterial`, or indices into the `material` array on the [renderer], which allows to build a [world] which can be used by different types of renderers. An `invertNormals` flag allows to invert (shading) normal vectors of the rendered geometry. That is particularly useful for clipping. By changing normal vectors orientation one can control whether inside or outside of the clipping geometry is being removed. For example, a clipping geometry with normals oriented outside clips everything what's inside. ----------------------------------------------- ------------- ---------------------------------------------------- Type Name Description ----------------------------------------------- ------------- ---------------------------------------------------- OSPGeometry geometry optional [geometry] object this model references OSPMaterial / OSPMaterial[] / uint32 / uint32[] material optional ([data] array of per-primitive) [material], may be an index into the `material` parameter on the renderer (if it exists) vec4f / vec4f[] color optional ([data] array of per-primitive) color assigned to the geometry (linear RGBA) uint8[] index optional [data] array of per-primitive indices into `color` and `material` bool invertNormals inverts all shading normals (Ns), default false uint32 id optional user ID, for [framebuffer] channel `OSP_FB_ID_OBJECT`, default -1u ----------------------------------------------- ------------- ---------------------------------------------------- : Parameters understood by GeometricModel. Lights ------ To create a new light source of given type `type` use OSPLight ospNewLight(const char *type); All light sources accept the following parameters: --------- ------------------ -------- -------------------------------------------- Type Name Default Description --------- ------------------ -------- -------------------------------------------- vec3f color white color of the light (linear RGB) float intensity 1 intensity of the light (a factor) uint intensityQuantity `OSPIntensityQuantity` to set the radiometric quantity represented by `intensity`. The default value depends on the light source. bool visible true whether the light can be directly seen --------- ------------------ -------- -------------------------------------------- : Parameters accepted by all lights. In OSPRay the `intensity` parameter of a light source can correspond to different types of radiometric quantities. The type of the value represented by a light's `intensity` parameter is set using `intensityQuantity`, which accepts values from the enum type `OSPIntensityQuantity`. The supported types of `OSPIntensityQuantity` 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/m^2^ 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`, or when using `intensityDistribution`). ---------------------------------- ---------------------------------------------------- : Types of radiometric quantities used to interpret a light's `intensity` parameter. ### Photometric Lights Measured light sources (IES, EULUMDAT, ...) are supported by the `sphere`, `spot`, and `quad` lights when setting an `intensityDistribution` [data] array to modulate the intensity per direction. The mapping is using the C-γ coordinate system (see also below figure): the values of the first (or only) dimension of `intensityDistribution` are uniformly mapped to γ in [0–π]; the first intensity value to 0, the last value to Ï€, thus at least two values need to be present. ![C-γ coordinate system for the mapping of `intensityDistribution` with photometric lights.][imgCGammaCoords] If the array has a second dimension then the intensities are not rotational symmetric around the main direction (where angle γ is zero), but are accordingly mapped to the C-halfplanes in [0–2Ï€]; the first "row" of values to 0 and 2Ï€, the other rows such that they have uniform distance to its neighbors. The orientation of the C0-plane is specified via `c0`. ---------- --------------------- --------------------------------------------- Type Name Description ---------- --------------------- --------------------------------------------- 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 for photometric lights. When using an `intensityDistribution` then the default and only valid value for `intensityQuantity` is `OSP_INTENSITY_QUANTITY_SCALE`. The following light types are supported by most OSPRay renderers. ### Directional Light / Distant Light The distant light (or traditionally the directional light) is thought to be far away (outside of the scene), thus its light arrives (almost) as parallel rays. It is created by passing the type string "`distant`" to `ospNewLight`. The distant light supports `OSP_INTENSITY_QUANTITY_RADIANCE` and `OSP_INTENSITY_QUANTITY_IRRADIANCE` (default) as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) understood by all lights the distant light supports the following special parameters: 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 soft shadows when the renderer uses stochastic sampling (like the [path tracer]). For instance, the apparent size of the sun is about 0.53°. ### Point Light / Sphere Light The sphere light (or the special case point light) is a light emitting uniformly in all directions from the surface toward the outside. It does not emit any light toward the inside of the sphere. It is created by passing the type string "`sphere`" to `ospNewLight`. The point light supports only `OSP_INTENSITY_QUANTITY_SCALE` when `intensityDistribution` is set, or otherwise `OSP_INTENSITY_QUANTITY_POWER`, `OSP_INTENSITY_QUANTITY_INTENSITY` (then default) and `OSP_INTENSITY_QUANTITY_RADIANCE` as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) understood by all lights and the [photometric parameters](#photometric-lights) the sphere light supports the following special parameters: Type Name Default Description ------- ---------- ------------ -------------------------------- vec3f position $(0, 0, 0)$ the center of the sphere light float radius 0 the size of the sphere light vec3f direction $(0, 0, 1)$ main orientation of `intensityDistribution` ------- ---------- ------------ -------------------------------- : Special parameters accepted by the sphere light. Setting the radius to a value greater than zero will result in soft shadows when the renderer uses stochastic sampling (like the [path tracer]). ### Spotlight / Ring Light The spotlight is a light emitting into a cone of directions. It is created by passing the type string "`spot`" to `ospNewLight`. The spotlight supports only `OSP_INTENSITY_QUANTITY_SCALE` when `intensityDistribution` is set, or otherwise `OSP_INTENSITY_QUANTITY_POWER`, `OSP_INTENSITY_QUANTITY_INTENSITY` (then default) and `OSP_INTENSITY_QUANTITY_RADIANCE` as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) understood by all lights and the [photometric parameters](#photometric-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 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 ---------- --------------------- ----------- --------------------------------- : Special parameters accepted by the spotlight. ![Angles used by the spotlight.][imgSpotLight] Setting the radius to a value greater than zero will result in soft shadows when the renderer uses stochastic sampling (like the [path tracer]). Additionally setting the inner radius will result in a ring instead of a disk emitting the light. ### Quad Light The quad^[actually a parallelogram] light is a planar, procedural area light source emitting uniformly on one side into the half-space. It is created by passing the type string "`quad`" to `ospNewLight`. The quad light supports only `OSP_INTENSITY_QUANTITY_SCALE` when `intensityDistribution` is set, or otherwise `OSP_INTENSITY_QUANTITY_POWER`, `OSP_INTENSITY_QUANTITY_INTENSITY` and `OSP_INTENSITY_QUANTITY_RADIANCE` (then default) as `intensityQuantity` parameter. In addition to the [general parameters](#lights) understood by all lights and the [photometric parameters](#photometric-lights) the quad light supports the following special parameters: 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] The emission side is determined by the cross product of `edge1`×`edge2`. which is also the main emission direction for `intensityDistribution`. Note that only renderers that use stochastic sampling (like the path 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 illuminating it from infinity. It is created by passing the type string "`hdri`" to `ospNewLight`. The values of the HDRI correspond to radiance and therefore the HDRI light only accepts `OSP_INTENSITY_QUANTITY_SCALE` as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) the HDRI light supports the following special parameters: ------------ --------- ------------ -------------------------------------------------- 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]) OSPTexture map environment map in latitude / longitude format ------------ --------- ------------ -------------------------------------------------- : Special parameters accepted by the HDRI light. ![Orientation and Mapping of an HDRI Light.][imgHDRILight] Note that the [SciVis renderer] only shows the HDRI light in the background (like an environment map) without computing illumination of the scene. ### Ambient Light The ambient light surrounds the scene and illuminates it from infinity with constant radiance (determined by combining the [parameters `color` and `intensity`](#lights)). It is created by passing the type string "`ambient`" to `ospNewLight`. The ambient light supports `OSP_INTENSITY_QUANTITY_RADIANCE` and `OSP_INTENSITY_QUANTITY_IRRADIANCE` (default) as `intensityQuantity` parameter value. Note that the [SciVis renderer] uses ambient lights to control the color and intensity of the computed ambient occlusion (AO). ### Sun-Sky Light The sun-sky light is a combination of a `distant` light for the sun and a procedural `hdri` light for the sky. It is created by passing the type string "`sunSky`" to `ospNewLight`. The sun-sky light surrounds the scene and illuminates it from infinity and can be used for rendering outdoor scenes. The radiance values are calculated using the HoÅ¡ek-Wilkie sky model and solar radiance function. The underlying model of the sun-sky light returns radiance values and therefore the light only accepts `OSP_INTENSITY_QUANTITY_SCALE` as `intensityQuantity` parameter value. To rescale the returned radiance of the sky model the 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 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. The lowest elevation for the sun is restricted to the horizon. Note that the [SciVis renderer] only computes illumination from the sun (yet the sky is still shown in the background, like an environment map). ### Emissive Objects The [path tracer] will consider illumination by [geometries] which have a light emitting material assigned (for example the [Luminous] or [Principled] material). Materials --------- Materials describe how light interacts with surfaces, they give objects their distinctive look. To create a new material of given type `type` call OSPMaterial ospNewMaterial(const char *material_type); The returned handle can then be used to assign the material to a given geometry with void ospSetObject(OSPGeometricModel, "material", OSPMaterial); ### OBJ Material The OBJ material is the workhorse material supported by both the [SciVis renderer] and the [path tracer] (the [Ambient Occlusion renderer] only uses the `kd` and `d` parameter). It offers widely used common properties like diffuse and specular reflection and is based on the [MTL material 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–10^4^\] float d opaque opacity vec3f tf black transparency filter color (linear RGB) OSPTexture map_bump NULL normal map ------------- --------- ---------- ----------------------------------------- : Main parameters of the OBJ material. In particular when using the path tracer it is important to adhere to the principle of energy conservation, i.e., that the amount of light reflected by a surface is not larger than the light arriving. Therefore the path tracer issues a warning and renormalizes the color parameters if the sum of `kd`, `ks`, and `tf` is larger than one in any color channel. Similarly important to mention is that almost all materials of the real world reflect at most only about 80% of the incoming light. So even for a white sheet of paper or white wall paint do better not set `kd` larger than 0.8; otherwise rendering times are unnecessary long and the contrast in the final images is low (for example, the corners of a white room would hardly be discernible, as can be seen in the figure below). ![Comparison of diffuse rooms with 100% reflecting white paint (left) and realistic 80% reflecting white paint (right), which leads to higher overall contrast. Note that exposure has been adjusted to achieve similar brightness levels.][imgDiffuseRooms] If present, the color component of [geometries] is also used for the diffuse color `kd` and the alpha component is also used for 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)$^[respectively $(127, 127, 255)$ for 8\ bit textures and $(32767, 32767, 65535)$ for 16\ bit textures] represents the unperturbed shading normal $(0, 0, 1)$. Because of this encoding an sRGB gamma [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.][imgNormalMap] Note that `tf` colored transparency is implemented in the SciVis and the path tracer but normal mapping with `map_bump` is currently supported in the path tracer only. All parameters (except `tf`) can be textured by passing a [texture] handle, prefixed with "`map_`". The fetched texels are multiplied by the respective parameter value. If only the texture is given (but not the corresponding parameter), only the texture is used (the default value of the parameter is *not* multiplied). The color textures `map_kd` and `map_ks` are typically in one of the sRGB gamma encoded formats, whereas textures `map_ns` and `map_d` are usually in a linear format (and only the first component is used). Additionally, all textures support [texture transformations]. ![Rendering of a OBJ material with wood textures.][imgMaterialOBJ] ### Principled The Principled material is the most complex material offered by the [path tracer], which is capable of producing a wide variety of materials (e.g., plastic, metal, wood, glass) by combining multiple different layers and lobes. It uses the GGX microfacet distribution with approximate multiple scattering for dielectrics and metals, uses the Oren-Nayar model for diffuse reflection, and is energy conserving. To create a Principled material, pass the type string "`principled`" to `ospNewMaterial`. Its parameters are listed in the table below. ------ ----------------- ---------- ------------------------------------------------------ Type Name Default Description ------ ----------------- ---------- ------------------------------------------------------ vec3f baseColor white 0.8 base reflectivity (diffuse and/or metallic, linear RGB) vec3f edgeColor white edge tint (metallic only, linear RGB) float metallic 0 mix between dielectric (diffuse and/or specular) and metallic (specular only with complex IOR) in [0–1] float diffuse 1 diffuse reflection weight in [0–1] float specular 1 specular reflection/transmission weight in [0–1] float ior 1 dielectric index of refraction float transmission 0 specular transmission weight in [0–1] vec3f transmissionColor white attenuated color due to transmission (Beer's law, linear RGB) float transmissionDepth 1 distance at which color attenuation is equal to transmissionColor float roughness 0 diffuse and specular roughness in [0–1], 0 is perfectly smooth float anisotropy 0 amount of specular anisotropy in [0–1] float rotation 0 rotation of the direction of anisotropy in [0–1], 1 is going full circle float normal 1 default normal map/scale for all layers float baseNormal 1 base normal map/scale (overrides default normal) bool thin false flag specifying whether the material is thin or solid float thickness 1 thickness of the material (thin only), affects the amount of color attenuation due to specular transmission float backlight 0 amount of diffuse transmission (thin only) in [0–2], 1 is 50% reflection and 50% transmission, 2 is transmission only float coat 0 clear coat layer weight in [0–1] float coatIor 1.5 clear coat index of refraction vec3f coatColor white clear coat color tint (linear RGB) float coatThickness 1 clear coat thickness, affects the amount of color attenuation float coatRoughness 0 clear coat roughness in [0–1], 0 is perfectly smooth float coatNormal 1 clear coat normal map/scale (overrides default normal) float sheen 0 sheen layer weight in [0–1] vec3f sheenColor white sheen color tint (linear RGB) float sheenTint 0 how much sheen is tinted from sheenColor toward baseColor float sheenRoughness 0.2 sheen roughness in [0–1], 0 is perfectly smooth float opacity 1 cut-out opacity/transparency, 1 is fully opaque vec3f emissiveColor black color (and intensity) of the emitted light ------ ----------------- ---------- ------------------------------------------------------ : Parameters of the Principled material. All parameters can be textured by passing a [texture] handle, prefixed with "`map_`" (e.g., "`map_baseColor`"). [texture transformations] are supported as well. ![Rendering of a Principled coated brushed metal material with textured anisotropic rotation and a dust layer (sheen) on top.][imgMaterialPrincipled] ### CarPaint The CarPaint material is a specialized version of the Principled material for rendering different types of car paints. To create a CarPaint material, pass the type string "`carPaint`" to `ospNewMaterial`. Its parameters are listed in the table below. ------ ----------------- ---------- ------------------------------------------------------ Type Name Default Description ------ ----------------- ---------- ------------------------------------------------------ vec3f baseColor white 0.8 diffuse base reflectivity (linear RGB) float roughness 0 diffuse roughness in [0–1], 0 is perfectly smooth float normal 1 normal map/scale vec3f flakeColor Aluminium color of metallic flakes (linear RGB) float flakeDensity 0 density of metallic flakes in [0–1], 0 disables flakes, 1 fully covers the surface with flakes float flakeScale 100 scale of the flake structure, higher values increase the amount of flakes float flakeSpread 0.3 flake spread in [0–1] float flakeJitter 0.75 flake randomness in [0–1] float flakeRoughness 0.3 flake roughness in [0–1], 0 is perfectly smooth float coat 1 clear coat layer weight in [0–1] float coatIor 1.5 clear coat index of refraction vec3f coatColor white clear coat color tint (linear RGB) float coatThickness 1 clear coat thickness, affects the amount of color attenuation float coatRoughness 0 clear coat roughness in [0–1], 0 is perfectly smooth float coatNormal 1 clear coat normal map/scale vec3f flipflopColor white reflectivity of coated flakes at grazing angle, used together with coatColor produces a pearlescent paint (linear RGB) float flipflopFalloff 1 flip flop color falloff, 1 disables the flip flop effect ------------------------------------------------------------------------------------------- : Parameters of the CarPaint material. All parameters can be textured by passing a [texture] handle, prefixed with "`map_`" (e.g., "`map_baseColor`"). [texture transformations] are supported as well. ![Rendering of a pearlescent CarPaint material.][imgMaterialCarPaint] ### Metal The [path tracer] offers a physical metal, supporting changing roughness and realistic color shifts at edges. To create a Metal material pass the type string "`metal`" to `ospNewMaterial`. Its parameters are -------- ---------- ---------- -------------------------------------------- Type Name Default Description -------- ---------- ---------- -------------------------------------------- vec3f[] ior Aluminium [data] array of spectral samples of complex refractive index, each entry in the form (wavelength, eta, k), ordered by wavelength (which is in nm) vec3f eta RGB complex refractive index, real part vec3f k RGB complex refractive index, imaginary part float roughness 0.1 roughness in [0–1], 0 is perfect mirror -------- ---------- ---------- -------------------------------------------- : Parameters of the Metal material. The main appearance (mostly the color) of the Metal material is controlled by the physical parameters `eta` and `k`, the wavelength-dependent, complex index of refraction. These coefficients are quite counter-intuitive but can be found in [published measurements](https://refractiveindex.info/). For accuracy the index of refraction can be given as an array of spectral samples in `ior`, each sample a triplet of wavelength (in nm), eta, and k, ordered monotonically increasing by wavelength; OSPRay will then calculate the Fresnel in the spectral domain. Alternatively, `eta` and `k` can also be specified as approximated RGB coefficients; some examples are given in below table. Metal eta k -------------- ----------------------- ----------------- Ag, Silver (0.051, 0.043, 0.041) (5.3, 3.6, 2.3) Al, Aluminium (1.5, 0.98, 0.6) (7.6, 6.6, 5.4) Au, Gold (0.07, 0.37, 1.5) (3.7, 2.3, 1.7) Cr, Chromium (3.2, 3.1, 2.3) (3.3, 3.3, 3.1) Cu, Copper (0.1, 0.8, 1.1) (3.5, 2.5, 2.4) -------------- ----------------------- ----------------- : Index of refraction of selected metals as approximated RGB coefficients, based on data from https://refractiveindex.info/. The `roughness` parameter controls the variation of microfacets and thus how polished the metal will look. The roughness can be modified by a [texture] `map_roughness` ([texture transformations] are supported as well) to create notable edging effects. ![Rendering of golden Metal material with textured roughness.][imgMaterialMetal] ### Alloy The [path tracer] offers an alloy material, which behaves similar to [Metal], but allows for more intuitive and flexible control of the color. To create an Alloy material pass the type string "`alloy`" to `ospNewMaterial`. Its parameters are Type Name Default Description ------ ---------- ---------- -------------------------------------------------------- vec3f color white 0.9 reflectivity at normal incidence (0 degree, linear RGB) vec3f edgeColor white reflectivity at grazing angle (90 degree, linear RGB) float roughness 0.1 roughness, in [0–1], 0 is perfect mirror ------ ---------- ---------- -------------------------------------------------------- : Parameters of the Alloy material. The main appearance of the Alloy material is controlled by the parameter `color`, while `edgeColor` influences the tint of reflections when seen at grazing angles (for real metals this is always 100% white). If present, the color component of [geometries] is also used for reflectivity at normal incidence `color`. As in [Metal] the `roughness` parameter controls the variation of microfacets and thus how polished the alloy will look. All parameters can be textured by passing a [texture] handle, prefixed with "`map_`"; [texture transformations] are supported as well. ![Rendering of a fictional Alloy material with textured color.][imgMaterialAlloy] ### Glass The [path tracer] offers a realistic a glass material, supporting refraction and volumetric attenuation (i.e., the transparency color varies with the geometric thickness). To create a Glass material pass the type string "`glass`" to `ospNewMaterial`. Its parameters are Type Name Default Description ------ -------------------- -------- ----------------------------------------------- float eta 1.5 index of refraction vec3f attenuationColor white resulting color due to attenuation (linear RGB) float attenuationDistance 1 distance affecting attenuation ------ -------------------- -------- ----------------------------------------------- : Parameters of the Glass material. For convenience, the rather counter-intuitive physical attenuation coefficients will be calculated from the user inputs in such a way, that the `attenuationColor` will be the result when white light traveled through a glass of thickness `attenuationDistance`. ![Rendering of a Glass material with orange attenuation.][imgMaterialGlass] ### ThinGlass The [path tracer] offers a thin glass material useful for objects with just a single surface, most prominently windows. It models a thin, transparent slab, i.e., it behaves as if a second, virtual surface is parallel to the real geometric surface. The implementation accounts for multiple internal reflections between the interfaces (including attenuation), but neglects parallax effects due to its (virtual) thickness. To create a such a thin glass material pass the type string "`thinGlass`" to `ospNewMaterial`. Its parameters are Type Name Default Description --------- -------------------- -------- ------------------------------------------------ float eta 1.5 index of refraction vec3f attenuationColor white resulting color due to attenuation (linear RGB) float attenuationDistance 1 distance affecting attenuation float thickness 1 virtual thickness --------- -------------------- -------- ------------------------------------------------ : Parameters of the ThinGlass material. For convenience the attenuation is controlled the same way as with the [Glass] material. Additionally, the color due to attenuation can be modulated with a [texture] `map_attenuationColor` ([texture transformations] are supported as well). If present, the color component of [geometries] is also used for the attenuation color. The `thickness` parameter sets the (virtual) thickness and allows for easy exchange of parameters with the (real) [Glass] material; internally just the ratio between `attenuationDistance` and `thickness` is used to calculate the resulting attenuation and thus the material appearance. ![Rendering of a ThinGlass material with red attenuation.][imgMaterialThinGlass] ![Example image of a colored window made with textured attenuation of the ThinGlass material.][imgColoredWindow] ### MetallicPaint The [path tracer] offers a metallic paint material, consisting of a base coat with optional flakes and a clear coat. To create a MetallicPaint material pass the type string "`metallicPaint`" to `ospNewMaterial`. Its parameters are listed in the table below. Type Name Default Description --------- ------------ ---------- -------------------------------------- vec3f baseColor white 0.8 color of base coat (linear RGB) float flakeAmount 0.3 amount of flakes, in [0–1] vec3f flakeColor Aluminium color of metallic flakes (linear RGB) float flakeSpread 0.5 spread of flakes, in [0–1] float eta 1.5 index of refraction of clear coat --------- ------------ ---------- -------------------------------------- : Parameters of the MetallicPaint material. The color of the base coat `baseColor` can be textured by a [texture] `map_baseColor`, which also supports [texture transformations]. If present, the color component of [geometries] is also used for the color of the base coat. Parameter `flakeAmount` controls the proportion of flakes in the base coat, so when setting it to 1 the `baseColor` will not be visible. The shininess of the metallic component is governed by `flakeSpread`, which controls the variation of the orientation of the flakes, similar to the `roughness` parameter of [Metal]. Note that the effect of the metallic flakes is currently only computed on average, thus individual flakes are not visible. ![Rendering of a MetallicPaint material.][imgMaterialMetallicPaint] ### Luminous The [path tracer] supports the Luminous material which emits light uniformly in all directions and which can thus be used to turn any geometric object into a light source. It is created by passing the type string "`luminous`" to `ospNewMaterial`. The amount of constant radiance that is emitted is determined by combining the general parameters of lights: [`color` and `intensity`](#lights) (which essentially means that parameter `intensityQuantity` is not needed because it is always `OSP_INTENSITY_QUANTITY_RADIANCE`). Type Name Default Description ------ ------------ -------- --------------------------------------- vec3f color white color of the emitted light (linear RGB) float intensity 1 intensity of the light (a factor) float transparency 0 material transparency ------ ------------ -------- --------------------------------------- : Parameters accepted by the Luminous material. The emission can be textured by passing a `map_color` [texture] handle, [texture transformations] are supported as well. ![Rendering of a yellow Luminous material.][imgMaterialLuminous] Texture ------- OSPRay currently implements two texture types (`texture2d` and `volume`) and is open for extension to other types by applications. More types may be added in future releases. To create a new texture use OSPTexture ospNewTexture(const char *type); ### Texture2D The `texture2d` texture type implements an image-based texture, where its parameters are as follows Type Name Description -------------- --------- ---------------------------------- uint format `OSPTextureFormat` for the texture uint filter default `OSP_TEXTURE_FILTER_LINEAR`, alternatively `OSP_TEXTURE_FILTER_NEAREST` OSPData data the actual texel 2D [data] uint / vec2ui wrapMode `OSPTextureWrapMode` for the texture coordinates s and t; supported wrap modes are: `OSP_TEXTURE_WRAP_REPEAT` (default) `OSP_TEXTURE_WRAP_MIRRORED_REPEAT` `OSP_TEXTURE_WRAP_CLAMP_TO_EDGE` -------------- --------- ---------------------------------- : 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_RGBA16F 16\ 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_RGB16F 16\ 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_RA32F 32\ bit float two component red, alpha OSP_TEXTURE_R32F 32\ bit float single component red OSP_TEXTURE_RA16F 16\ bit float two component red, alpha OSP_TEXTURE_R16F 16\ 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`. The size of the texture is inferred from the size of the 2D array `data`, which also needs have a compatible type to `format`. The texel data in `data` starts with the texels in the lower left corner of the texture image, like in OpenGL. Per default a texture fetch is filtered by performing bi-linear interpolation of the nearest 2×2 texels; if instead fetching only the nearest texel is desired (i.e., no filtering) then pass the `OSP_TEXTURE_FILTER_NEAREST` flag. Texturing with `texture2d` image textures requires [geometries] with texture coordinates, e.g., a [mesh] with `vertex.texcoord` provided. ### Volume Texture The `volume` texture type implements texture lookups based on 3D object coordinates of the surface hit point on the associated geometry. If the given hit point is within the attached volume, the volume is sampled and classified with the transfer function attached to the volume. This implements the ability to visualize volume values (as colored by a transfer function) on arbitrary surfaces inside the volume (as opposed to an isosurface showing a particular value in the volume). Its parameters are as follows Type Name Description ------------------- ---------------- ----------------------------------------- OSPVolume volume [Volume] used to generate color lookups OSPTransferFunction transferFunction [transfer function] applied to `volume` ------------------- ---------------- ----------------------------------------- : Parameters of `volume` texture type. TextureVolume can be used for implementing slicing of volumes with any geometry type. It enables coloring of the slicing geometry with a different transfer function than that of the sliced volume. ### Texture Transformations 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.*`"). 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 translation move texture in positive direction (right/up) --------- ------------ ------------------------------------------------- : Parameters to define 2D texture coordinate transformations. Above parameters are combined into a single `affine2d` transformation matrix and the transformations are applied in the given order. Rotation, scale and translation are interpreted "texture centric", i.e., their effect seen by an user are relative to the texture (although the transformations are applied to the texture coordinates). Type Name Description -------- ------------ -------------------------------------------------------- affine3f transform linear transformation (rotation, scale) plus translation -------- ------------ -------------------------------------------------------- : Parameter to define 3D volume texture transformations. Similarly, volume texture placement can also be modified by an `affine3f` transformation matrix. Cameras ------- To create a new camera of given type `type` use OSPCamera ospNewCamera(const char *type); All cameras accept these parameters: ----------- ----------------------- --------------------- ------------------------------------------ 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] uint 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`, `direction` and `up`. Additionally, an extra transformation `transform` can be specified, which will only be applied to 3D vectors (i.e., `position`, `direction` and `up`), but does *not* affect any sizes (e.g., `nearClip`, `apertureRadius`, or `height`). The same holds for the array of transformations `motion.transform` to achieve camera motion blur (in combination with `time` and `shutter`). OSPRay uses a right-handed coordinate system. The region of the camera sensor that is rendered to the image can be specified in normalized screen-space coordinates with `imageStart` (lower left corner) and `imageEnd` (upper right corner). This can be used, for example, to crop the image, to achieve asymmetrical view frusta, or to horizontally flip the image to view scenes which are specified in a left-handed coordinate system. Note that values outside the default range of [0–1] are valid, which is useful to easily realize overscan or film gate, or to emulate a shifted sensor. ### Perspective Camera The perspective camera implements a simple thin lens camera for perspective rendering, supporting optionally depth of field and stereo rendering (with the [path tracer]). It is created by passing the type 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 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 uint 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. Note that when computing the `aspect` ratio a potentially set image region (using `imageStart` & `imageEnd`) needs to be regarded as well. In architectural photography it is often desired for aesthetic reasons to display the vertical edges of buildings or walls vertically in the image as well, regardless of how the camera is tilted. Enabling the `architectural` mode achieves this by internally leveling the camera parallel to the ground (based on the `up` direction) and then shifting the lens such that the objects in direction `dir` are centered in the image. If finer control of the lens shift is needed use `imageStart` & `imageEnd`. Because the camera is now effectively leveled its image plane and thus the plane of focus is oriented parallel to the front of buildings, the whole façade appears sharp, as can be seen in the example images below. The resolution of the [framebuffer] is not altered by `imageStart`/`imageEnd`. ![Example image created with the perspective camera, featuring depth of field.][imgCameraPerspective] ![Enabling the `architectural` flag corrects the perspective projection distortion, resulting in parallel vertical edges.][imgCameraArchitectural] ![Example 3D stereo image using `stereoMode = OSP_STEREO_SIDE_BY_SIDE`.][imgCameraStereo] ### Orthographic Camera The orthographic camera implements a simple camera with orthographic projection, without support for depth. It is created by passing the type string "`orthographic`" to `ospNewCamera`. In addition to the [general parameters](#cameras) understood by all cameras the orthographic camera supports the following special parameters: Type Name Description ------ ------- ------------------------------------------------------------ float height size of the camera's image plane in y, in world coordinates float aspect ratio of width by height of the frame ------ ------- ------------------------------------------------------------ : Additional parameters accepted by the orthographic camera. For convenience the size of the camera sensor, and thus the extent of the scene that is captured in the image, can be controlled with the `height` parameter. The same effect can be achieved with `imageStart` and `imageEnd`, and both methods can be combined. In any case, the `aspect` ratio needs to be set accordingly to get an undistorted image. ![Example image created with the orthographic camera.][imgCameraOrthographic] ### Panoramic Camera The panoramic camera implements a simple camera with support for stereo rendering. It captures the complete surrounding with a latitude / longitude mapping and thus the rendered images should best have a ratio of 2:1. A panoramic camera is created by passing the type string "`panoramic`" to `ospNewCamera`. It is placed and oriented in the scene by using the [general parameters](#cameras) understood by all cameras. ----- ---------------------- ----------------------------------------- Type Name Description ----- ---------------------- ----------------------------------------- uint 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 ----- ---------------------- ----------------------------------------- : Additional parameters accepted by the panoramic camera. ![Latitude / longitude map created with the panoramic camera.][imgCameraPanoramic] Scene Hierarchy --------------- ### Groups 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, 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 parameter will be used as clipping geometries. Any supported geometry can be used for clipping^[including spheres, boxes, infinite planes, closed meshes, closed subdivisions and curves], the only requirement is that it has to distinctly partition space into clipping and non-clipping one. The use of clipping geometry that is not closed or infinite could result in rendering artifacts. User can decide which part of space is clipped by changing shading normals orientation with the `invertNormals` flag of the [GeometricModel]. All geometries and volumes assigned to `geometry` or `volume` will be clipped. All clipping geometries from all groups and [Instances] will be combined together – a union of these areas will be applied to all other objects in the [world]. -------------------- ---------------- ---------- -------------------------------------- Type Name Default Description -------------------- ---------------- ---------- -------------------------------------- OSPGeometricModel[] geometry NULL [data] array of [GeometricModels] OSPVolumetricModel[] volume NULL [data] array of [VolumetricModels] OSPGeometricModel[] clippingGeometry NULL [data] array of [GeometricModels] used for clipping OSPLight[] light NULL [data] array of [lights] bool dynamicScene false tell Embree to use faster BVH build (slower ray traversal), otherwise optimized for 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. ### Instances Instances in OSPRay represent a single group's placement into the world via a transform. To create and instance call OSPInstance ospNewInstance(OSPGroup); The passed group can be `NULL` as long as the group to be instanced is passed as a parameter. If both a group is specified on object creation and as a parameter, the parameter value is used. If the parameter value is later removed, the group object passed on object creation is again used. ------------ ----------------- ---------- -------------------------------------------------------- Type Name Default Description ------------ ----------------- ---------- -------------------------------------------------------- OSPGroup group optional [group] object to be instanced 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) uint32 id -1u optional user ID, for [framebuffer] channel `OSP_FB_ID_INSTANCE` ------------ ----------------- ---------- -------------------------------------------------------- : Parameters understood by instances. ### World Worlds are a container of scene data represented by [instances]. To create an (empty) world call OSPWorld ospNewWorld(); Objects are placed in the world through an array of instances. Similar to [groups], the array of instances is optional: there is no need to create empty arrays if there are no instances (though there will be nothing to render). Applications can query the world (axis-aligned) bounding box after the world has been committed. To get this information, call OSPBounds ospGetBounds(OSPObject); The result is returned in the provided `OSPBounds`^[`OSPBounds` has essentially the same layout as the `OSP_BOX3F` [`OSPDataType`][data].] struct: typedef struct { float lower[3]; float upper[3]; } OSPBounds; This call can also take `OSPGroup` and `OSPInstance` as well: all other 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] array with handles of the [instances] OSPLight[] light NULL [data] array with handles of the [lights] bool dynamicScene false tell Embree to use faster BVH build (slower ray traversal), otherwise optimized for 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. Renderers --------- A renderer is the central object for rendering in OSPRay. Different renderers implement different features and support different materials. To create a new renderer of given type `type` use OSPRenderer ospNewRenderer(const char *type); General parameters of all renderers are -------------- ------------------ ----------------------- ----------------------------------------- Type Name Default Description -------------- ------------------ ----------------------- ----------------------------------------- int pixelSamples 1 samples per pixel, best results when a power of 2 int maxPathLength 20 maximum ray recursion depth float minContribution 0.001 sample contributions below this value will be neglected to speedup rendering float varianceThreshold 0 threshold for adaptive accumulation float / backgroundColor black, background color and alpha (linear vec3f / vec4f transparent A/RGB/RGBA), if no `map_backplate` is set OSPTexture map_backplate optional [texture] image used as background (use texture type `texture2d`) OSPTexture map_maxDepth optional screen-sized float [texture] with maximum far distance per pixel (use texture type `texture2d`) OSPMaterial[] material optional [data] array of [materials] which can be indexed by a [GeometricModel]'s `material` parameter uint pixelFilter `OSP_PIXELFILTER_GAUSS` `OSPPixelFilterType` to select the pixel filter used by the renderer for antialiasing. Possible pixel filters are listed below. float mipMapBias 0 bias for texture MIP-mapping, balancing between sharpness/aliasing and blurriness due to prefiltering -------------- ------------------ ----------------------- ----------------------------------------- : Parameters understood by all renderers. OSPRay's renderers support a feature called adaptive accumulation, which accelerates progressive [rendering] by stopping the rendering and refinement of image regions that have an estimated variance below the `varianceThreshold`. This feature requires a [framebuffer] with an `OSP_FB_VARIANCE` channel. Per default the background of the rendered image will be transparent black, i.e., the alpha channel holds the opacity of the rendered objects. This eases transparency-aware blending of the image with an arbitrary background image by the application (via $ospray.rgb + appBackground.rgbâ‹…(1-ospray.alpha)$). The parameter `backgroundColor` or `map_backplate` can be used to already blend with a constant background color or backplate texture, respectively, (and alpha) during rendering. OSPRay renderers support depth composition with images of other renderers, for example to incorporate help geometries of a 3D UI that were rendered with OpenGL. The screen-sized [texture] `map_maxDepth` must have format `OSP_TEXTURE_R32F` and flag `OSP_TEXTURE_FILTER_NEAREST`. The fetched values are used to limit the distance of primary rays, thus objects of other renderers can hide objects rendered by OSPRay. OSPRay supports antialiasing in image space by using pixel filters, which are aligned around the center of a pixel. The size $w×w$ of 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 $\sigma = 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. OSPRay also antialiases textures with prefiltering and MIP-mapping, which can be adjusted with parameter `mipMapBias`. For final frame rendering with a high number of `pixelSamples` or accumulated frames `mipMapBias` can be lowered (e.g., set to -0.5 or -2) to result in sharper textures which are essentially anisotropically filtered. Conversely, for preview rendering with just a single sample per pixel a higher `mipMapBias` of 1 or 2 can reduce texture aliasing and increase rendering speed. ### SciVis Renderer The SciVis renderer is a fast ray tracer for scientific visualization which supports volume rendering and ambient occlusion (AO). It is created by passing the type string "`scivis`" to `ospNewRenderer`. In addition to the [general parameters](#renderer) understood by all renderers, the SciVis renderer supports the following parameters: ------ ------------------- --------- ---------------------------------- Type Name Default Description ------ ------------------- --------- ---------------------------------- bool shadows false whether to compute (hard) shadows int aoSamples 0 number of rays per sample to compute ambient occlusion float aoDistance 10^20^ maximum distance to consider for ambient occlusion float volumeSamplingRate 1 sampling rate for volumes bool visibleLights false whether light sources are potentially visible (as in the [path tracer], regarding each light's `visible`) ------ ------------------- --------- ---------------------------------- : Special parameters understood by the SciVis renderer. Note that the intensity (and color) of AO is deduced from an [ambient light] in the `lights` array.^[If there are multiple ambient lights then their contribution is added.] If `aoSamples` is zero (the default) then ambient lights cause ambient illumination (without occlusion). ### Ambient Occlusion Renderer This renderer supports only a subset of the features of the [SciVis renderer] to gain performance. As the name suggest its main shading method is ambient occlusion (AO), [lights] are *not* considered at all. Volume rendering is supported. The Ambient Occlusion renderer is created by passing the type string "`ao`" to `ospNewRenderer`. In addition to the [general parameters](#renderer) understood by all renderers the following parameters are supported as well: ------------- ---------------------- ------------ ---------------------------- Type Name Default Description ------------- ---------------------- ------------ ---------------------------- int aoSamples 1 number of rays per sample to compute ambient occlusion float aoDistance 10^20^ maximum distance to consider for ambient occlusion float aoIntensity 1 ambient occlusion strength float volumeSamplingRate 1 sampling rate for volumes ------------- ---------------------- ------------ ---------------------------- : Special parameters understood by the Ambient Occlusion renderer. ### Path Tracer The path tracer supports soft shadows, indirect illumination and realistic materials. This renderer is created by passing the type string "`pathtracer`" to `ospNewRenderer`. In addition to the [general parameters](#renderer) understood by all renderers the path tracer supports the following special parameters: ------ -------------------------- -------- ---------------------------------- Type Name Default Description ------ -------------------------- -------- ---------------------------------- int lightSamples all number of random light samples per path vertex, best results when a power of 2; per default all light sources are sampled bool limitIndirectLightSamples true after the first non-specular (i.e., diffuse and glossy) path vertex take (at most) a single light sample (instead of `lightSamples` many) int roulettePathLength 5 ray recursion depth at which to start Russian roulette termination int maxScatteringEvents 20 maximum number of non-specular (i.e., diffuse and glossy) bounces float maxContribution ∞ samples are clamped to this value before they are accumulated into the framebuffer bool backgroundRefraction false allow for alpha blending even if background is seen through refractive objects like glass ------ -------------------------- -------- ---------------------------------- : Special parameters understood by the path tracer. The path tracer requires that [materials] are assigned to [geometries], otherwise surfaces are treated as completely black. The path tracer supports [volumes](#volumes) with multiple scattering. The scattering albedo can be specified using the [transfer function]. Extinction is assumed to be spectrally constant. Framebuffer ----------- The framebuffer holds the rendered 2D image (and optionally auxiliary information associated with pixels). To create a new framebuffer object of given size `size` (in pixels), color format, and channels use OSPFrameBuffer ospNewFrameBuffer(int size_x, int size_y, OSPFrameBufferFormat format = OSP_FB_SRGBA, uint32_t frameBufferChannels = OSP_FB_COLOR); 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 --------------- ------------------------------------------------------------- : Supported color formats of the framebuffer that can be passed to `ospNewFrameBuffer`, i.e., valid constants of type `OSPFrameBufferFormat`. 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] 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 non-specular hit, as vec3f OSP_FB_ID_PRIMITIVE primitive index of the first hit, as uint32 OSP_FB_ID_OBJECT geometric/volumetric model `id`, if specified, or index in [group] of first hit, as uint32 OSP_FB_ID_INSTANCE user defined [instance] `id`, if specified, or instance index of first hit, as uint32 ------------------- ---------------------------------------------------------- : Framebuffer channels constants (of type `OSPFrameBufferChannel`), naming optional information the framebuffer can store. These values can be combined by bitwise OR when passed to `ospNewFrameBuffer`. If a certain channel value is _not_ specified, the given buffer channel will not be present. Note that OSPRay makes a clear distinction between the _external_ format of the framebuffer and the internal one: The external format is the format the user specifies in the `format` parameter; it specifies what color format OSPRay will eventually _return_ the framebuffer to the application (when calling `ospMapFrameBuffer`): no matter what OSPRay uses internally, it will simply return a 2D array of pixels of that format, with possibly all kinds of reformatting, compression/decompression, etc., going on in-between the generation of the _internal_ framebuffer and the mapping of the externally visible one. In particular, `OSP_FB_NONE` is a perfectly valid pixel format for a framebuffer that an application will never map. For example, an application driving a display wall may well generate an intermediate framebuffer and eventually transfer its pixel to the individual displays using an `OSPImageOperation` [image operation]. The application can map the given channel of a framebuffer – and thus access the stored pixel information – via const void *ospMapFrameBuffer(OSPFrameBuffer, OSPFrameBufferChannel = OSP_FB_COLOR); Note that `OSP_FB_ACCUM` or `OSP_FB_VARIANCE` cannot be mapped. The origin of the screen coordinate system in OSPRay is the lower left corner (as in OpenGL), thus the first pixel addressed by the returned pointer is the lower left pixel of the image. A previously mapped channel of a framebuffer can be unmapped by passing the received pointer `mapped` to void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer); The individual channels of a framebuffer can be cleared with void ospResetAccumulation(OSPFrameBuffer); This function will clear *all* accumulating buffers (`OSP_FB_VARIANCE`, `OSP_FB_NORMAL`, and `OSP_FB_ALBEDO`, if present) and resets the accumulation counter `accumID`. It is unspecified if the existing color and depth buffers are physically cleared when `ospResetAccumulation` is called. If `OSP_FB_VARIANCE` is specified, an estimate of the variance of the last accumulated frame can be queried with float ospGetVariance(OSPFrameBuffer); Note this value is only updated after synchronizing with `OSP_FRAME_FINISHED`, as further described in [asynchronous rendering]. The estimated variance can be used by the application as a quality indicator and thus to decide whether to stop or to continue progressive rendering. The framebuffer takes a list of pixel operations to be applied to the image in sequence as an `OSPData`. The pixel operations will be run in the order they are in the array. -------------------- --------------- ----------------------------------------- Type Name Description -------------------- --------------- ----------------------------------------- OSPImageOperation[] imageOperation ordered sequence of image operations int targetFrames anticipated number of frames that will be accumulated for progressive refinement, used renderers to generate a blue noise sampling pattern; should be a power of 2, is always 1 without `OSP_FB_ACCUM`; default 0 (disabled) -------------------- --------------- ----------------------------------------- : Parameters accepted by the framebuffer. If the total number of frames to be accumulated is known, then `targetFrames` should be set, because then renderers can generate more pleasing blue noise patterns. Accumulation stops when `targetFrames` is reached. ### Image Operation Image operations are functions that are applied to every pixel of a frame. Examples include post-processing, filtering, blending, tone mapping, or sending tiles to a display wall. To create a new pixel operation of given type `type` use OSPImageOperation ospNewImageOperation(const char *type); #### Tone Mapper The tone mapper is a pixel operation which implements a generic filmic tone mapping operator. Using the default parameters it approximates the Academy 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 Filmic Description ------ ---------- --------- --------- ----------------------------------------- float exposure 1.0 1.0 amount of light per unit area float contrast 1.6773 1.1759 contrast (toe of the curve); typically is in [1–2] float shoulder 0.9714 0.9746 highlight compression (shoulder of the curve); typically is in [0.9–1] float midIn 0.18 0.18 mid-level anchor input; default is 18% gray float midOut 0.18 0.18 mid-level anchor output; default is 18% gray float hdrMax 11.0785 6.3704 maximum HDR input that is not clipped bool acesColor true false apply the ACES color transforms ------ ---------- --------- --------- ----------------------------------------- : Parameters accepted by the tone mapper. The column "Filmic" lists alternative values for the popular "Uncharted 2" tone mapping curve (note that that curve includes an exposure bias to match 18% middle gray). #### Denoiser OSPRay comes with a module that adds support for Intel® Open Image Denoise (OIDN). This is provided as an optional module as it creates an additional project dependency at compile time. The module implements a "`denoiser`" frame operation, which denoises the entire frame before the frame is completed. OIDN will automatically select the fastest device, using a GPU when available. The device selection be overridden by the environment variable `OIDN_DEFAULT_DEVICE`, possible values are `cpu`, `sycl`, `cuda`, `hip`, or a physical device ID ----- ------------- ---------------------------------------------------------- Type Name Description ----- ------------- ---------------------------------------------------------- uint quality `OSPDenoiserQuality` for denoiser quality, default is `OSP_DENOISER_QUALITY_MEDIUM`: balanced quality/performance for interactive/real-time rendering; also allowed are: `OSP_DENOISER_QUALITY_LOW`: high performance, for interactive/real-time preview rendering `OSP_DENOISER_QUALITY_HIGH`: high quality, for final frame rendering bool denoiseAlpha whether to denoise the alpha channel as well, default false ----- ------------- ---------------------------------------------------------- : Parameters accepted by the denoiser. Rendering --------- ### Asynchronous Rendering Rendering is by default asynchronous (non-blocking), and is done by combining a framebuffer, renderer, camera, and world. What to render and how to render it depends on the renderer's parameters. If the framebuffer supports accumulation (i.e., it was created with `OSP_FB_ACCUM`) then successive calls to `ospRenderFrame` will progressively refine the rendered image (until `targetFrames` is reached). To start an render task, use OSPFuture ospRenderFrame(OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); This returns an `OSPFuture` handle, which can be used to synchronize with the application, cancel, or query for progress of the running task. When `ospRenderFrame` is called, there is no guarantee when the associated task will begin execution. Progress of a running frame can be queried with the following API function float ospGetProgress(OSPFuture); This returns the approximated progress of the task in [0-1]. Applications can cancel a currently running asynchronous operation via void ospCancel(OSPFuture); Applications can wait on the result of an asynchronous operation, or choose to only synchronize with a specific event. To synchronize with an `OSPFuture` use 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 -------------------- -------------------------------------------------------- : Supported events that can be passed to `ospWait`. Currently only rendering can be invoked asynchronously. However, future releases of OSPRay may add more asynchronous versions of API calls (and thus return `OSPFuture`). Applications can query whether particular events are complete with int ospIsReady(OSPFuture, OSPSyncEvent = OSP_TASK_FINISHED); As the given running task runs (as tracked by the `OSPFuture`), applications can query a boolean [0, 1] result if the passed event has been completed. Applications can query how long an async task ran with float ospGetTaskDuration(OSPFuture); This returns the wall clock execution time of the task in seconds. If the task is still running, this will block until the task is completed. This is useful for applications to query exactly how long an asynchronous task executed without the overhead of measuring both task execution + synchronization by the calling application. ### Synchronous Rendering For convenience in certain use cases, `ospray_util.h` provides a synchronous version of `ospRenderFrame`: float ospRenderFrameBlocking(OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); This version is the equivalent of: ospRenderFrame ospWait(f, OSP_TASK_FINISHED) return ospGetVariance(fb) This version is closest to `ospRenderFrame` from OSPRay v1.x. ### Rendering and ospCommit The use of either `ospRenderFrame` or `ospRenderFrameBlocking` requires that all objects in the scene being rendered have been committed before rendering occurs. If a call to `ospCommit` happens while a frame is rendered, the result is undefined behavior and should be avoided. ### Picking To get the world-space position of the geometry (if any) seen at [0–1] normalized screen-space pixel coordinates `screenPos_x` and `screenPos_y` use void ospPick(OSPPickResult *, OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, float screenPos_x, float screenPos_y); The result is returned in the provided `OSPPickResult` struct: typedef struct { int hasHit; float worldPosition[3]; OSPInstance instance; OSPGeometricModel model; uint32_t primID; } OSPPickResult; Note that `ospPick` considers exactly the same camera of the given renderer that is used to render an image, thus matching results can be expected. If the camera supports depth of field then the center of the lens and thus the center of the circle of confusion is used for picking. Note that the caller needs to `ospRelease` the `instance` and `model` handles of `OSPPickResult` once the information is not needed anymore. Modules and Devices =================== CPU ---- The CPU module is implicitly loaded and the `cpu` device is automatically used if no other options are specified. GPU (Beta) --------- To use the GPU for rendering load the `gpu` module and select the `gpu` device: ```sh ./ospExamples --osp:load-modules=gpu --osp:device=gpu ``` or via explicit device creation by the application: ospLoadModule("gpu"); OSPDevice dev = ospNewDevice("gpu"); ospDeviceCommit(dev); ospSetCurrentDevice(dev); Type Name Description -------- ------------- -------------------------------- void\ * syclContext SYCL context void\ * syclDevice SYCL device -------- ------------- -------------------------------- : Parameters specific to the `gpu` device. Applications can set their SYCL context and device to share device memory with OSPRay or to control which device should be used (e.g., in case multiple GPUs are present). If neither parameter is set, the `gpu` device will automatically create a context internally and select a GPU (that selection can be influenced via environment variable `ONEAPI_DEVICE_SELECTOR`, see [Intel oneAPI DPC++ Compiler documentation](https://intel.github.io/llvm-docs/EnvironmentVariables.html#oneapi-device-selector)). Compile times for just in time compilation (JIT compilation) can be large. To resolve this issue we recommend enabling persistent JIT compilation caching inside your application before the SYCL device is created, by setting environment variables `SYCL_CACHE_PERSISTENT=1` (and optionally `SYCL_CACHE_DIR=` to some proper directory where the JIT cache should get stored). To reduce GPU memory allocation overhead when rendering scenes with many objects (geometries, instances, etc.), memory pooling should be enabled by setting the environment variable `SYCL_PI_LEVEL_ZERO_USM_ALLOCATOR="1;0;shared:1M,0,2M"`. See [Intel oneAPI DPC++ Compiler documentation](https://intel.github.io/llvm-docs/EnvironmentVariables.html#debugging-variables-for-level-zero-plugin) for more details. ### Known Issues {-} The following features are not implemented yet or are not working correctly on the GPU device: - Multiple volumes in the scene - Clipping - Motion blur - Subdivision surfaces - Progress reporting via `ospGetProgress` or canceling the frame via `ospCancel` - Picking via `ospPick` - Adaptive accumulation via `OSP_FB_VARIANCE` and `varianceThreshold` - Framebuffer channels `OSP_FB_ID_*` (id buffers) - Experimental support for shared device-only data, works only for `structuredRegular` volume There will be some delay on start-up as the kernel code is JIT compiled for the device, and similar pauses when changing the scene configuration, because the kernel specialized and re-compiled. For some combination of compiler, GPU driver and scene the rendered images might show artifacts (e.g., vertical lines or small blocks). Distributed Rendering with MPI ------------------------------ The purpose of OSPRay's MPI modules is to provide distributed rendering capabilities for OSPRay. The modules enables image- and data-parallel rendering across HPC clusters using MPI, allowing applications to transparently distribute rendering work, or to render data sets which are too large to fit in memory on a single machine. OSPRay provides multiple MPI modules that expose different distributed rendering capabilities. The `mpi_offload` module provides image-parallel rendering through the `mpiOffload` device; it enables OSPRay applications written for local rendering to be replicated across multiple nodes to distribute the rendering work without code changes. And the `mpi_distributed_cpu` and `mpi_distributed_gpu` modules provides data-parallel rendering through the `mpiDistributed` device, which allows MPI distributed applications to use OSPRay for distributed rendering. Each rank using the `mpiDistributed` device can render an independent piece of a global data set, or perform hybrid rendering where ranks partially or completely share data. The `mpiDistributed` device's image-parallel rendering support can be used to accelerate data loading for image-parallel applications, where all ranks load the same data from a shared disk and then perform image-parallel rendering on the replicated data, as if the `mpiOffload` device where being used. ### MPI Offload Rendering The `mpiOffload` device can be used to distribute image rendering tasks across a cluster without requiring modifications to the application itself. Existing applications using OSPRay for local rendering simply be passed command line arguments to load the module and indicate that the `mpiOffload` device should be used for image-parallel rendering. To load the module, pass `--osp:load-modules=mpi_offload`, to select the MPIOffloadDevice, pass `--osp:device=mpiOffload`. For example, the `ospExamples` application can be run as: ```sh mpirun -n ./ospExamples --osp:load-modules=mpi_offload --osp:device=mpiOffload ``` and will automatically distribute the image rendering tasks among the corresponding `N` nodes. Note that in this configuration rank 0 will act as a master/application rank, and will run the user application code but not perform rendering locally. Thus, a minimum of 2 ranks are required, one master to run the application and one worker to perform the rendering. Running with 3 ranks for example would now distribute half the image rendering work to rank 1 and half to rank 2. If more control is required over the placement of ranks to nodes, or you want to run a worker rank on the master node as well you can run the application and the `ospray_mpi_worker` program through MPI's MPMD mode. The `ospray_mpi_worker` will load the MPI module and select the offload device by default. ```sh mpirun -n 1 ./ospExamples --osp:load-modules=mpi_offload --osp:device=mpiOffload \ : -n ./ospray_mpi_worker ``` If initializing the `mpiOffload` device manually, or passing parameters through the command line, the following parameters can be set: -------- ------------------------ --------- --------------------------------- Type Name Default Description -------- ------------------------ --------- --------------------------------- string mpiMode mpi The mode to communicate with the worker ranks. `mpi` will assume you are launching the application and workers in the same mpi command (or split launch command). `mpi` is the only supported mode uint maxCommandBufferEntries 8192 Set the max number of commands to buffer before submitting the command buffer to the workers uint commandBufferSize 512\ MiB Set the max command buffer size to allow. Units are in MiB. Max size is 1.8\ GiB uint maxInlineDataSize 32\ MiB Set the max size of an OSPData which can be inline'd into the command buffer instead of being sent separately. Max size is half the commandBufferSize. Units are in MiB -------- ------------------------ --------- --------------------------------- : Parameters specific to the `mpiOffload` device. The `maxCommandBufferEntries`, `commandBufferSize`, and `maxInlineDataSize` can also be set via the environment variables: `OSPRAY_MPI_MAX_COMMAND_BUFFER_ENTRIES`, `OSPRAY_MPI_COMMAND_BUFFER_SIZE`, and `OSPRAY_MPI_MAX_INLINE_DATA_SIZE`, respectively. The `mpiOffload` device uses a dynamic load balancer by default. If you wish to use a static load balancer you can do so by setting the `OSPRAY_STATIC_BALANCER` environment variable to 1. For the worker ranks to create GPU devices instead of the default CPU devices set the environment variable `OSPRAY_MPI_DISTRIBUTED_GPU`, e.g., ```sh export OSPRAY_MPI_DISTRIBUTED_GPU=1 ``` or ```sh mpiexec -genv OSPRAY_MPI_DISTRIBUTED_GPU 1 \ -n 1 ./ospExamples --osp:load-modules=mpi_offload --osp:device=mpiOffload \ : -n 2 ./ospray_mpi_worker ``` The `mpiOffload` device does not support multiple init/shutdown cycles. Thus, to run `ospBenchmark` for this device make sure to exclude the init/shutdown test by passing `--benchmark_filter=-ospInit_ospShutdown` through the command line. ### MPI Distributed Rendering While MPI Offload rendering is used to transparently distribute rendering work without requiring modification to the application, MPI Distributed rendering is targeted at use of OSPRay within MPI-parallel applications. The MPI distributed device can be selected by loading the `mpi_distributed_cpu` module for CPU rendering or `mpi_distributed_gpu` for GPU rendering, and manually creating and using an instance of the `mpiDistributed` device, for example: ospLoadModule("mpi_distributed_cpu"); OSPDevice mpiDevice = ospNewDevice("mpiDistributed"); ospDeviceCommit(mpiDevice); ospSetCurrentDevice(mpiDevice); Your application can either initialize MPI before-hand, ensuring that `MPI_THREAD_SERIALIZED` or higher is supported, or allow the device to initialize MPI on commit. Thread multiple support is required if your application will make MPI calls while rendering asynchronously with OSPRay. When using the distributed device each rank can specify independent local data using the OSPRay API, as if rendering locally. However, when calling `ospRenderFrameAsync` the ranks will work collectively to render the data. The distributed device supports both image-parallel, where the data is replicated, and data-parallel, where the data is distributed, rendering modes. The `mpiDistributed` device will by default use each rank in `MPI_COMM_WORLD` as a render worker; 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 -------- ------------------ ---------------- -------------------------------- : Parameters specific to the `mpiDistributed` device. -------- ------- --------- ----------------------------------------------- Type Name Default Description -------- ------- --------- ----------------------------------------------- box3f[] region NULL A list of bounding boxes which bound the owned local data to be rendered by the rank -------- ------- --------- ----------------------------------------------- : Parameters specific to the distributed `OSPWorld`. ------ ------------------- --------- ------------------------------------------------ Type Name Default Description ------ ------------------- --------- ------------------------------------------------ int aoSamples 0 The number of AO samples to take per-pixel float aoDistance 10^20^ The AO ray length to use. Note that if the AO ray would have crossed a rank boundary and ghost geometry is not available, there will be visible artifacts in the shading float volumeSamplingRate 1 sampling rate for volumes ------ ------------------- --------- ------------------------------------------------ : Parameters specific to the `mpiRaycast` renderer. #### Image Parallel Rendering in the MPI Distributed Device If all ranks specify exactly the same data, the distributed device can be used for image-parallel rendering. This works identical to the offload device, except that the MPI-aware application is able to load data in parallel on each rank rather than loading on the master and 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 [ospMPIDistribTutorialReplicated](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialReplicated.cpp) for an example. #### Data Parallel Rendering in the MPI Distributed Device The MPI Distributed device also supports data-parallel rendering with sort-last compositing. Each rank can specify a different piece of data, as long as the bounding boxes of each rank's data are non-overlapping. The rest of the scene setup is similar to local rendering; however, for distributed rendering only the `mpiRaycast` renderer is supported. This renderer implements a subset of the `scivis` rendering features which are suitable for implementation in a distributed environment. By default the aggregate bounding box of the instances in the local world will be used as the bounds of that rank's data. However, when using ghost zones for volume interpolation, geometry or ambient occlusion, each rank's data can overlap. To clip these non-owned overlap 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 [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 rendering, where multiple ranks can share a single piece of data. For 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 [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 {-} Calling `ospPick` in the distributed device will find and return the closest global object at the screen position on the rank that owns that object. The other ranks will report no hit. Picking in the distributed device takes into account data clipping applied through the `regions` parameter to avoid picking ghost data. ### Interaction with User Modules The MPI Offload rendering mode trivially supports user modules, with the caveat that attempting to share data directly with the application (e.g., passing a `void *` or other tricks to the module) will not work in a distributed environment. Instead, use the `ospNewSharedData` API to share data from the application with OSPRay, which will in turn be copied over the network to the workers. The MPI Distributed device also supports user modules, as all that is required for compositing the distributed data are the bounds of each rank's local data. MultiDevice ----------- The multidevice module is an experimental OSPRay device type that renders images by delegating off pixel tiles to a number of internal delegate OSPRay devices. 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_cpu` extension and create a multidevice for rendering instead of the default CPU device. One example in a bash like shell is as follows: ```sh OSPRAY_NUM_SUBDEVICES=6 ./ospTutorial --osp:load-modules=multidevice_cpu --osp:device=multidevice ``` Note that the multidevice currently does not support `OSPImageOperation`s for denoising nor tone mapping. RenderKit-ospray-85af292/doc/c-gamma_coords.fig000066400000000000000000000015371464752671100214100ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.7 Landscape Center Metric Letter 100.00 Single -2 1200 2 5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 1 4951.758 905.273 5400 1800 5130 1890 4950 1906 1 1 2.00 60.00 135.00 5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5265.000 1192.500 5850 900 5760 765 5310 540 1 1 1.00 60.00 135.00 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 2.00 120.00 270.00 4950 900 5850 900 2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 2 1 1 2.00 120.00 270.00 4950 900 4950 2250 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4950 900 5400 1800 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4950 900 5310 540 4 2 0 50 -1 16 14 0.0000 4 240 825 4860 990 position\001 4 0 0 50 -1 16 14 0.0000 4 180 900 5040 2340 direction\001 4 0 0 50 -1 16 14 0.0000 4 180 255 5850 990 c0\001 4 0 0 50 -1 16 14 0.0000 4 180 390 5490 450 c90\001 4 0 0 50 -1 32 14 0.0000 4 195 105 5085 1755 g\001 RenderKit-ospray-85af292/doc/compilation.md000066400000000000000000000105661464752671100207100ustar00rootroot00000000000000Standard CMake Build -------------------- ### Compiling OSPRay on Linux and Mac OS\ X Assuming the above requisites are all fulfilled, building OSPRay through CMake is easy: - Create a build directory, and go into it mkdir ospray/build cd ospray/build (We do recommend having separate build directories for different configurations such as release, debug, etc.). - The compiler CMake will use will default to whatever the `CC` and `CXX` environment variables point to. Should you want to specify a different compiler, run cmake manually while specifying the desired compiler. The default compiler on most linux machines is `gcc`, but it can be pointed to `clang` instead by executing the following: cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. CMake will now use Clang instead of GCC. If you are OK with using the default compiler on your system, then simply skip this step. Note that the compiler variables cannot be changed after the first `cmake` or `ccmake` run. - Open the CMake configuration dialog ccmake .. - Make sure to properly set build mode and enable the components you need, etc.; then type 'c'onfigure and 'g'enerate. When back on the command prompt, build it using make - You should now have `libospray.[so,dylib]` as well as a set of [example applications]. ### Compiling OSPRay on Windows On Windows using the CMake GUI (`cmake-gui.exe`) is the most convenient way to configure OSPRay and to create the Visual Studio solution files: - Browse to the OSPRay sources and specify a build directory (if it does not exist yet CMake will create it). - Click "Configure" and select as generator the Visual Studio version you have; OSPRay needs "Visual Studio 15 2017 Win64" or newer, 32\ bit builds are not supported, e.g., "Visual Studio 17 2022". - If the configuration fails because some dependencies could not be found then follow the instructions given in the error message, e.g., set the variable `embree_DIR` to the folder where Embree was installed and `openvkl_DIR` to where Open VKL was installed. - Optionally change the default build options, and then click "Generate" to create the solution and project files in the build directory. - Open the generated `OSPRay.sln` in Visual Studio, select the build configuration and compile the project. Alternatively, OSPRay can also be built without any GUI, entirely on the console. In the Visual Studio command prompt type: cd path\to\ospray mkdir build cd build cmake -G "Visual Studio 17 2022" [-D VARIABLE=value] .. cmake --build . --config Release Use `-D` to set variables for CMake, e.g., the path to Embree with "`-D embree_DIR=\path\to\embree`". You can also build only some projects with the `--target` switch. Additional parameters after "`--`" will be passed to `msbuild`. For example, to build in parallel only the OSPRay library without the example applications use cmake --build . --config Release --target ospray -- /m Finding an OSPRay Install with CMake ------------------------------------ Client applications using OSPRay can find it with CMake's `find_package()` command. For example, find_package(ospray 3.0.0 REQUIRED) finds OSPRay via OSPRay's configuration file `osprayConfig.cmake`^[This file is usually in `${install_location}/[lib|lib64]/cmake/ospray-${version}/`. If CMake does not find it automatically, then specify its location in variable `ospray_DIR` (either an environment variable or CMake variable).]. Once found, the following is all that is required to use OSPRay: target_link_libraries(${client_target} ospray::ospray) This will automatically propagate all required include paths, linked libraries, and compiler definitions to the client CMake target (either an executable or library). Advanced users may want to link to additional targets which are exported in OSPRay's CMake config, which includes all installed modules. All targets built with OSPRay are exported in the `ospray::` namespace, therefore all targets locally used in the OSPRay source tree can be accessed from an install. For example, `ospray_module_cpu` can be consumed directly via the `ospray::ospray_module_cpu` target. All targets have their libraries, includes, and definitions attached to them for public consumption (please [report bugs] if this is broken!). RenderKit-ospray-85af292/doc/displaywall.md000066400000000000000000000015311464752671100207070ustar00rootroot00000000000000OSPRay parallel rendering on TACC's "Stallion" display wall =========================================================== [![](gallery/thumbnails/ospray_stallion-thumb.jpg)](gallery/ospray_stallion.jpg) This photo shows OSPRay running on the [Stallion 328 megapixel tiled display](https://www.tacc.utexas.edu/vislab/stallion) at the Texas Advanced Computing Center (TACC) visualization lab. OSPRay is rendering in an MPI parallel mode and interactively streaming to the tiled display via its [DisplayCluster](https://www.tacc.utexas.edu/research-development/tacc-software/displaycluster) interface. These features are scheduled to be released in OSPRay v0.9. The model used is courtesy Florida International University and the Texas Advanced Computing Center, and stems from a simulation of Ground Water Flow performed by Florida International University. RenderKit-ospray-85af292/doc/documentation.md000066400000000000000000000011551464752671100212350ustar00rootroot00000000000000Documentation ============= The following [API documentation][OSPRayReadme] of OSPRay can also be found as a [pdf document][OSPRayReadme]. For a deeper explanation of the concepts, design, features and performance of OSPRay also have a look at the IEEE Vis 2016 paper "[OSPRay – A CPU Ray Tracing Framework for Scientific Visualization](https://www.ospray.org/talks/IEEEVis2016_OSPRay_paper.pdf)" (49MB, or get the [smaller version](https://www.ospray.org/talks/IEEEVis2016_OSPRay_paper_small.pdf) 1.8MB). The [slides of the talk](https://www.ospray.org/talks/IEEEVis2016_OSPRay_talk.pdf) (5.2MB) are also available. RenderKit-ospray-85af292/doc/filter-latex.py000066400000000000000000000035341464752671100210170ustar00rootroot00000000000000# 1. convert tables to use 'tabu' # Based on Wagner Macedo's filter.py posted at # https://groups.google.com/forum/#!msg/pandoc-discuss/RUC-tuu_qf0/h-H3RRVt1coJ import pandocfilters as pf def latex(s): return pf.RawBlock('latex', s) def inlatex(s): return pf.RawInline('latex', s) def tbl_caption(s): return pf.Para([inlatex(r'\caption{')] + s + [inlatex(r'}')]) def tbl_alignment(a): aligns = { "AlignDefault": 'l', "AlignLeft": 'l', "AlignCenter": 'c', "AlignRight": 'r', } s = ''.join(map(lambda al: aligns[al['t']], a[:-1])) s += 'X[1,'+aligns[a[-1]['t']]+']' return s def tbl_headers(s): result = s[0][0]['c'][:] for i in range(1, len(s)): result.append(inlatex(' & ')) result.extend(s[i][0]['c']) result.append(inlatex(r'\\' '\n')) return pf.Para(result) def tbl_contents(s): result = [] for row in s: para = [] for col in row: if col: para.extend(col[0]['c']) para.append(inlatex(' & ')) result.extend(para) result[-1] = inlatex(r'\\' '\n') return pf.Para(result) def do_filter(k, v, f, m): if k == "Table": w = v[2] if sum(w) == 0: w = [1 for e in w] wd = '' ha = r'\centering' else: wd = '*' ha = r'\raggedright' return [latex(r'\begin{table'+wd+'}[!h]'), tbl_caption(v[0]), latex(ha), latex(r'\begin{tabu}{' + tbl_alignment(v[1]) + '}'), latex(r'\toprule'), tbl_headers(v[3]), latex(r'\midrule'), tbl_contents(v[4]), latex(r'\bottomrule' '\n' r'\end{tabu}'), latex(r'\end{table'+wd+'}')] if __name__ == "__main__": pf.toJSONFilter(do_filter) RenderKit-ospray-85af292/doc/filter-sectionnumbers.py000066400000000000000000000007701464752671100227410ustar00rootroot00000000000000# remove section numbers for subheadings # Based on Wagner Macedo's filter.py posted at # https://groups.google.com/forum/#!msg/pandoc-discuss/RUC-tuu_qf0/h-H3RRVt1coJ import pandocfilters as pf sec = 0 def do_filter(k, v, f, m): global sec if sec > 2 or (k == "Header" and v[0] < 3): return [] if k == "Header" and v[0] > 2: sec += 1 v[1][1].append('unnumbered') return pf.Header(v[0], v[1], v[2]) if __name__ == "__main__": pf.toJSONFilter(do_filter) RenderKit-ospray-85af292/doc/fiu_comparison.md000066400000000000000000000017261464752671100214050ustar00rootroot00000000000000FIU Data Set: Shadows and Ambient Occlusion vs. OpenGL-like local shading ========================================================================= (click on images to see higher-res versions) [![](demos/fiu/fiu-gl-small.jpg)](demos/fiu/fiu-gl.png) FIU with local (OpenGL-like) Shading : Without shadows and/or ambient occlusion (i.e., using a OpenGL-like local shading model), the FIU data set looks like this. \ [![](demos/fiu/fiu-obj-small.jpg)](demos/fiu/fiu-obj.png) FIU with ray traced shadows : Simply adding shadows already greatly enhances the user's perception of depth (e.g., the relative positions of streamlines and base geometry, the actual shape of the geometry, etc.). \ [![](demos/fiu/fiu-ao-small.jpg)](demos/fiu/fiu-ao.png) FIU with OSPRay's Ambient Occlusion Renderer : Ambient Occlusion further increases perception of depth. In OSPRay, enabling (true, ray-cast) Ambient Occlusion is as simple as selecting the "ao" renderer. RenderKit-ospray-85af292/doc/gallery.md000066400000000000000000000142161464752671100200250ustar00rootroot00000000000000OSPRay Gallery ============== This page contains a few sample screenshots of different renderings done with OSPRay. If *you* have created any notable images through OSPRay and would like to share them on this page, please [send us an email](mailto:ospray@googlegroups.com). RenderKit-ospray-85af292/doc/getting_ospray.md000066400000000000000000000052701464752671100214240ustar00rootroot00000000000000Download Precompiled OSPRay Binary Packages =========================================== Prerequisites ------------- Your CPU must support at least SSE4.1 or NEON to run OSPRay. The TGZ/ZIP packages contain most needed 3rd party dependencies. Additionally you need - To run the example viewer: OpenGL - To use the distributed, multi-node rendering feature: Intel® [MPI Library](https://software.intel.com/en-us/intel-mpi-library/) We recommend the latest version of both TBB and Embree libraries. GPU Runtime Requirements ------------------------ To run OSPRay on Intel GPUs you will need to first have drivers installed on your system. ### GPU drivers on Linux Install the latest GPGPU drivers for your Intel GPU from: . Follow the driver installation instructions for your graphics card. ### GPU drivers on Windows Install the latest GPGPU drivers for your Intel GPU from: . Follow the driver installation instructions for your graphics card. Packages -------- Packages for x86_64 are provided, OSPRay can be built for ARM64/NEON using the superbuild (see [Building and Finding OSPRay](#building-and-finding-ospray)). For Linux we provide OSPRay precompiled for 64\ bit (including the GPU module) as a TGZ archive. [ospray-.x86_64.linux.tar.gz](https://github.com/ospray/OSPRay/releases/download/v/ospray-.x86_64.linux.tar.gz) For Mac OS\ X we provide OSPRay as a ZIP archives for x86_64 and ARM64 architectures: [ospray-.x86_64.macosx.zip](https://github.com/ospray/OSPRay/releases/download/v/ospray-.x86_64.macosx.zip) [ospray-.arm64.macosx.zip](https://github.com/ospray/OSPRay/releases/download/v/ospray-.arm64.macosx.zip) For Windows we provide OSPRay binaries precompiled for 64\ bit (including the GPU module) as an MSI installer as well as a ZIP archive. [ospray-.x86_64.windows.msi](https://github.com/ospray/OSPRay/releases/download/v/ospray-.x86_64.windows.msi) [ospray-.x86_64.windows.zip](https://github.com/ospray/OSPRay/releases/download/v/ospray-.x86_64.windows.zip) The source code of the latest OSPRay version can be downloaded here: [ospray-.zip](https://github.com/ospray/OSPRay/archive/v.zip) [ospray-.tar.gz](https://github.com/ospray/OSPRay/archive/v.tar.gz) You can also access [previous OSPRay releases](https://github.com/ospray/OSPRay/releases). RenderKit-ospray-85af292/doc/hdri_light.fig000066400000000000000000000006151464752671100206460ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.7 Landscape Center Metric Letter 100.00 Single -2 1200 2 2 1 0 3 0 7 60 -1 -1 0.000 0 0 -1 0 0 1 4500 1125 2 1 0 1 0 7 60 -1 -1 0.000 0 0 7 0 0 4 5850 450 5850 1800 3150 1800 3150 450 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3150 450 5850 450 4 0 0 50 -1 16 14 0.0000 4 195 270 5895 495 up\001 4 0 0 50 -1 16 14 0.0000 4 180 900 4590 1215 direction\001 RenderKit-ospray-85af292/doc/images.md000066400000000000000000000033041464752671100176270ustar00rootroot00000000000000[imgTutorial1]: tutorial_firstframe.png [imgTutorial2]: tutorial_accumulatedframe.png [imgRenderSunSky]: renderSunSky.png { width=90% } [imgOspExamples]: ospExamples.png { width=90% } [imgMPIDistribTutorial1]: ospMPIDistribTutorial_firstFrame.jpg { width=60% } [imgMPIDistribTutorial2]: ospMPIDistribTutorial_accumulatedFrame.jpg { width=60% } [imgMPIDistribTutorialSpheres]: ospMPIDistribTutorialSpheres.jpg { width=60% } [imgMPIDistribTutorialVolume]: ospMPIDistribTutorialVolume.jpg { width=60% } [imgCGammaCoords]: c-gamma_coords.fig [imgSpotLight]: spot_light.fig [imgQuadLight]: quad_light.fig [imgHDRILight]: hdri_light.fig [imgCameraPerspective]: camera_perspective.jpg { width=60% } [imgCameraArchitectural]: camera_architectural.jpg { width=60% } [imgCameraStereo]: camera_stereo.jpg { width=90% } [imgCameraOrthographic]: camera_orthographic.jpg { width=60% } [imgCameraPanoramic]: camera_panoramic.jpg { width=90% } [imgDiffuseRooms]: diffuse_rooms.png { width=80% } [imgNormalMap]: normalmap_frustum.png { width=60% } [imgMaterialOBJ]: material_OBJ.jpg { width=60% } [imgMaterialPrincipled]: material_Principled.jpg { width=60% } [imgMaterialCarPaint]: material_CarPaint.jpg { width=60% } [imgMaterialMetal]: material_Metal.jpg { width=60% } [imgMaterialAlloy]: material_Alloy.jpg { width=60% } [imgMaterialGlass]: material_Glass.jpg { width=60% } [imgMaterialThinGlass]: material_ThinGlass.jpg { width=60% } [imgMaterialMetallicPaint]: material_MetallicPaint.jpg { width=60% } [imgMaterialLuminous]: material_Luminous.jpg { width=60% } [imgColoredWindow]: ColoredWindow.jpg { width=60% } [imgStructuredSphericalCoords]: structured_spherical_coords.svg { width=60% } [imgVdbStructure]: vdb_structure.svg { width=80% } RenderKit-ospray-85af292/doc/legal.md000066400000000000000000000011451464752671100174470ustar00rootroot00000000000000Disclaimer and Legal Information ================================ © 2013 Intel Corporation [Privacy Notice](https://www.intel.com/privacy) Intel, the Intel logo, Xeon, Intel Xeon Phi, and Intel Core are trademarks of Intel Corporation in the U.S. and/or other countries. *Other names and brands may be claimed as the property of others. Performance varies by use, configuration and other factors. Learn more at [www.Intel.com/PerformanceIndex](https://www.intel.com/PerformanceIndex). Intel optimizations, for Intel compilers or other products, may not optimize to the same degree for non-Intel products. RenderKit-ospray-85af292/doc/links.md000066400000000000000000000023271464752671100175060ustar00rootroot00000000000000 [Embree]: https://www.embree.org/ [Open VKL]: https://www.openvkl.org/ [Open Image Denoise]: https://openimagedenoise.github.io/ [OSPRayReadme]: https://www.ospray.org/OSPRay_readme.pdf "OSPRay Documentation" [doc/ospray2_porting_guide.md]: https://www.ospray.org/ospray2_porting_guide.html [camera]: documentation.html#cameras [geometry]: documentation.html#geometries [volume]: documentation.html#volumes [curves]: documentation.html#curves [group]: documentation.html#groups [instance]: documentation.html#instances [world]: documentation.html#world [data]: documentation.html#data [GeometricModel]: documentation.html#geometricmodels [VolumetricModel]: documentation.html#volumetricmodels [texture transformations]: documentation.html#texture-transformations [renderer]: documentation.html#renderers [SciVis renderer]: documentation.html#scivis-renderer [path tracer]: documentation.html#path-tracer [material]: documentation.html#materials [OBJ material]: documentation.html#obj-material [point light]: documentation.html#point-light-sphere-light [example applications]: tutorials.html#tutorials [tutorial]: tutorials.html#osptutorial [ospExamples]: tutorials.html#ospexamples [report bugs]: index.html#ospray-support-and-contact RenderKit-ospray-85af292/doc/ospray2_porting_guide.md000066400000000000000000000265511464752671100227110ustar00rootroot00000000000000OSPRay v2.0 Porting Guide ========================= OSPRay v2.0.0 introduces a number of new features and updates, as well as some API changes. This guide is intended as an introduction to the new features and the concepts behind them, and as a guide to porting applications using OSPRay v1.8.x to v2.0.0. Parameters ---------- ### Setting parameters OSPRay traded having a limited number of parameter types (with a unique function signature for each type) by instead having a single generic function that takes any type found in the `OSPDataType` enum. The new function signature is as follows: void ospSetParam(OSPObject, const char *name, OSPDataType type, const void *mem) This function takes the address of the value being set, where care should be taken when setting pointer-based types. For example, consider the following C-array: float myValues[] = {0.f, 1.f, 2.f} If the application wants to set these values as an OSP_VEC3F, note that the `const void *mem` parameter to `ospSetParam` should point to what is the address of what would be a `vec3f`. Thus either of the following are valid: void ospSetParam(object, "some_parameter", OSP_VEC3F, &myValues[0]); or void ospSetParam(object, "some_parameter", OSP_VEC3F, myValues); The second variant relies on implicit casting from `float[]` to `float *`, which will point to the address of the first value. This then gets casted to a `vec3f` to be set on the target `object`. Some of the `ospSet*` functions were preserved as utility wrapper functions outlined later in this document (and can be found in `ospray_util.h`). ### OSPDataType type checking Where it was previously accepted to create data of generic type `OSP_OBJECT` to represent a list of any object type, the `OSPDataType` must now match the object(s) it contains. Objects ------- ### New Object Hierarchy OSPRay objects, such as `OSPGeometry` and `OSPVolume`, have a new hierarchy that affords more control over geometry and volume transformation and instancing in the scene. Previously, the workflow was to create an object, fill it with the necessary parameters, and then place the object into an `OSPModel` via, for example, `ospAddGeometry`. An example is shown below using the C API. OSPGeometry mesh = ospNewGeometry("triangles"); // set parameters on mesh ospCommit(mesh); OSPModel world = ospNewModel(); ospAddGeometry(world, mesh); ospRelease(mesh); ospCommit(world); In OSPRay v2.0.0, there is now an `OSPWorld`, which effectively replaces the old `OSPModel`. In addition, there are now 3 new objects that exist "in between" the geometry and the world: `OSPGeometricModel`, `OSPGroup`, and `OSPInstance`. There is also an `OSPVolumetricModel` equivalent for working with `OSPVolume` objects. The new workflow is shown below. Note that calls to `ospRelease()` have been removed for brevity. // create a geometry OSPGeometry mesh = ospNewGeometry("triangles"); // set parameters on mesh ospCommit(mesh); // put the geometry in a model (a geometry can exist in more than one model) OSPGeometricModel model = ospNewGeometricModel(mesh); ospCommit(model); // put the geometric model(s) in a group OSPGroup group = ospNewGroup(); OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1); ospSetObject(group, "geometry", geometricModels); ospCommit(group); // put the group in an instance (a group can be instanced more than once) OSPInstance = ospNewInstance(group); ospCommit(instance); // put the instance in the world OSPWorld world = ospNewWorld(); OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1); ospSetObject(world, "instance", instances); ospCommit(world); While this looks more complex at first, the new hierarchy structure provides more fine control over appearance information and instance transformations. In OSPRay v1.x, geometries and volumes contained both structural and appearance information which limited their reuse in other objects. For example, the volume's transfer function can now be different between an isosurface, slice, and rendered volume all in the same scene without duplicating the actual volume itself. #### OSPGeometry and OSPVolume `OSPGeometry` and `OSPVolume` contain the physical data represented by the object. For geometries, this is the intersectable surface. For volumes, it is the scalar field to be sampled. #### OSPGeometricModel and OSPVolumetricModel `OSPGeometricModel` and `OSPVolumetricModel` contain appearance information about the geometry or volume that they hold. They have a one-to-N relationship with `OSPGeometry` and `OSPVolume` objects (i.e. a geometry or volume can exist in more than one model), but commonly exist as one-to-one. This could be used to create multiple copies of a geometry with different materials, for example. `OSPGeometricModel`s can hold primitive color information (e.g. the color used for each sphere in a `Spheres` geometry), a material or list of materials, and primitive material IDs (i.e. indexes into the list of materials if it is used). `OSPVolumetricModel`s can hold transfer functions. #### OSPGroup `OSPGroup` objects contain zero or more `OSPGeometricModel` and `OSPVolumetricModel` objects. They can hold geometries and volumes simultaneously. This is useful to collect together any objects that are logically grouped together in the scene. #### OSPInstance `OSPInstance` contains transformation information on an `OSPGroup` object. It has a one-to-one relationship with `OSPGroup`. This means that each `OSPInstance` contains exactly one `OSPGroup`. Similar to models and groups, a single `OSPGroup` may be placed into multiple `OSPInstace` objects. This allows for *instancing* of multiple objects throughout the scene, each with different transformations. `OSPInstance` objects holds an affine transformation matrix that is applied to all objects in its group. #### OSPWorld `OSPWorld` is the final container for all `OSPInstance` and `OSPLight` objects. It can contain one or more instances and lights. The world is passed along with a renderer, camera, and framebuffer to `ospRenderFrame` to generate an image. ### void ospRetain(OSPObject) To allow the user greater control over the lifetime of objects, a new API `ospRetain` has been introduced. This call increments an object's reference count, and can delay automatic deletion. Updated Public Parameter Names ------------------------------ OSPRay v2.0.0 has updated public parameter names (the strings used in `ospSetParam`) to a more consistent naming convention. OSPRay now will print a warning (visible if debug logs are enabled) if a parameter provided by the user is not used by an object. This can help catch cases where applications are using parameter names from OSPRay v1.8.5 or mistyped names. Some objects have required parameters. In these cases, OSPRay will invoke the error callback indicating which object and which parameter. OSPRay now universally uses the camelCase naming convention for all object types and parameter names. Furthermore, parameter names which are data arrays now use singular names to indicate what the elements are, and parameters which form a logical "struture-of-arrays" are communicated via the `"[structure_name].[member_name]"` naming convention. For example, the `"opacities"` array for `linear` transfer functions is now named `"opacity"`. Finally, some parameters have changed from being string-based to enum-based. All enums can be found in `OSPEnums.h`, where their usage can be found in the main API documentation. ospRenderFrame -------------- `ospRenderFrame` has changed in two ways. The signature has changed from: float ospRenderFrame(OSPFrameBuffer, OSPRenderer, const uint32_t frameBufferChannels = OSP_FB_COLOR); to OSPFuture ospRenderFrame(OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); And, notably, it is no longer blocking. Two new calls `ospIsReady`, and `ospWait` are available to manage synchronization. Utility Library --------------- As a convenience, a lightweight utility library has been provided to help users port from the previous versions and reduce boilerplate code. This set of additional API calls are all implemented in terms of the core API found in `ospray.h`, where they can be found in `ospray_util.h`. Their definitions are compiled into `libospray` (the `ospray::ospray` CMake target) and are compatible with any valid device implementation. ### OSPData and Parameter helpers The core OSPRay API has been simplified by removing many of the type specializations from the data and parameter set calls. The utility library provides wrappers to the familiar calls listed below: ospSetString(OSPObject, const char *n, const char *s); ospSetObject(OSPObject, const char *n, OSPObject obj); ospSetBool(OSPObject, const char *n, int x); ospSetFloat(OSPObject, const char *n, float x); ospSetInt(OSPObject, const char *n, int x); ospSetVec2f(OSPObject, const char *n, float x, float y); ospSetVec3f(OSPObject, const char *n, float x, float y, float z); ospSetVec4f(OSPObject, const char *n, float x, float y, float z, float w); ospSetVec2i(OSPObject, const char *n, int x, int y); ospSetVec3i(OSPObject, const char *n, int x, int y, int z); ospSetVec4i(OSPObject, const char *n, int x, int y, int z, int w); ospSetObjectAsData(OSPObject, const char *n, OSPDataType type, OSPObject obj); OSPRay v1.x calls to `ospSetData` have been replaced with `ospSetObject`. Convenience wrappers have also been provided to specialize `ospNewData`, and the new `ospNewSharedData` and `ospCopyData` APIs. ospNewSharedData1D(const void *sharedData, OSPDataType type, uint32_t numItems); ospNewSharedData1DStride(const void *sharedData, OSPDataType type, uint32_t numItems, int64_t byteStride); ospNewSharedData2D(const void *sharedData, OSPDataType type, uint32_t numItems1, uint32_t numItems2); ospNewSharedData2DStride(const void *sharedData, OSPDataType type, uint32_t numItems1, int64_t byteStride1, uint32_t numItems2, int64_t byteStride2); ospNewSharedData3D(const void *sharedData, OSPDataType type, uint32_t numItems1, uint32_t numItems2, uint32_t numItems3); ospNewData1D(OSPDataType type, uint32_t numItems); ospNewData2D(OSPDataType type, uint32_t numItems1, uint32_t numItems2); ospCopyData1D(const OSPData source, OSPData destination, uint32_t destinationIndex); ospCopyData2D(const OSPData source, OSPData destination, uint32_t destinationIndex1, uint32_t destinationIndex2); ### Object Usage Simplification To simplify setting data onto an object, if there is only a single data item, the wrapper `ospSetObjectAsData` permits the user to assign this item without first creating a data object containing that item. For example: OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1); ospSetObject(group, "geometry", geometricModels); ospRelease(geometricModels); simply becomes: ospSetObjectAsData(group, "geometry", OSP_GEOMETRIC_MODEL, model); ### Rendering helpers While `ospRenderFrame` is now asynchronous, some users will prefer the original blocking behavior that returns the frame variance. The utility library provides a wrapper to this functionality: float ospRenderFrameBlocking(OSPFrameBuffer fb, OSPRenderer renderer, OSPCamera camera, OSPWorld world) RenderKit-ospray-85af292/doc/overview.md000066400000000000000000000044501464752671100202330ustar00rootroot00000000000000OSPRay Overview =============== Intel® OSPRay is an **o**pen source, **s**calable, and **p**ortable **ray** tracing engine for high-performance, high-fidelity visualization on Intel Architecture CPUs, Intel Xe GPUs, and ARM64 CPUs. OSPRay is part of the [Intel Rendering Toolkit (Render Kit)](https://software.intel.com/en-us/rendering-framework) and is released under the permissive [Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0). The purpose of OSPRay is to provide an open, powerful, and easy-to-use rendering library that allows one to easily build applications that use ray tracing based rendering for interactive applications (including both surface- and volume-based visualizations). OSPRay runs on anything from laptops, to workstations, to compute nodes in HPC systems. OSPRay internally builds on top of Intel [Embree], Intel [Open VKL], and Intel [Open Image Denoise]. The CPU implementation is based on 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. Hence, a CPU with support for at least SSE4.1 is required to run OSPRay on x86_64 architectures, or a CPU with support for NEON is required to run OSPRay on ARM64 architectures. OSPRay's GPU implementation (beta status) is based on the [SYCL](https://www.khronos.org/sycl/) cross-platform programming language implemented by [Intel oneAPI Data Parallel C++ (DPC++)](https://www.intel.com/content/www/us/en/developer/tools/oneapi/data-parallel-c-plus-plus.html) and currently supports Intel Arcâ„¢ GPUs on Linux and Windows, and Intel Data Center GPU Flex and Max Series on Linux, exploiting ray tracing hardware support. OSPRay Support and Contact -------------------------- OSPRay is under active development, and though we do our best to guarantee stable release versions a certain number of bugs, as-yet-missing features, inconsistencies, or any other issues are still possible. For any such requests or findings please use [OSPRay's GitHub Issue Tracker](https://github.com/ospray/OSPRay/issues) (or, if you should happen to have a fix for it, you can also send us a pull request). To receive release announcements simply ["Watch" the OSPRay repository](https://github.com/ospray/OSPRay) on GitHub. RenderKit-ospray-85af292/doc/preamble.tex000066400000000000000000000150061464752671100203530ustar00rootroot00000000000000\usepackage{polyglossia} \setdefaultlanguage{english} \usepackage{amssymb,amsmath} \usepackage{nicefrac} \usepackage{ifxetex,ifluatex} \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \else % if luatex or xelatex \ifxetex % \usepackage{mathspec} \usepackage[no-sscript]{xltxtra} \usepackage{xunicode} \else \usepackage{fontspec} \fi \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase} \newcommand{\euro}{€} \fi % use upquote if available, for straight quotes in verbatim environments \IfFileExists{upquote.sty}{\usepackage{upquote}}{} % use microtype if available \IfFileExists{microtype.sty}{% \usepackage{microtype} \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts }{} \PassOptionsToPackage{hyphens}{url} % url is loaded by hyperref \usepackage{tabu,booktabs} \tabulinesep=3pt \usepackage{graphicx} \usepackage{color} \usepackage{fancyvrb} \newcommand{\VerbBar}{|} \newcommand{\VERB}{\Verb[commandchars=\\\{\}]} \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} % fix issue with linebreaks and letter spacing in non-cpp blocks \DefineVerbatimEnvironment{verbatim}{Verbatim}{} % Add ',fontsize=\small' for more characters per line \newenvironment{Shaded}{}{} \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}} \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}} \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}} \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}} \newcommand{\ImportTok}[1]{#1} \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}} \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}} \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}} \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}} \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}} \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand{\BuiltInTok}[1]{#1} \newcommand{\ExtensionTok}[1]{#1} \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}} \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}} \newcommand{\RegionMarkerTok}[1]{#1} \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}} \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}} \newcommand{\NormalTok}[1]{#1} \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \makeatletter \def\maxwidth{\ifdim\Gin@nat@width>\columnwidth\columnwidth\else\Gin@nat@width\fi} \def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} \def\fps@figure{htp}% set default figure placement \makeatother % Scale images if necessary, so that they will not overflow the page % margins by default, and it is still possible to overwrite the defaults % using explicit options in \includegraphics[width, height, ...]{} \setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} \ifxetex \usepackage[setpagesize=false, % page size defined by xetex unicode=false, % unicode breaks when used with xetex xetex]{hyperref} \else \usepackage[unicode=true]{hyperref} \fi % read version into \osprayversion \newread\versionfile \openin\versionfile=tmp/version \read\versionfile to\osprayversion \closein\versionfile \hypersetup{breaklinks=true, bookmarks=true, pdfauthor={Intel Corporation}, pdftitle={OSPRay: An Open, Scalable, Parallel, Ray Tracing Based Rendering Engine for High-Fidelity Visualization \osprayversion}, colorlinks=true, citecolor=blue, urlcolor=blue, linkcolor=blue, pdfborder={0 0 0}} \copyrightyears{2013} \trademarkacknowledgment{% Intel, the Intel logo, Xeon, Intel Xeon Phi, and Intel Core are trademarks of Intel Corporation in the U.S. and/or other countries. } \performancedisclaimer \optimizationdisclaimer % no hyphenation (e.g. for trademarks) \hyphenation{Intel Xeon} % fix missing unicode chars in used font \catcode`\â‡\active \defâ‡{\ensuremath{\Leftarrow}} \catcode`\⇒\active \def⇒{\ensuremath{\Rightarrow}} \catcode`\â†\active \defâ†{\ensuremath{\leftarrow}} \catcode`\→\active \def→{\ensuremath{\rightarrow}} \catcode`\∞\active \def∞{\ensuremath{\infty}} \catcode`\½\active \def½{\nicefrac12} \catcode`\â…“\active \defâ…“{\nicefrac13} \catcode`\â…”\active \defâ…”{\nicefrac23} \catcode`\¼\active \def¼{\nicefrac14} \catcode`\¾\active \def¾{\nicefrac34} \catcode`\∙\active \def∙{\ensuremath{\cdot}} % fix overfull hboxes, somehow required for xelatex % pdflatex and lualatex is fine without \emergencystretch=0.5em \makeatletter% \newcommand*{\BreakableChar}{% \leavevmode% \nobreak\hskip\z@skip% \discretionary{}{}{}% \nobreak\hskip\z@skip% }% \makeatother % enable (more flexible) linebreaks in \texttt \renewcommand{\texttt}[1]{% \begingroup% \protect\renewcommand{\_}{\textunderscore\BreakableChar}% \ttfamily% \fontdimen3\font=0.1em% interword stretch \fontdimen4\font=0.1em% interword shrink \hyphenchar\font=`\-% to allow hyphenation \begingroup\lccode`~=`/\lowercase{\endgroup\def~}{/\BreakableChar}% \catcode`/=\active% \begingroup\lccode`~=`*\lowercase{\endgroup\def~}{*\BreakableChar}% \catcode`*=\active% \begingroup\lccode`~=`?\lowercase{\endgroup\def~}{?\BreakableChar}% \catcode`?=\active% \begingroup\lccode`~=`)\lowercase{\endgroup\def~}{)\BreakableChar}% \catcode`)=\active% \begingroup\lccode`~=`.\lowercase{\endgroup\def~}{.\BreakableChar}% \catcode`.=\active% \begingroup\lccode`~=`;\lowercase{\endgroup\def~}{;\BreakableChar}% \catcode`;=\active% \scantokens{#1\noexpand}% \endgroup% } RenderKit-ospray-85af292/doc/prerequisites.md000066400000000000000000000106551464752671100212750ustar00rootroot00000000000000Building and Finding OSPRay =========================== The latest OSPRay sources are always available at the [OSPRay GitHub repository](http://github.com/ospray/ospray). The default `master` branch should always point to the latest bugfix release. Prerequisites ------------- OSPRay currently supports Linux, Mac OS\ X, and Windows. In addition, before you can build OSPRay you need the following prerequisites: - You can clone the latest OSPRay sources via: git clone https://github.com/ospray/ospray.git - To build OSPRay you need [CMake](http://www.cmake.org), any form of C++11 compiler (we recommend using GCC, but also support Clang, MSVC, and [Intel® C++ Compiler (icc)](https://software.intel.com/en-us/c-compilers)), and standard Linux development tools. - Additionally you require a copy of the [Intel® Implicit SPMD Program Compiler (ISPC)](http://ispc.github.io), version 1.23.0 or later. Please obtain a release of ISPC from the [ISPC downloads page](https://ispc.github.io/downloads.html). If ISPC is not found by CMake its location can be hinted with the variable `ISPC_EXECUTABLE`. - OSPRay builds on top of the [Intel Rendering Toolkit (Render Kit) common library (rkcommon)](https://www.github.com/ospray/rkcommon). The library provides abstractions for tasking, aligned memory allocation, vector math types, among others. For users who also need to build rkcommon, we recommend the default the Intel [Threading Building Blocks (TBB)](https://www.threadingbuildingblocks.org/) as tasking system for performance and flexibility reasons. TBB must be built from source when targeting ARM CPUs, or can be built from source as part of the [superbuild](#cmake-superbuild). Alternatively you can set CMake variable `RKCOMMON_TASKING_SYSTEM` to `OpenMP` or `Internal`. - OSPRay also heavily uses Intel [Embree], installing version 4.3.3 or newer is required. If Embree is not found by CMake its location can be hinted with the variable `embree_DIR`. - OSPRay supports volume rendering (enabled by default via `OSPRAY_ENABLE_VOLUMES`), which heavily uses Intel [Open VKL], version 2.0.1 or newer is required. If Open VKL is not found by CMake its location can be hinted with the variable `openvkl_DIR`, or disable `OSPRAY_ENABLE_VOLUMES`. - OSPRay also provides an optional module implementing the `denoiser` image operation, which is enabled by `OSPRAY_MODULE_DENOISER`. This module requires Intel [Open Image Denoise] in version 2.3.0 or newer. You may need to hint the location of the library with the CMake variable `OpenImageDenoise_DIR`. - For the optional MPI modules (enabled by `OSPRAY_MODULE_MPI`), which provide the `mpiOffload` and `mpiDistributed` devices, you need an MPI library and [Google Snappy](https://github.com/google/snappy). - The optional example application, the test suit and benchmarks need some version of OpenGL and GLFW as well as [GoogleTest](https://github.com/google/googletest) and [Google Benchmark](https://github.com/google/benchmark/) Depending on your Linux distribution you can install these dependencies using `yum` or `apt-get`. Some of these packages might already be installed or might have slightly different names. Type the following to install the dependencies using `yum`: sudo yum install cmake.x86_64 sudo yum install tbb.x86_64 tbb-devel.x86_64 Type the following to install the dependencies using `apt-get`: sudo apt-get install cmake-curses-gui sudo apt-get install libtbb-dev Under Mac OS\ X these dependencies can be installed using [MacPorts](http://www.macports.org/): sudo port install cmake tbb Under Windows please directly use the appropriate installers for [CMake](https://cmake.org/download/), [TBB](https://github.com/oneapi-src/oneTBB/releases), [ISPC](https://ispc.github.io/downloads.html) (for your Visual Studio version) and [Embree](https://github.com/embree/embree/releases/). ### Additional Prerequisites for GPU Build {-} To build OSPRay's GPU module you need - a SYCL compiler, either the open source [oneAPI DPC++ Compiler 2023-10-26](https://github.com/intel/llvm/releases/tag/nightly-2023-10-26) or the latest [Intel oneAPI DPC++/C++ Compiler](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp) - a recent [CMake](http://www.cmake.org), version 3.25.3 or higher RenderKit-ospray-85af292/doc/pvospray.md000066400000000000000000000013021464752671100202410ustar00rootroot00000000000000OSPRay running inside ParaView ============================== [![](related_projects/vtk-paraview/screenshot-paraview-fiu-thumb.jpg)](related_projects/vtk-paraview/screenshot-paraview-fiu.jpg) This picture shows a ParaView plugin that allows ParaView to render through OSPRay, using a ParaView/VTK plugin developed by the Texas Advanced Computing Center. (click on the image for a full-resolution version) The particular model used in this screenshot is courtesy Florida International University and the Texas Advanced Computing Center, and stems from a simulation of Ground Water Flow performed by Florida International University. Screenshot courtesy Carson Brownlee, Texas Advanced Computing Center. RenderKit-ospray-85af292/doc/quad_light.fig000066400000000000000000000014571464752671100206570ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.7 Landscape Center Metric Letter 100.00 Single -2 1200 2 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 3204.068 1745.932 3150 1080 3678 1275 3870 1800 1 1 1.00 60.00 135.00 2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 2 1 1 2.00 120.00 270.00 3150 1800 5400 1800 2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 2 1 1 2.00 120.00 270.00 3150 1800 3150 450 2 2 0 1 0 7 60 -1 -1 0.000 0 0 7 0 0 5 3150 450 5400 450 5400 1800 3150 1800 3150 450 2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 2 1 1 2.00 120.00 270.00 3150 1800 3150 990 4 1 0 50 -1 16 14 0.0000 4 240 825 3105 2070 position\001 4 0 0 50 -1 16 14 0.0000 4 240 675 3240 720 edge2\001 4 2 0 50 -1 16 14 0.0000 4 240 675 5175 2070 edge1\001 4 0 0 50 -1 16 14 0.0000 4 180 255 3240 1305 c0\001 4 0 0 50 -1 16 14 0.0000 4 180 390 3915 1710 c90\001 RenderKit-ospray-85af292/doc/readme.tex000066400000000000000000000016521464752671100200230ustar00rootroot00000000000000\IfFileExists{ospray-doc/intel-spec.cls} { \documentclass[oneside]{ospray-doc/intel-spec} }{ \documentclass[oneside]{report} \newcommand{\copyrightyears}[1] {} \newcommand{\trademarkacknowledgment}[1] {} \newcommand{\performancedisclaimer}{} \newcommand{\optimizationdisclaimer}{} \newcommand{\makedisclaimers}{} \newcommand{\version}[1] { \author{Version ##1} } } \include{preamble} \begin{document} \title{Intel® OSPRay\vskip0.3\baselineskip\LARGE \noindent An Open, Scalable, Parallel, Ray Tracing Based Rendering Engine for High-Fidelity Visualization} \version{\osprayversion} \maketitle \tableofcontents \input{tmp/overview} \input{tmp/changelog} \input{tmp/compilation} \addtocontents{toc}{\protect\setcounter{tocdepth}{2}} \hypersetup{bookmarksdepth=2} \input{tmp/api} \addtocontents{toc}{\protect\setcounter{tocdepth}{1}} \hypersetup{bookmarksdepth=1} \input{tmp/tutorials} \makedisclaimers \end{document} RenderKit-ospray-85af292/doc/readme_head.md000066400000000000000000000002671464752671100206050ustar00rootroot00000000000000OSPRay ====== This is release v of Intel® OSPRay. For changes and new features see the [changelog](CHANGELOG.md). Visit http://www.ospray.org for more information. RenderKit-ospray-85af292/doc/related_projects.md000066400000000000000000000073671464752671100217300ustar00rootroot00000000000000Projects that make use of OSPRay ================================ This page gives a brief (and incomplete) list of other projects that make use of OSPRay, as well as a set of related links to other projects and related information. If you have a project that makes use of OSPRay and would like this to be listed here, please let us know. VTK, ParaView and VisIt ----------------------- VTK and Paraview 5.x+ have direct integrations for OSPRay rendering, as has [VisIt 3.x+](https://wci.llnl.gov/simulation/computer-codes/visit). Code and documentation are available on Kitware's instance of [GitLab](https://gitlab.kitware.com/paraview/paraview). Furthermore, interested users can also access Kitware's [tutorial on using OSPRay](https://www.paraview.org/Wiki/Intel_HPC_Dev_Con_ParaView_and_OSPRay_Tutorial). For information on using the path tracer inside ParaView, see [this Kitware blog post](https://blog.kitware.com/virtual-tour-and-high-quality-visualization-with-paraview-5-6-ospray/). HdOSPRay -------- HdOSPRay is a rendering plugin for the Hydra rendering layer in USD. For more information see the project's [page on GitHub](https://github.com/ospray/hdospray). OSPRay Studio -------- [Studio](https://github.com/ospray/ospray_studio) is the OSPRay team's lightweight visualization application used to showcase the latest features of OSPRay. "osprey" Rhino Viewport Plugin -------- [osprey](https://github.com/darbyjohnston/Osprey) is a rendering plugin written by Darby Johnston for Rhino3D that greatly accelerates rendering over the built-in renderer. BLOSPRAY -------- [BLOSPRAY](https://github.com/surfsara-visualization/blospray) is a rendering plugin for Blender that uses OSPRay for fast previews and final path traced rendering. Tapestry -------- Tapestry is a microservice for delivering scientific visualization on the cloud. With OSPRay, Tapestry can provide interactive visualization of large datasets accessible to many users throughout the web ecosystem. See the [demo page](https://seelabutk.github.io/tapestry/) and the project's [page on GitHub](https://github.com/seelabutk/tapestry) for more information. Megamol ------- [Megamol](https://megamol.org/2018/07/02/megamol-at-isc-2018/) is a molecular dynamics framework. With OSPRay, it can render billions of particles interactively. VESTEC ------ [![VESTEC](images/VESTEC-Logo-web.png){style="display:inline"}](https://vestec-project.eu/) [VESTEC](https://vestec-project.eu/) – Visual Exploration and Sampling Toolkit for Extreme Computing – is an European funded project that builds a flexible toolchain to combine multiple data sources, efficiently extract essential features, enable flexible scheduling and interactive supercomputing, and realize 3D visualization environments (partly using OSPRay) for interactive explorations by stakeholders and decision makers. VMD --- VMD is a popular molecular dynamics visualization package, where OSPRay is integrated as one its renderers. For more information see VMD's [release notes](https://www.ks.uiuc.edu/Research/vmd/current/). pCon.planner --- [pCon.planner](https://pcon-planner.com/en/) is an architectural design and rendering application that utilizes OSPRay for path traced photorealistic renderings. Projects that are closely related to OSPRay =========================================== - The Intel® [Embree] Ray Tracing Kernel Framework - Intel [Open Image Denoise], a high-performance denoising library - OSPRay's "sister project" [OpenSWR](http://openswr.org/) (**o**pen **s**oft**w**are **r**asterizer), a high-performance, highly-scalable, software OpenGL implementation that runs entirely on CPUs. OpenSWR is now included in [Mesa](http://mesa3d.org/). - The [Intel Implicit SPMD Program Compiler](http://ispc.github.io) (ISPC) RenderKit-ospray-85af292/doc/spot_light.fig000066400000000000000000000010271464752671100207030ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5c Landscape Center Metric Letter 100.00 Single -2 1200 2 5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 4275.000 1974.375 3600 3150 4275 3330 4950 3150 5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 4972.500 3307.500 5175 4140 5310 4095 5400 4050 2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 0 0 3 2250 5850 4275 1800 6300 5850 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 2700 5850 4275 1800 5850 5850 4 0 0 50 -1 16 14 0.0000 4 225 1500 4950 2970 openingAngle\001 4 0 0 50 -1 16 14 0.0000 4 225 1710 5400 3870 penumbraAngle\001 RenderKit-ospray-85af292/doc/stylesheet.css000066400000000000000000000324511464752671100207500ustar00rootroot00000000000000body { font-size: 16px; font-weight: normal; letter-spacing: normal; color:#373737; background: #f2f2f2; font-family: "Myriad Set Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; text-rendering: optimizeLegibility; font-style: normal; line-height: 1.5; -webkit-font-smoothing: antialiased; text-align: justify; margin: 0; } h1, h2, h3, h4, h5, h6 { margin: 5px 0; font-weight: 700; color: #0071C5; letter-spacing: normal; clear: both; } h2 { background: none; border-top: 1pt solid #333; padding-top: 0.5em; } h1 { font-size: 24px; } h2 { font-size: 20px; } h3 { font-size: 16px; } h4 { font-size: 16px; } p { margin: 10px 0 15px 0; } dl dt { font-weight:bold; } code { font-size: 90%; } li p { margin: 0 } img { display: block; margin-left: auto; margin-right: auto; padding: 0 2em 1ex 0; } figcaption { color: #666; text-align: center; } div.left { float: left; max-width: 250px; margin: 0; padding: 0; } br { clear:both; } #TOC { max-height: 100%; max-width: calc(190px + 4em); top: 125px; left: -4em; position: fixed; z-index: 1; overflow-x: hidden; background: #e0e0e0; padding-right: 10px; text-align: left; } /* hide top-level items */ #TOC > ul > li { list-style: none; } #TOC > ul > li > a { display: none; } #TOC > ul > li > ul { list-style: none; } #demo-bullets { font-size: 90%; } #footer { padding-top: 5px; margin: 0; text-align: center; background:#212121; position:fixed; bottom:0px; height:22px; width:100%; font-size: 12px; color: #ffffff; } #footer_padding { margin: 0; text-align: center; background:#212121; bottom:0px; width:100%; height:100%; font-size: 12px; color: #ffffff; } #footer a:hover { color:#ff0000; } #footer a { color:#ffffff; } #header { color: #fff; position: fixed; width: 100%; letter-spacing: -1px; background: #379; z-index: 2; display: block; } #content-wrap { width:100%; height:calc(100% - 134px); position:fixed; top:107px; overflow:auto; background: #f2f2f2; } #content, #content-wtoc { padding-left: 5px; padding-right: 0px; position:static; max-width: 1024px; margin-left: auto; margin-right: auto; background: #f2f2f2; padding-top:10px; padding-bottom:10px; } /* prevent content to reach into TOC if not enough space */ @media screen and ( max-width: 1444px ) { #content-wtoc { margin-left: 200px; margin-right: 0px; } } #header-title { /*display:inline-block;*/ margin: 0; color: #fff; font-size: 42px; /*background:#212121; */ font-weight: 700; padding: 20px 0px 0px 10px; text-shadow: #111 0px 0px 10px; /*padding-left: 100px;*/ padding-top:10px; letter-spacing: -1px; max-width: 1024px; margin-left: auto; margin-right: auto; } #header-subtitle { display:inline-block; color: #fff; font-size: 21px; font-weight: 300; /*background: none;*/ text-shadow: #111 0px 0px 10px; /*padding-top: 10px;*/ /*padding-left: 100px;*/ padding-left: 10px; /*padding-bottom: 10px;*/ /*background:#212121; */ letter-spacing: -1px; } #header-github { color: #fff; font-size: 16px; font-weight: 300; background: none; } #forkme-banner { display: block; position: absolute; top:0; right: 20px; width:250px; z-index: 10; padding: 10px 0px 10px 20px; color: #fff; background: url('images/blacktocat.png') #0090ff no-repeat 80% 50%; font-weight: 700; } #header-spacing { color: #fff; font-size: 16px; font-weight: 300; height:5px; background: #f2f2f2; } #footer-spacing { color: #fff; font-size: 16px; font-weight: 300; height:5px; background: #f2f2f2; } #header-navbar { font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; color: #fff; font-size: 14px; font-weight: normal; letter-spacing: normal; background: #444; padding-top: 0px; padding-bottom: 4px; height:18px; } #header-navbar ul { list-style : none; margin: 0; padding: 0; padding-top: 2px; max-width: 1024px; margin-left: auto; margin-right: auto; } #header-navbar ul li { display: inline; } #header-navbar ul li a { display: block; float: left; padding-left: 8px; padding-right: 8px; color: #DFDFDF; text-decoration: none; } #header-navbar ul li a:hover { color: #FAFAFA; } #header-navbar ul li#selected a { color: #fff; } .title { border: 0; padding: 0; margin: 0; margin-bottom: 20px; } .title h1 { color: #333; font-size: 60px; font-weight: 300; text-align: center; border: 0; padding: 0; margin: 0; border: 0; } .title h2 { color: #888; font-size: 24px; font-weight: 200; text-align: center; border: 0; padding: 0; margin: 0; border: 0; } .teaser-features { margin: 10px auto 150px auto; } div.feature { /* display:inline-block; */ /* width: 100%; */ margin-left: 10px; margin-right: 10px; margin-top: 10px; margin-bottom: 10px; float: left; /* width: 40%; */ width: 400px; height: 200px; display: block; } div.feature a { color:#373737; } div.feature img { float: left; display:inline-block; width: 360px; height: 260px; padding:0; box-shadow: 4px 4px 18px -5px rgba(0,0,0,0.86); } .feature-alt { display: block; float: left; padding-left: 184px; } .feature-alt img { float: right !important; } .feature .container { /* margin-left: 20px; margin-right: 20px; display:inline-block; max-width: 544px; color: #666; font-size: 18px; font-weight: 200; */ } div.feature p { /* padding-left: 20px; */ color: #777; } div.feature h2 { text-align: center; border: 0; color:#555; font-size: 26px; } .fadein { display: block; margin-left: auto; margin-right: auto; margin-bottom: 20px; margin-top: 0px; padding: 0; position: relative; padding-bottom: 58.59375%; /* 600/1024 */ max-width: 1000px; } #f1 { box-shadow: 4px 4px 18px -5px rgba(0,0,0,0.86); } .fadein img { margin-left: auto; max-width: 100%; height: 100%; padding: 0; position: absolute; } .teaser-img { margin-top: 60px; margin-bottom: 60px; } .fade { animation: fade 30s 1; } @keyframes fade { 0% {opacity: 0;} 5% {opacity: 0;} 20% {opacity: 1;} 25% {opacity: 1;} 45% {opacity: 0;} 50% {opacity: 0;} 60% {opacity: 1;} 65% {opacity: 1;} 75% {opacity: 0;} 80% {opacity: 0;} 100% {opacity: 1;} } hr { width: 60%; display: block; height: 1px; margin-left: auto; margin-right: auto; margin-top: 0px; margin-bottom: 0px; border: 0; border-top: 1.5px solid #aaa; padding: 0; } table { counter-increment: table; border-collapse: collapse; border-spacing: 0; border: 0px solid #373737; margin-top: 20px; margin-bottom: 20px; text-align: left; } table > caption:before { content: 'Table ' counter(table) ': '; color: #0071C5; } th { font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 10px; background: #0071C5; color: #fff; } td { padding: 10px; border: 0px solid #373737; color: #222; background-color: #fff; vertical-align:top; } div.figure { clear: both; counter-increment: figure; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; margin: 0 0 3em 0; display: inline-block; width: 100%; } p.caption { margin-top: 3ex; font-size: 1.1rem; line-height: 1.6; text-align: left; } p.caption:before { content: 'Figure ' counter(figure) ': '; color: #0071C5; } .carousel { position: relative; } .carousel.pointer-event { -ms-touch-action: pan-y; touch-action: pan-y; } .carousel-inner { position: relative; width: 100%; overflow: hidden; padding-bottom: 4em; margin-top: 15px; margin-bottom: 15px; } .carousel-inner img { width: 100%; height: 100%; } .carousel-inner::after { display: block; clear: both; content: ""; } .carousel-item { position: relative; display: none; float: left; margin-right: -100%; -webkit-backface-visibility: hidden; backface-visibility: hidden; transition: -webkit-transform 0.6s ease-in-out; transition: transform 0.6s ease-in-out; transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out; height: 428px; } @media (prefers-reduced-motion: reduce) { .carousel-item { transition: none; } } .carousel-item.active, .carousel-item-next, .carousel-item-prev { display: block; } .carousel-item-next:not(.carousel-item-left), .active.carousel-item-right { -webkit-transform: translateX(100%); transform: translateX(100%); } .carousel-item-prev:not(.carousel-item-right), .active.carousel-item-left { -webkit-transform: translateX(-100%); transform: translateX(-100%); } .carousel-fade .carousel-item { opacity: 0; transition-property: opacity; -webkit-transform: none; transform: none; } .carousel-fade .carousel-item.active, .carousel-fade .carousel-item-next.carousel-item-left, .carousel-fade .carousel-item-prev.carousel-item-right { z-index: 1; opacity: 1; } .carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right { z-index: 0; opacity: 0; transition: 0s 0.6s opacity; } @media (prefers-reduced-motion: reduce) { .carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right { transition: none; } } .carousel-control-prev, .carousel-control-next { position: absolute; top: 0; bottom: 4em; z-index: 1; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; -ms-flex-pack: center; justify-content: center; width: 15%; color: #fff; text-align: center; opacity: 0.5; transition: opacity 0.15s ease; } @media (prefers-reduced-motion: reduce) { .carousel-control-prev, .carousel-control-next { transition: none; } } .carousel-control-prev:hover, .carousel-control-prev:focus, .carousel-control-next:hover, .carousel-control-next:focus { color: #fff; text-decoration: none; outline: 0; opacity: 0.9; } .carousel-control-prev { left: 0; } .carousel-control-next { right: 0; } .carousel-control-prev-icon, .carousel-control-next-icon { display: inline-block; width: 20px; height: 20px; background: no-repeat 50% / 100% 100%; } .carousel-control-prev-icon { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e"); } .carousel-control-next-icon { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e"); } .carousel-indicators { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; display: -ms-flexbox; display: flex; -ms-flex-pack: center; justify-content: center; padding-left: 0; margin-right: 15%; margin-left: 15%; list-style: none; padding-bottom: 20px; } .carousel-indicators li { box-sizing: content-box; -ms-flex: 0 1 auto; flex: 0 1 auto; width: 30px; height: 3px; margin-right: 3px; margin-left: 3px; text-indent: -999px; cursor: pointer; background-color: #fff; background-clip: padding-box; border-top: 10px solid transparent; border-bottom: 45px solid transparent; opacity: .5; transition: opacity 0.6s ease; } @media (prefers-reduced-motion: reduce) { .carousel-indicators li { transition: none; } } .carousel-indicators .active { opacity: 1; } .carousel-caption { position: absolute; right: 15%; bottom: -80px; left: 15%; z-index: 1; padding-top: 40px; color: #fff; text-align: center; overflow: visible; line-height: normal; } .carousel-caption h3 { color: #555; } .carousel-caption p { color: #777; } .carousel img { padding: 0px; margin-bottom:8px; box-shadow: 0 8px 10px -6px black; } .gallery { display: grid; #border: 2px dashed rgba(114, 186, 94, 0.35); height: 250px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: auto; #background: rgba(114, 186, 94, 0.05); } .exhibit { display: block; margin-left: auto; margin-right: auto; padding: 0 2em 1ex 0; # width: 50%; # height: 50%; font-size: 16px; margin: 5px 0; font-weight: 700; color: #0071C5; letter-spacing: normal; clear: both; text-align: center; } .exhibit img { margin: 0; padding: 0; #float: left; #display:inline-block; display: block; float: left; width: 300px; box-shadow: 3px 3px 12px -5px rgba(0,0,0,0.86); } .exhibit .caption { font-size: 12px; color: #555; text-align: center; }RenderKit-ospray-85af292/doc/teaser.html000066400000000000000000000074461464752671100202240ustar00rootroot00000000000000

The Open, Scalable, and Portable Ray Tracing Engine



Interactive Rendering on CPU or GPU

OSPRay features scalable CPU and GPU rendering capabilities geared toward Scientific Visualization applications. Advanced shading effects such as ambient occlusion, shadows, and transparency can be rendered interactively to enable new insights into huge data.

Global Illumination

OSPRay includes a path tracer capable of interactively rendering photorealistic global illumination with phyiscally-based materials.

Volume Rendering

OSPRay supports high-fidelity, interactive direct volume rendering with a number of state of the art visualization features.

MPI Distributed

Run on large scale distributed-memory systems with high-performance MPI backends to both decrease render time and increase total scene size.

Industry Adoption

OSPRay is directly integrated into ParaView 5.x. Implementations for VisIt, VMD, and other popular tools have also freely available.

Open Source

OSPRay is Open Sourced under the Apache 2.0 license.

RenderKit-ospray-85af292/doc/tutorials.md000066400000000000000000000213021464752671100204060ustar00rootroot00000000000000Tutorials ========= ospTutorial ----------- A minimal working example demonstrating how to use OSPRay can be found at [`apps/tutorials/ospTutorial.c`](https://github.com/ospray/ospray/blob/master/apps/ospTutorial/ospTutorial.c)^[A C++ version that uses the C++ convenience wrappers of OSPRay's C99 API via [`include/ospray/ospray_cpp.h`](https://github.com/ospray/ospray/blob/master/ospray/include/ospray/ospray_cpp.h) is available at [`apps/tutorials/ospTutorial.cpp`](https://github.com/ospray/ospray/blob/master/apps/ospTutorial/ospTutorial.cpp).]. An example of building `ospTutorial.c` with CMake can be found in [`apps/tutorials/ospTutorialFindospray/`](https://github.com/ospray/ospray/tree/master/apps/ospTutorial/ospTutorialFindospray). To build the tutorial on Linux, build it in a build directory with gcc -std=c99 ../apps/ospTutorial/ospTutorial.c \ -I ../ospray/include -L . -lospray -Wl,-rpath,. -o ospTutorial On Windows build it can be build manually in a "build_directory\\$Configuration" directory with cl ..\..\apps\ospTutorial\ospTutorial.c -I ..\..\ospray\include -I ..\.. ospray.lib Running `ospTutorial` will create two images of two triangles, rendered with the Scientific Visualization renderer with full Ambient Occlusion. The first image `firstFrame.ppm` shows the result after one call to `ospRenderFrame` – jagged edges and noise in the shadow can be seen. Calling `ospRenderFrame` multiple times enables progressive refinement, resulting in antialiased edges and converged shadows, shown after ten frames in the second image `accumulatedFrames.ppm`. ![First frame.][imgTutorial1] ![After accumulating ten frames.][imgTutorial2] ospExamples ----------- Apart from tutorials, `OSPRay` comes with a C++ app called [`ospExamples`](https://github.com/ospray/ospray/tree/master/apps/ospExamples) which is an elaborate easy-to-use tutorial, with a single interface to try various `OSPRay` features. It is aimed at providing users with multiple simple scenes composed of basic geometry types, lights, volumes etc. to get started with OSPRay quickly. `ospExamples` app runs a `GLFWOSPRayWindow` instance that manages instances of the camera, framebuffer, renderer and other OSPRay objects necessary to render an interactive scene. The scene is rendered on a `GLFW` window with an `imgui` GUI controls panel for the user to manipulate the scene at runtime. The application is located in [`apps/ospExamples/`](https://github.com/ospray/ospray/tree/master/apps/ospExamples) directory and can be built with CMake. It can be run from the build directory via: ``` ./ospExamples ``` The command line parameter is optional however. ![`ospExamples` application with default `boxes` scene.][imgOspExamples] ### Scenes Different scenes can be selected from the `scenes` dropdown and each scene corresponds to an instance of a special `detail::Builder` struct. Example builders are located in [`apps/common/ospray_testing/builders/`](https://github.com/ospray/ospray/tree/master/apps/common/ospray_testing/builders). These builders provide a usage guide for the OSPRay scene hierarchy and OSPRay API in the form of `cpp` wrappers. They instantiate and manage objects for the specific scene like `cpp::Geometry`, `cpp::Volume`, `cpp::Light` etc. The `detail::Builder` base struct is mostly responsible for setting up OSPRay `world` and objects common in all scenes (for example lighting and ground plane), which can be conveniently overridden in the derived builders. ### Renderer This app comes with four [renderer] options: `scivis`, `pathtracer`, `ao` and `debug`. The app provides some common rendering controls like `pixelSamples` and other more specific to the renderer type like `aoSamples` for the `scivis` and `ao` renderer or `maxPathLength` for the `pathtracer`. The sun-sky lighting can be used in a sample scene by enabling the `renderSunSky` option of the `pathtracer` renderer. It allows the user to change `turbidity` and `sunDirection`. ![Rendering an evening sky with the `renderSunSky` option.][imgRenderSunSky] ospMPIDistribTutorial --------------------- A minimal working example demonstrating how to use OSPRay for rendering distributed data can be found at [`modules/mpi/tutorials/ospMPIDistribTutorial.c`](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorial.c)^[A C++ version that uses the C++ convenience wrappers of OSPRay's C99 API via [`include/ospray/ospray_cpp.h`](https://github.com/ospray/ospray/blob/master/ospray/include/ospray/ospray_cpp.h) is available at [`modules/mpi/tutorials/ospMPIDistribTutorial.cpp`](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorial.cpp).]. The compilation process via CMake is the similar to [`apps/tutorials/ospTutorialFindospray/`](https://github.com/ospray/ospray/tree/master/apps/ospTutorial/ospTutorialFindospray), with the addition of finding and linking MPI. To build the tutorial on Linux, build it in a build directory with mpicc -std=c99 ../modules/mpi/tutorials/ospMPIDistribTutorial.c \ -I ../ospray/include -L . -lospray -Wl,-rpath,. -o ospMPIDistribTutorial On Windows build it can be build manually in a "build_directory\\$Configuration" directory with cl ..\..\modules\mpi\tutorials\ospMPIDistribTutorial.c -I ..\..\ospray\include -I ..\.. ospray.lib The MPI module does not need to be linked explicitly, as it is loaded as a module at runtime. ![The first frame output by the `ospMPIDistribTutorial` or C++ tutorial with 4 ranks.][imgMPIDistribTutorial1] ![The accumulated frame output by the `ospMPIDistribTutorial` or C++ tutorial with 4 ranks.][imgMPIDistribTutorial2] ospMPIDistribTutorialSpheres and ospMPIDistribTutorialVolume ------------------------------------------------------------ The spheres and volume distributed tutorials are built as part of the MPI tutorials when building OSPRay with the MPI module and tutorials enabled. These tutorials demonstrate using OSPRay to render distributed data sets where each rank owns some subregion of the data, and displaying the output in an interactive window. The domain is distributed in a grid among the processes, each of which will generate a subset of the data corresponding to its subdomain. In `ospMPIDistribTutorialSpheres`, each process generates a set of spheres within its assigned domain. The spheres are colored from dark to light blue, where lighter colors correspond to higher ranks. ![Running `ospMPIDistribTutorialSpheres` on 4 ranks.][imgMPIDistribTutorialSpheres] In `ospMPIDistribTutorialVolume`, each process generates a subbrick of volume data, which is colored by its rank. ![Running `ospMPIDistribTutorialVolume` on 4 ranks.][imgMPIDistribTutorialVolume] ospMPIDistribTutorialPartialRepl -------------------------------- The partially replicated MPI tutorial demonstrates how to use OSPRay's distributed rendering capabilities to render data sets that are partially replicated among the processes. Each pair of ranks generates the same volume brick, allowing them to subdivide the rendering workload between themselves. For example, when run with two ranks, each will generate the same brick and be responsible for rendering half of the image tiles it projects to. When run with four ranks, the pairs of ranks 0,1 and 2,3 will generate the same data and divide the rendering workload for that data among themselves. The image work subdivision happens automatically, based on which ranks specify the same bounding box for their data, as demonstrated in the tutorial. The partially replicated distribution is useful to support load-balanced rendering of data sets that are too large to be fully replicated among the processes, but are small enough to be partially replicated among them. ospMPIDistribTutorialReplicated ------------------------------- The replicated MPI tutorial demonstrates how OSPRay's distributed rendering capabilities can be used to render data sets that are fully replicated among the ranks with advanced illumination effects. In this case, although the processes are run MPI parallel, each rank specifies the exact same data. OSPRay's MPI parallel renderer will detect that the data is replicated in this case and use the same image-parallel rendering algorithms employed in the MPI offload rendering configuration to render the data. This image-parallel rendering algorithm supports all rendering configurations that are used in local rendering, e.g., path tracing, to provide high-quality images. The replicated MPI tutorial supports the same scenes and parameters as the [`ospExamples`][ospExamples] app described above. This mode can be useful when high-quality rendering is desired and it is possible to copy the entire data set on to each rank, or to accelerate loading of a large model by leveraging a parallel file system. RenderKit-ospray-85af292/doc/webtemplate.html000066400000000000000000000044361464752671100212460ustar00rootroot00000000000000 Intel OSPRay$if(select_downloads)$ Download$endif$$if(select_documentation)$ Documentation$endif$$if(select_tutorials)$ Tutorials$endif$$if(select_gallery)$ Gallery$endif$$if(select_related_projects)$ – RelatedProjects$endif$ $if(highlighting-css)$ $endif$ $if(select_index)$ $endif$ $if(toc)$ $endif$
$body$
$if(select_legal)$ $else$ $endif$ RenderKit-ospray-85af292/modules/000077500000000000000000000000001464752671100167435ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/CMakeLists.txt000066400000000000000000000005171464752671100215060ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 add_subdirectory(cpu) if(OSPRAY_MODULE_CPU) get_target_property(OSPRAY_CPU_MODULE_INCLUDE_DIRS ospray_module_cpu INTERFACE_INCLUDE_DIRECTORIES) include_directories_ispc(${OSPRAY_CPU_MODULE_INCLUDE_DIRS}) endif() add_all_subdirectories_except(cpu) RenderKit-ospray-85af292/modules/cpu/000077500000000000000000000000001464752671100175325ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/CMakeLists.txt000066400000000000000000000344231464752671100223000ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 option(OSPRAY_MODULE_CPU "Build the CPU module" ON) mark_as_advanced(OSPRAY_MODULE_CPU) cmake_dependent_option( OSPRAY_MODULE_GPU "Build the GPU module (beta)" OFF EMBREE_SYCL_SUPPORT OFF ) if ((NOT OSPRAY_MODULE_CPU) AND (NOT OSPRAY_MODULE_GPU)) return() endif() # ------------------------------------------------------- # Setup module include directories and source files # ------------------------------------------------------- set(OSPRAY_HOST_SOURCES ${OSPRAY_RESOURCE} ModuleInit.cpp ispc_tasksys.cpp ISPCDevice.h ISPCDevice.cpp common/Data.cpp common/Future.cpp common/Group.cpp common/Instance.cpp common/MotionTransform.cpp common/World.cpp fb/FrameBuffer.cpp fb/LocalFB.cpp fb/SparseFB.cpp fb/FrameOp.cpp fb/TaskError.cpp fb/registration.cpp fb/frame_ops/Blur.cpp fb/frame_ops/ColorConversion.cpp fb/frame_ops/Debug.cpp fb/frame_ops/ToneMapper.cpp fb/frame_ops/Variance.cpp pf/PixelFilter.cpp camera/Camera.cpp camera/PerspectiveCamera.cpp camera/OrthographicCamera.cpp camera/PanoramicCamera.cpp camera/registration.cpp geometry/Geometry.cpp geometry/GeometricModel.cpp geometry/Boxes.cpp geometry/Curves.cpp geometry/Spheres.cpp geometry/Planes.cpp geometry/Mesh.cpp geometry/registration.cpp lights/Light.cpp lights/AmbientLight.cpp lights/DirectionalLight.cpp lights/PointLight.cpp lights/IntensityDistribution.cpp lights/SpotLight.cpp lights/QuadLight.cpp lights/CylinderLight.cpp lights/HDRILight.cpp lights/SunSkyLight.cpp lights/sky_model/sky_model.cpp lights/registration.cpp math/spectrum.h math/Distribution2D.cpp render/LoadBalancer.cpp render/Material.cpp render/Renderer.cpp render/registration.cpp render/debug/DebugRenderer.cpp render/ao/AORenderer.cpp render/scivis/SciVis.cpp render/scivis/SciVisData.cpp render/pathtracer/PathTracer.cpp render/pathtracer/PathTracerData.cpp render/materials/OBJ.cpp render/materials/Principled.cpp render/materials/CarPaint.cpp render/materials/Velvet.cpp render/materials/Metal.cpp render/materials/Alloy.cpp render/materials/ThinGlass.cpp render/materials/Glass.cpp render/materials/MetallicPaint.cpp render/materials/Plastic.cpp render/materials/Luminous.cpp render/materials/Mix.cpp render/bsdfs/MicrofacetAlbedoTables.cpp texture/Texture.cpp texture/Texture2D.cpp texture/registration.cpp ) set(OSPRAY_KERNEL_SOURCES ISPCDevice.ispc common/World.ispc fb/FrameBufferDispatch.ispc fb/LocalFB.ispc fb/SparseFB.ispc fb/frame_ops/Blur.ispc fb/frame_ops/ColorConversion.ispc fb/frame_ops/Debug.ispc fb/frame_ops/ToneMapper.ispc fb/frame_ops/Variance.ispc pf/PixelFilterDispatch.ispc pf/LUTPixelFilter.ispc camera/CameraDispatch.ispc camera/PerspectiveCamera.ispc camera/OrthographicCamera.ispc camera/PanoramicCamera.ispc geometry/GeometryDispatch.ispc geometry/GeometricModel.ispc geometry/Boxes.ispc geometry/Curves.ispc geometry/Spheres.ispc geometry/Planes.ispc geometry/Mesh.ispc lights/LightDispatch.ispc lights/Light.ispc lights/AmbientLight.ispc lights/DirectionalLight.ispc lights/PointLight.ispc lights/SpotLight.ispc lights/QuadLight.ispc lights/CylinderLight.ispc lights/HDRILight.ispc math/Distribution1D.ispc math/Distribution2D.ispc math/spectrum.ispc render/Material.ispc render/MaterialDispatch.ispc render/Renderer.ispc render/util.ispc render/debug/DebugRenderer.ispc render/ao/AORenderer.ispc render/ao/surfaces.ispc render/scivis/SciVis.ispc render/scivis/surfaces.ispc render/scivis/lightAlpha.ispc render/pathtracer/PathTracer.ispc render/pathtracer/PathSampler.ispc render/pathtracer/GeometryLight.ispc render/pathtracer/VirtualLight.ispc render/pathtracer/TransparentShadow.ispc render/pathtracer/ShadowCatcher.ispc render/pathtracer/NextEventEstimation.ispc render/bsdfs/BSDF.ispc render/bsdfs/MicrofacetAlbedoTables.ispc render/materials/OBJ.ispc render/materials/Principled.ispc render/materials/CarPaint.ispc render/materials/Velvet.ispc render/materials/Metal.ispc render/materials/Alloy.ispc render/materials/ThinGlass.ispc render/materials/Glass.ispc render/materials/MetallicPaint.ispc render/materials/Plastic.ispc render/materials/Luminous.ispc render/materials/Mix.ispc texture/TextureDispatch.ispc texture/Texture2D.ispc texture/TextureParam.ispc ) set(OSPRAY_BCKND_ISPC_SOURCES common/DeviceRTImpl_ispc.cpp ) set(OSPRAY_BCKND_SYCL_SOURCES common/DeviceRTImpl_sycl.cpp ) if (OSPRAY_ENABLE_VOLUMES) list(APPEND OSPRAY_HOST_SOURCES geometry/Isosurfaces.cpp texture/TextureVolume.cpp volume/Volume.cpp volume/VolumetricModel.cpp volume/transferFunction/LinearTransferFunction.cpp volume/transferFunction/TransferFunction.cpp volume/transferFunction/registration.cpp ) list(APPEND OSPRAY_KERNEL_SOURCES geometry/Isosurfaces.ispc render/ao/volumes.ispc render/scivis/volumes.ispc render/pathtracer/volumes/VolumeSampler.ispc texture/TextureVolume.ispc volume/Volume.ispc volume/transferFunction/LinearTransferFunction.ispc volume/transferFunction/TransferFunctionDispatch.ispc ) endif() ############################################################## # Build ISPC device ############################################################## ## Windows-specifc ISPC symbol exports ## if (WIN32) file(READ def_header.txt OSPRAY_DEF) file(READ ispc_symbols.txt OSPRAY_ISPC_SYMBOLS_IN) if (OSPRAY_ENABLE_VOLUMES) file(READ ispc_symbols_volume.txt OSPRAY_ISPC_SYMBOLS_VOLUME) list(APPEND OSPRAY_ISPC_SYMBOLS_IN ${OSPRAY_ISPC_SYMBOLS_VOLUME}) endif() list(LENGTH OSPRAY_ISPC_TARGET_LIST NUM_TARGETS) foreach(isa ${OSPRAY_ISPC_TARGET_LIST}) string(REPLACE "-i32x16" "" isa ${isa}) # strip avx512skx-i32x16 if (NUM_TARGETS EQUAL 1) set(isa "") # for single target no suffix endif() # add isa suffix string(REPLACE "," "${isa}" OSPRAY_ISPC_SYMBOLS ${OSPRAY_ISPC_SYMBOLS_IN}) string(APPEND OSPRAY_DEF ${OSPRAY_ISPC_SYMBOLS}) endforeach() file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/ospray_module_cpu.def.in "${OSPRAY_DEF}") # changes .def only if content changed, avoids unnecessary re-linking configure_file(${CMAKE_CURRENT_BINARY_DIR}/ospray_module_cpu.def.in ospray_module_cpu.def COPYONLY) set(OSPRAY_ISPC_DEF ospray_module_cpu.def) endif() ## ISPC Device-specific options ## set(OSPRAY_TILE_SIZE 64 CACHE STRING "Tile size (x,y dimensions)") set_property(CACHE OSPRAY_TILE_SIZE PROPERTY STRINGS 8 16 32 64 128 256 512) mark_as_advanced(OSPRAY_TILE_SIZE) set(OSPRAY_RENDER_TASK_SIZE 8 CACHE STRING "Render task size (x,y dimensions). 8 is the default, -1 indicates to use a SIMD-width render task size determined at runtime. Must be less than OSPRAY_TILE_SIZE.") set_property(CACHE OSPRAY_RENDER_TASK_SIZE PROPERTY STRINGS -1 2 4 8 16 32 64) mark_as_advanced(OSPRAY_RENDER_TASK_SIZE) if (WIN32) set(TILE_STACK_DEFAULT_SIZE 64) elseif (APPLE) set(TILE_STACK_DEFAULT_SIZE 32) else () set(TILE_STACK_DEFAULT_SIZE 128) endif() set(OSPRAY_MAX_STACK_TILE_SIZE ${TILE_STACK_DEFAULT_SIZE} CACHE STRING "Max size for tile to remain allocated on the stack") set_property(CACHE OSPRAY_MAX_STACK_TILE_SIZE PROPERTY STRINGS 8 16 32 64 128 256 512) mark_as_advanced(OSPRAY_MAX_STACK_TILE_SIZE) configure_file(common/OSPConfig.h.in ${PROJECT_BINARY_DIR}/OSPConfig.h) install(FILES ${CMAKE_BINARY_DIR}/OSPConfig.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/SDK COMPONENT devel ) ## Build the module ## if (OSPRAY_MODULE_CPU) include_directories_ispc( ${PROJECT_SOURCE_DIR}/ospray/include ${PROJECT_SOURCE_DIR}/ospray ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} ${RKCOMMON_INCLUDE_DIRS} ${EMBREE_INCLUDE_DIRS} ) add_definitions_ispc( -DOSPRAY_BEGIN_ISPC_NAMESPACE= -DOSPRAY_END_ISPC_NAMESPACE= -DSYCL_EXTERNAL= ) if (OSPRAY_ENABLE_VOLUMES) include_directories_ispc( ${OPENVKL_INCLUDE_DIRS} ) # Keep the NOTFOUND out of the ISPC include dirs list, because CMake will # see the variable ending with NOTFOUND and evaluate it to false and not # pass our include directories if (OPENVKL_CPU_DEVICE_INCLUDE_DIRS) include_directories_ispc( ${OPENVKL_CPU_DEVICE_INCLUDE_DIRS} ) endif() add_definitions_ispc( -DOSPRAY_ENABLE_VOLUMES ) endif() add_library(ospray_module_cpu SHARED ${OSPRAY_HOST_SOURCES} ${OSPRAY_ISPC_DEF} ${OSPRAY_BCKND_ISPC_SOURCES} math/halton.c math/sobol.c # constants exported for ISPC only geometry/Subdivision.cpp ) ispc_target_add_sources(ospray_module_cpu ${OSPRAY_KERNEL_SOURCES} geometry/Subdivision.ispc texture/MipMapGeneration.ispc ) ospray_install_library(ospray_module_cpu lib) target_link_libraries(ospray_module_cpu PUBLIC ospray rkcommon::rkcommon $ ) target_include_directories(ospray_module_cpu PUBLIC $ $ $ $ $ $ # NOTE(jda) - the following includes are missing despite PUBLIC linking $ ####################################################################### $ $ ) target_compile_definitions(ospray_module_cpu PUBLIC TILE_SIZE=${OSPRAY_TILE_SIZE} MAX_TILE_SIZE=${OSPRAY_MAX_STACK_TILE_SIZE} SYCL_EXTERNAL= OSPRAY_GLOBAL= ) if (OSPRAY_ENABLE_VOLUMES) target_link_libraries(ospray_module_cpu PUBLIC $ $ ) target_compile_definitions(ospray_module_cpu PUBLIC OSPRAY_ENABLE_VOLUMES ) endif() endif() if (OSPRAY_MODULE_GPU) if (WIN32) cmake_minimum_required(VERSION 3.25) else() cmake_minimum_required(VERSION 3.20.5) endif() # Have CMake's build infrastructure treat the ISPC files as C++ for SYCL set_source_files_properties(${OSPRAY_KERNEL_SOURCES} ${OSPRAY_VOLUMES_KERNEL_SOURCES} PROPERTIES LANGUAGE CXX) add_library(ospray_module_gpu_kernels OBJECT ${OSPRAY_KERNEL_SOURCES} ) ospray_add_sycl_target(ospray_module_gpu_kernels) target_link_libraries(ospray_module_gpu_kernels PUBLIC ospray rkcommon::rkcommon $ ) target_include_directories(ospray_module_gpu_kernels PUBLIC $ $ $ $ $ $ # NOTE(jda) - the following includes are missing despite PUBLIC linking $ ####################################################################### $ $ ) target_compile_definitions(ospray_module_gpu_kernels PUBLIC TILE_SIZE=${OSPRAY_TILE_SIZE} MAX_TILE_SIZE=${OSPRAY_MAX_STACK_TILE_SIZE} RKCOMMON_NO_SIMD ) if (OSPRAY_COMPILER_NEEDS_X_CPP) target_compile_options(ospray_module_gpu_kernels PRIVATE -x c++) endif() target_compile_options(ospray_module_gpu_kernels PRIVATE -g0 # XXX debug on device broken -Wdouble-promotion ) target_compile_definitions(ospray_module_gpu_kernels PUBLIC OSPRAY_TARGET_SYCL __SYCL_USE_NON_VARIADIC_SPIRV_OCL_PRINTF__ # WA to allow printf of float, see https://github.com/intel/llvm/issues/12880 OSPRAY_BEGIN_ISPC_NAMESPACE=namespace\ ispc{ OSPRAY_END_ISPC_NAMESPACE=} OSPRAY_GLOBAL=static _ALLOW_KEYWORD_MACROS # avoid error when redefining reserved keywords like "export" uniform= varying= unmasked= export= rtcIntersectV=rtcIntersect1 rtcOccludedV=rtcOccluded1 rtcInterpolateV1=rtcInterpolate1 vklComputeSampleV=vklComputeSample vklComputeGradientV=vklComputeGradient vklInitIntervalIteratorV=vklInitIntervalIterator vklIterateIntervalV=vklIterateInterval vklInitHitIteratorV=vklInitHitIterator vklIterateHitV=vklIterateHit programCount=1 programIndex=0 ) if (OSPRAY_ENABLE_VOLUMES) target_link_libraries(ospray_module_gpu_kernels PUBLIC $ $ ) target_compile_definitions(ospray_module_gpu_kernels PUBLIC OSPRAY_ENABLE_VOLUMES ) endif() # Install and export without DESTINATION to turn it into INTERFACE library install(TARGETS ospray_module_gpu_kernels EXPORT ospray_Exports) add_library(ospray_module_gpu SHARED ${OSPRAY_HOST_SOURCES} ${OSPRAY_BCKND_SYCL_SOURCES} ) ispc_target_add_sources(ospray_module_gpu texture/MipMapGeneration.ispc ) target_link_libraries(ospray_module_gpu PUBLIC ospray_module_gpu_kernels ) ospray_install_library(ospray_module_gpu gpu) endif() # ------------------------------------------------------- # Install SDK headers # ------------------------------------------------------- get_subdirectories(SUBDIRS ${CMAKE_CURRENT_LIST_DIR}) foreach(dir . ${SUBDIRS}) install(DIRECTORY ${dir} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/SDK/modules/cpu COMPONENT devel FILES_MATCHING PATTERN *.h PATTERN *.ih ) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/SDK/modules/cpu COMPONENT devel FILES_MATCHING PATTERN *_ispc.h PATTERN CMakeFiles EXCLUDE ) endforeach() ############################################################## # Additional interface targets ############################################################## add_library(ospray_sdk INTERFACE) target_link_libraries(ospray_sdk INTERFACE ospray rkcommon::rkcommon ) ospray_install_target(ospray_sdk devel) RenderKit-ospray-85af292/modules/cpu/ISPCDevice.cpp000066400000000000000000000465641464752671100221330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "ISPCDevice.h" #include "camera/Camera.h" #include "common/Data.h" #include "common/DeviceRTImpl.h" #include "common/Group.h" #include "common/Instance.h" #include "common/Library.h" #include "common/World.h" #include "fb/ImageOp.h" #include "fb/LocalFB.h" #include "geometry/GeometricModel.h" #include "lights/Light.h" #include "render/LoadBalancer.h" #include "render/Material.h" #include "render/Renderer.h" #include "render/RenderingFuture.h" #include "texture/MipMapCache.h" #include "texture/Texture.h" #include "texture/Texture2D.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/VolumetricModel.h" #include "volume/transferFunction/TransferFunction.h" #endif // stl #include #include #include #ifndef OSPRAY_TARGET_SYCL #include "ISPCDevice_ispc.h" #endif namespace ospray { namespace api { using SetParamFcn = void(OSPObject, const char *, const void *); template static void setParamOnObject(OSPObject _obj, const char *p, const T &v) { auto *obj = (ManagedObject *)_obj; obj->setParam(p, v); } #define declare_param_setter(TYPE) \ { \ OSPTypeFor::value, [](OSPObject o, const char *p, const void *v) { \ setParamOnObject(o, p, *(TYPE *)v); \ } \ } #define declare_param_setter_object(TYPE) \ { \ OSPTypeFor::value, [](OSPObject o, const char *p, const void *v) { \ ManagedObject *obj = *(TYPE *)v; \ setParamOnObject(o, p, obj); \ } \ } #define declare_param_setter_string(TYPE) \ { \ OSPTypeFor::value, [](OSPObject o, const char *p, const void *v) { \ const char *str = (const char *)v; \ setParamOnObject(o, p, std::string(str)); \ } \ } static std::map> setParamFcns = { declare_param_setter(Device *), declare_param_setter(void *), declare_param_setter(bool), declare_param_setter_object(ManagedObject *), declare_param_setter_object(Camera *), declare_param_setter_object(Data *), declare_param_setter_object(FrameBuffer *), declare_param_setter_object(Future *), declare_param_setter_object(Geometry *), declare_param_setter_object(GeometricModel *), declare_param_setter_object(Group *), declare_param_setter_object(ImageOp *), declare_param_setter_object(Instance *), declare_param_setter_object(Light *), declare_param_setter_object(Material *), declare_param_setter_object(Renderer *), declare_param_setter_object(Texture *), #ifdef OSPRAY_ENABLE_VOLUMES declare_param_setter_object(TransferFunction *), declare_param_setter_object(Volume *), declare_param_setter_object(VolumetricModel *), #endif declare_param_setter_object(World *), declare_param_setter_string(const char *), declare_param_setter(char *), declare_param_setter(char), declare_param_setter(vec2c), declare_param_setter(vec3c), declare_param_setter(vec4c), declare_param_setter(unsigned char), declare_param_setter(vec2uc), declare_param_setter(vec3uc), declare_param_setter(vec4uc), declare_param_setter(short), declare_param_setter(vec2s), declare_param_setter(vec3s), declare_param_setter(vec4s), declare_param_setter(unsigned short), declare_param_setter(vec2us), declare_param_setter(vec3us), declare_param_setter(vec4us), declare_param_setter(int), declare_param_setter(vec2i), declare_param_setter(vec3i), declare_param_setter(vec4i), declare_param_setter(unsigned int), declare_param_setter(vec2ui), declare_param_setter(vec3ui), declare_param_setter(vec4ui), declare_param_setter(int64_t), declare_param_setter(vec2l), declare_param_setter(vec3l), declare_param_setter(vec4l), declare_param_setter(uint64_t), declare_param_setter(vec2ul), declare_param_setter(vec3ul), declare_param_setter(vec4ul), declare_param_setter(float), declare_param_setter(vec2f), declare_param_setter(vec3f), declare_param_setter(vec4f), declare_param_setter(double), declare_param_setter(vec2d), declare_param_setter(vec3d), declare_param_setter(vec4d), declare_param_setter(box1i), declare_param_setter(box2i), declare_param_setter(box3i), declare_param_setter(box4i), declare_param_setter(box1f), declare_param_setter(box2f), declare_param_setter(box3f), declare_param_setter(box4f), declare_param_setter(linear2f), declare_param_setter(linear3f), declare_param_setter(affine2f), declare_param_setter(affine3f)}; #undef declare_param_setter ISPCDevice::ISPCDevice() : loadBalancer(std::make_shared()) { #if (defined(__APPLE__) || defined(MACOSX) || defined(__MACOSX__)) \ && (defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)) // trigger enabling AVX512, see e.g. https://github.com/ispc/ispc/issues/1854 float vf[16]; float f = ispc::ISPCDevice_dummyCompute(vf); #endif } ISPCDevice::ISPCDevice(std::unique_ptr device) : ISPCDevice() { drtDevice = std::move(device); } ISPCDevice::~ISPCDevice() { try { if (embreeDevice) { rtcReleaseDevice(embreeDevice); } } catch (...) { // silently move on, sometimes a pthread mutex lock fails in Embree } #ifdef OSPRAY_ENABLE_VOLUMES if (vklDevice) { vklReleaseDevice(vklDevice); } #endif } static void embreeErrorFunc(void *, const RTCError code, const char *str) { const std::string msg = std::string("Embree internal error ") + rtcGetErrorString(code) + " : " + str; postStatusMsg() << "#osp: Embree internal error " << msg; OSPError e = (code > RTC_ERROR_UNSUPPORTED_CPU) ? OSP_UNKNOWN_ERROR : (OSPError)code; handleError(e, msg); } #ifdef OSPRAY_ENABLE_VOLUMES static void vklErrorFunc(void *, const VKLError code, const char *str) { postStatusMsg() << "#osp: Open VKL internal error " << code << " : " << str; OSPError e = (code > VKL_UNSUPPORTED_CPU) ? OSP_UNKNOWN_ERROR : (OSPError)code; handleError(e, "Open VKL internal error '" + std::string(str) + "'"); } #endif void ISPCDevice::commit() { Device::commit(); // Check if SYCL context and device have been provided externally void *appSyclCtxNew = getParam("syclContext", nullptr); void *appSyclDeviceNew = getParam("syclDevice", nullptr); if ((appSyclCtxNew && !appSyclDeviceNew) || (!appSyclCtxNew && appSyclDeviceNew)) { handleError(OSP_INVALID_OPERATION, "OSPRay ISPCDevice invalid configuration: if providing a syclContext and syclDevice both must be provided"); return; } // Release all devices if user-provided parameters has changed if ((appSyclCtxNew != appSyclCtx) || (appSyclDeviceNew != appSyclDevice)) { // Release DRT device drtDevice.reset(); // Release Embree device if (embreeDevice) { rtcReleaseDevice(embreeDevice); embreeDevice = nullptr; } #ifdef OSPRAY_ENABLE_VOLUMES // Release VKL device if (vklDevice) { vklReleaseDevice(vklDevice); vklDevice = nullptr; } #endif } // Save user-provided parameters appSyclCtx = appSyclCtxNew; appSyclDevice = appSyclDeviceNew; // We will create run-time device once only if (!drtDevice) { // Create DRT device if (appSyclCtx && appSyclDevice) drtDevice = devicert::make_device_unique(appSyclDevice, appSyclCtx, debugMode); else drtDevice = devicert::make_device_unique(debugMode); } if (!embreeDevice) { #ifdef OSPRAY_TARGET_SYCL embreeDevice = rtcNewSYCLDevice( *static_cast(drtDevice->getSyclContextPtr()), generateEmbreeDeviceCfg(*this).c_str()); rtcSetDeviceSYCLDevice(embreeDevice, *static_cast(drtDevice->getSyclDevicePtr())); #else embreeDevice = rtcNewDevice(generateEmbreeDeviceCfg(*this).c_str()); #endif rtcSetDeviceErrorFunction(embreeDevice, embreeErrorFunc, nullptr); RTCError erc = rtcGetDeviceError(embreeDevice); if (erc != RTC_ERROR_NONE) { postStatusMsg() << "#osp:init: embree internal error: " << rtcGetDeviceLastErrorMessage(embreeDevice); throw std::runtime_error("failed to initialize Embree"); } } #ifdef OSPRAY_ENABLE_VOLUMES if (!vklDevice) { vklInit(); #ifdef OSPRAY_TARGET_SYCL vklDevice = vklNewDevice("gpu"); vklDeviceSetVoidPtr( vklDevice, "syclContext", drtDevice->getSyclContextPtr()); #else int cpu_width = ispc::ISPCDevice_programCount(); switch (cpu_width) { case 4: vklDevice = vklNewDevice("cpu_4"); break; case 8: vklDevice = vklNewDevice("cpu_8"); break; case 16: vklDevice = vklNewDevice("cpu_16"); break; default: vklDevice = vklNewDevice("cpu"); break; } #endif vklDeviceSetErrorCallback(vklDevice, vklErrorFunc, nullptr); vklDeviceSetLogCallback( vklDevice, [](void *, const char *message) { postStatusMsg(OSP_LOG_INFO) << message; }, nullptr); vklDeviceSetInt(vklDevice, "logLevel", logLevel); vklDeviceSetInt(vklDevice, "numThreads", numThreads); vklCommitDevice(vklDevice); } #endif // Create MIP map cache if needed if (!disableMipMapGeneration) mipMapCache = rkcommon::make_unique(); #ifndef OSPRAY_TARGET_SYCL // Output device info string const char *isaNames[] = { "unknown", "SSE2", "SSE4", "AVX", "AVX2", "AVX512SKX", "NEON"}; postStatusMsg(OSP_LOG_INFO) << "Using ISPC device with " << isaNames[ispc::ISPCDevice_isa()] << " instruction set"; #endif } /////////////////////////////////////////////////////////////////////////// // Device Implementation ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// int ISPCDevice::loadModule(const char *name) { return loadLocalModule(name); } /////////////////////////////////////////////////////////////////////////// // OSPRay Data Arrays ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPData ISPCDevice::newSharedData(const void *sharedData, OSPDataType type, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback freeFunction, const void *userPtr) { return (OSPData) new Data( *this, sharedData, type, numItems, byteStride, freeFunction, userPtr); } OSPData ISPCDevice::newData(OSPDataType type, const vec3ul &numItems) { return (OSPData) new Data(*this, type, numItems); } void ISPCDevice::copyData( const OSPData source, OSPData destination, const vec3ul &destinationIndex) { Data *dst = (Data *)destination; dst->copy(*(Data *)source, destinationIndex); } /////////////////////////////////////////////////////////////////////////// // Renderable Objects ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPLight ISPCDevice::newLight(const char *type) { return (OSPLight)Light::createInstance(type, *this); } OSPCamera ISPCDevice::newCamera(const char *type) { return (OSPCamera)Camera::createInstance(type, *this); } OSPGeometry ISPCDevice::newGeometry(const char *type) { return (OSPGeometry)Geometry::createInstance(type, *this); } OSPVolume ISPCDevice::newVolume(const char *type) { #ifdef OSPRAY_ENABLE_VOLUMES return (OSPVolume) new Volume(*this, type); #else (void)type; return (OSPVolume) nullptr; #endif } OSPGeometricModel ISPCDevice::newGeometricModel(OSPGeometry _geom) { auto *geom = (Geometry *)_geom; auto *model = new GeometricModel(*this, geom); return (OSPGeometricModel)model; } OSPVolumetricModel ISPCDevice::newVolumetricModel(OSPVolume _volume) { #ifdef OSPRAY_ENABLE_VOLUMES auto *volume = (Volume *)_volume; auto *model = new VolumetricModel(*this, volume); return (OSPVolumetricModel)model; #else (void)_volume; return (OSPVolumetricModel) nullptr; #endif } /////////////////////////////////////////////////////////////////////////// // Model Meta-Data //////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPMaterial ISPCDevice::newMaterial(const char *material_type) { return (OSPMaterial)Material::createInstance(material_type, *this); } OSPTransferFunction ISPCDevice::newTransferFunction(const char *type) { #ifdef OSPRAY_ENABLE_VOLUMES return (OSPTransferFunction)TransferFunction::createInstance(type, *this); #else (void)type; return (OSPTransferFunction) nullptr; #endif } OSPTexture ISPCDevice::newTexture(const char *type) { return (OSPTexture)Texture::createInstance(type, *this); } /////////////////////////////////////////////////////////////////////////// // Instancing ///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPGroup ISPCDevice::newGroup() { return (OSPGroup) new Group(*this); } OSPInstance ISPCDevice::newInstance(OSPGroup _group) { auto *group = (Group *)_group; auto *instance = new Instance(*this, group); return (OSPInstance)instance; } /////////////////////////////////////////////////////////////////////////// // Top-level Worlds /////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPWorld ISPCDevice::newWorld() { return (OSPWorld) new World(*this); } box3f ISPCDevice::getBounds(OSPObject _obj) { auto *obj = (ManagedObject *)_obj; return obj->getBounds(); } /////////////////////////////////////////////////////////////////////////// // Object + Parameter Lifetime Management ///////////////////////////////// /////////////////////////////////////////////////////////////////////////// void ISPCDevice::setObjectParam( OSPObject object, const char *name, OSPDataType type, const void *mem) { if (type == OSP_UNKNOWN) throw std::runtime_error("cannot set OSP_UNKNOWN parameter type"); if (type == OSP_BYTE || type == OSP_RAW) { setParamOnObject(object, name, *(const byte_t *)mem); return; } setParamFcns[type](object, name, mem); } void ISPCDevice::removeObjectParam(OSPObject _object, const char *name) { ManagedObject *object = (ManagedObject *)_object; ManagedObject *existing = object->getParamObject(name); if (existing) existing->refDec(); object->removeParam(name); } void ISPCDevice::commit(OSPObject _object) { ManagedObject *object = (ManagedObject *)_object; object->commit(); object->checkUnused(); object->resetAllParamQueryStatus(); } void ISPCDevice::release(OSPObject _obj) { ManagedObject *obj = (ManagedObject *)_obj; obj->refDec(); } void ISPCDevice::retain(OSPObject _obj) { ManagedObject *obj = (ManagedObject *)_obj; obj->refInc(); } /////////////////////////////////////////////////////////////////////////// // FrameBuffer Manipulation /////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPFrameBuffer ISPCDevice::frameBufferCreate( const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) { FrameBuffer::ColorBufferFormat colorBufferFormat = mode; FrameBuffer *fb = new LocalFrameBuffer(*this, size, colorBufferFormat, channels); return (OSPFrameBuffer)fb; } OSPImageOperation ISPCDevice::newImageOp(const char *type) { ospray::ImageOp *ret = ImageOp::createImageOp(type, getDRTDevice()); return (OSPImageOperation)ret; } const void *ISPCDevice::frameBufferMap( OSPFrameBuffer _fb, OSPFrameBufferChannel channel) { FrameBuffer *fb = (FrameBuffer *)_fb; return fb->mapBuffer(channel); } void ISPCDevice::frameBufferUnmap(const void *mapped, OSPFrameBuffer _fb) { FrameBuffer *fb = (FrameBuffer *)_fb; fb->unmap(mapped); } float ISPCDevice::getVariance(OSPFrameBuffer _fb) { FrameBuffer *fb = (FrameBuffer *)_fb; return fb->getVariance(); } void ISPCDevice::resetAccumulation(OSPFrameBuffer _fb) { FrameBuffer *fb = (FrameBuffer *)_fb; fb->clear(); } /////////////////////////////////////////////////////////////////////////// // Frame Rendering //////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPRenderer ISPCDevice::newRenderer(const char *type) { return (OSPRenderer)Renderer::createInstance(type, *this); } OSPFuture ISPCDevice::renderFrame(OSPFrameBuffer _fb, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world) { FrameBuffer *fb = (FrameBuffer *)_fb; Renderer *renderer = (Renderer *)_renderer; Camera *camera = (Camera *)_camera; World *world = (World *)_world; // Increase reference counters so the passed objects will not be released // during frame rendering fb->refInc(); renderer->refInc(); camera->refInc(); world->refInc(); // Schedule frame rendering std::pair events = loadBalancer->renderFrame(fb, renderer, camera, world); // Schedule reference counters decrease to be done after the rendering devicert::AsyncEvent event = getDRTDevice().launchHostTask([=]() { fb->refDec(); renderer->refDec(); camera->refDec(); world->refDec(); }); // Return rendering future object return (OSPFuture) new RenderingFuture( fb, events.first, events.second, event); } int ISPCDevice::isReady(OSPFuture _task, OSPSyncEvent event) { auto *task = (Future *)_task; return task->isFinished(event); } void ISPCDevice::wait(OSPFuture _task, OSPSyncEvent event) { auto *task = (Future *)_task; task->wait(event); } void ISPCDevice::cancel(OSPFuture _task) { auto *task = (Future *)_task; return task->cancel(); } float ISPCDevice::getProgress(OSPFuture _task) { auto *task = (Future *)_task; return task->getProgress(); } float ISPCDevice::getTaskDuration(OSPFuture _task) { auto *task = (Future *)_task; return task->getTaskDuration(); } OSPPickResult ISPCDevice::pick(OSPFrameBuffer _fb, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world, const vec2f &screenPos) { FrameBuffer *fb = (FrameBuffer *)_fb; Renderer *renderer = (Renderer *)_renderer; Camera *camera = (Camera *)_camera; World *world = (World *)_world; return renderer->pick(fb, camera, world, screenPos); } #ifdef OSPRAY_TARGET_SYCL sycl::nd_range<1> ISPCDevice::computeDispatchRange( const size_t globalSize, const size_t workgroupSize) const { // roundedRange global size must be at least workgroupSize const size_t roundedRange = std::max(size_t(1), (globalSize + workgroupSize - 1) / workgroupSize) * workgroupSize; return sycl::nd_range<1>(roundedRange, workgroupSize); } #endif } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/cpu/ISPCDevice.h000066400000000000000000000130071464752671100215620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "Device.h" // device run-time #include "DeviceRT.h" // embree #include "common/Embree.h" #ifdef OSPRAY_ENABLE_VOLUMES // openvkl #include "openvkl/openvkl.h" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.h" #endif /*! \file ISPCDevice.h Implements the "local" device for local rendering */ #ifdef OSPRAY_TARGET_SYCL namespace ispc { int ISPCDevice_programCount(); int ISPCDevice_isa(); } // namespace ispc #endif namespace ospray { struct LocalTiledLoadBalancer; struct MipMapCache; namespace api { struct OSPRAY_SDK_INTERFACE ISPCDevice : public Device { ISPCDevice(); ISPCDevice(std::unique_ptr device); virtual ~ISPCDevice() override; ///////////////////////////////////////////////////////////////////////// // ManagedObject Implementation ///////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// void commit() override; ///////////////////////////////////////////////////////////////////////// // Device Implementation //////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// int loadModule(const char *name) override; // OSPRay Data Arrays /////////////////////////////////////////////////// OSPData newSharedData(const void *sharedData, OSPDataType, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback, const void *userPtr) override; OSPData newData(OSPDataType, const vec3ul &numItems) override; void copyData(const OSPData source, OSPData destination, const vec3ul &destinationIndex) override; // Renderable Objects /////////////////////////////////////////////////// OSPLight newLight(const char *type) override; OSPCamera newCamera(const char *type) override; OSPGeometry newGeometry(const char *type) override; OSPVolume newVolume(const char *type) override; OSPGeometricModel newGeometricModel(OSPGeometry geom) override; OSPVolumetricModel newVolumetricModel(OSPVolume volume) override; // Model Meta-Data ////////////////////////////////////////////////////// OSPMaterial newMaterial(const char *material_type) override; OSPTransferFunction newTransferFunction(const char *type) override; OSPTexture newTexture(const char *type) override; // Instancing /////////////////////////////////////////////////////////// OSPGroup newGroup() override; OSPInstance newInstance(OSPGroup group) override; // Top-level Worlds ///////////////////////////////////////////////////// OSPWorld newWorld() override; box3f getBounds(OSPObject) override; // Object + Parameter Lifetime Management /////////////////////////////// void setObjectParam(OSPObject object, const char *name, OSPDataType type, const void *mem) override; void removeObjectParam(OSPObject object, const char *name) override; void commit(OSPObject object) override; void release(OSPObject _obj) override; void retain(OSPObject _obj) override; // FrameBuffer Manipulation ///////////////////////////////////////////// OSPFrameBuffer frameBufferCreate(const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) override; OSPImageOperation newImageOp(const char *type) override; const void *frameBufferMap( OSPFrameBuffer fb, const OSPFrameBufferChannel) override; void frameBufferUnmap(const void *mapped, OSPFrameBuffer fb) override; float getVariance(OSPFrameBuffer) override; void resetAccumulation(OSPFrameBuffer _fb) override; // Frame Rendering ////////////////////////////////////////////////////// OSPRenderer newRenderer(const char *type) override; OSPFuture renderFrame( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld) override; int isReady(OSPFuture, OSPSyncEvent) override; void wait(OSPFuture, OSPSyncEvent) override; void cancel(OSPFuture) override; float getProgress(OSPFuture) override; float getTaskDuration(OSPFuture) override; OSPPickResult pick( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, const vec2f &) override; std::shared_ptr loadBalancer; RTCDevice getEmbreeDevice() { return embreeDevice; } #ifdef OSPRAY_ENABLE_VOLUMES VKLDevice getVklDevice() { return vklDevice; } #endif inline devicert::Device &getDRTDevice() { return *drtDevice; } #ifdef OSPRAY_TARGET_SYCL /* Compute the rounded dispatch global size for the given work group size. * SYCL requires that globalSize % workgroupSize == 0, this function will * round up globalSize and return nd_range(roundedSize, workgroupSize). * The kernel being launched must discard tasks that are out of bounds * bounds due to this rounding */ sycl::nd_range<1> computeDispatchRange( const size_t globalSize, const size_t workgroupSize) const; #endif inline MipMapCache &getMipMapCache() { return *mipMapCache; } private: std::unique_ptr drtDevice; RTCDevice embreeDevice = nullptr; #ifdef OSPRAY_ENABLE_VOLUMES VKLDevice vklDevice = nullptr; #endif // External SYCL context and device void *appSyclCtx{nullptr}; void *appSyclDevice{nullptr}; // Device-wide MIP map cache is needed because the same texture data objects // (and thus generated MIP maps) can be shared among many textures std::unique_ptr mipMapCache; }; } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/cpu/ISPCDevice.ispc000066400000000000000000000017501464752671100222730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL int ISPCDevice_programCount() { // TODO: This should query the GPU width for ISPC, // But for SYCL we're in a scalar context, so just 1 program wide return 1; } int ISPCDevice_isa() { // TODO: GPU ISA/width detection // Not relevant for SYCL return 0; } #else export uniform int ISPCDevice_programCount() { return programCount; } export uniform int ISPCDevice_isa() { #if defined(ISPC_TARGET_SSE2) return 1; #elif defined(ISPC_TARGET_SSE4) return 2; #elif defined(ISPC_TARGET_AVX) return 3; #elif defined(ISPC_TARGET_AVX2) return 4; #elif defined(ISPC_TARGET_AVX512SKX) return 5; #elif defined(ISPC_TARGET_NEON) return 6; #else return 0; #endif } export uniform float ISPCDevice_dummyCompute(const float *uniform fp) { const float f = *((const varying float *uniform)fp); return reduce_add(f * f); } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/ISPCDeviceObject.h000066400000000000000000000012611464752671100227100ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "ISPCDevice.h" #include "common/Managed.h" namespace ospray { struct OSPRAY_SDK_INTERFACE ISPCDeviceObject : public ManagedObject { ISPCDeviceObject(api::ISPCDevice &device) : ispcDevice(&device) {} inline api::ISPCDevice &getISPCDevice() const { return *ispcDevice; } template const Ref> getParamDataT( const char *name, bool required = false, bool promoteScalar = false); private: // Ref ispcDevice; TODO: const problem api::ISPCDevice *ispcDevice{nullptr}; }; } // namespace osprayRenderKit-ospray-85af292/modules/cpu/ModuleInit.cpp000066400000000000000000000026151464752671100223130ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // We don't want an instance of ObjectFactory static table in this library // so we have to include it with import define so the table will be imported // from 'ospray' library #define OBJECTFACTORY_IMPORT #include "common/ObjectFactory.h" #include "ISPCDevice.h" #include "OSPCommon.h" #include "camera/registration.h" #include "fb/registration.h" #include "geometry/registration.h" #include "lights/registration.h" #include "render/registration.h" #include "texture/registration.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/transferFunction/registration.h" #endif using namespace ospray; extern "C" OSPError OSPRAY_DLLEXPORT #ifdef OSPRAY_TARGET_SYCL ospray_module_init_gpu #else ospray_module_init_cpu #endif (int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/) { auto status = moduleVersionCheck(versionMajor, versionMinor); if (status == OSP_NO_ERROR) { #ifdef OSPRAY_TARGET_SYCL api::Device::registerType("gpu"); #else api::Device::registerType("cpu"); #endif registerAllCameras(); registerAllImageOps(); registerAllGeometries(); registerAllLights(); registerAllMaterials(); registerAllRenderers(); registerAllTextures(); #ifdef OSPRAY_ENABLE_VOLUMES registerAllTransferFunctions(); #endif } return status; } RenderKit-ospray-85af292/modules/cpu/camera/000077500000000000000000000000001464752671100207625ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/camera/Camera.cpp000066400000000000000000000073371464752671100226700ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Camera.h" namespace ospray { Camera::Camera(api::ISPCDevice &device, const FeatureFlagsOther featureFlags) : AddStructShared(device.getDRTDevice(), device), featureFlags(featureFlags) { managedObjectType = OSP_CAMERA; } Camera::~Camera() { if (embreeGeometry) { rtcReleaseGeometry(embreeGeometry); rtcReleaseScene(embreeScene); } } std::string Camera::toString() const { return "ospray::Camera"; } box3f Camera::projectBox(const box3f &) const { return box3f(vec3f(0.f), vec3f(1.f)); } void Camera::commit() { motionTransform.readParams(*this); // "parse" the general expected parameters pos = getParam("position", vec3f(0.f)); dir = getParam("direction", vec3f(0.f, 0.f, 1.f)); up = getParam("up", vec3f(0.f, 1.f, 0.f)); nearClip = std::max(getParam("nearClip", 1e-6f), 0.f); imageStart = getParam("imageStart", vec2f(0.f)); imageEnd = getParam("imageEnd", vec2f(1.f)); shutter = getParam("shutter", range1f(0.5f, 0.5f)); clamp(shutter.lower); 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()); if (motionTransform.motionBlur || motionTransform.quaternion) { // create dummy RTCGeometry for transform interpolation or conversion if (!embreeGeometry) { embreeGeometry = rtcNewGeometry( getISPCDevice().getEmbreeDevice(), RTC_GEOMETRY_TYPE_INSTANCE); embreeScene = rtcNewScene(getISPCDevice().getEmbreeDevice()); rtcAttachGeometryByID(embreeScene, embreeGeometry, 0); } motionTransform.setEmbreeTransform(embreeGeometry); if (shutter.lower == shutter.upper || !motionTransform.motionBlur) { // directly interpolate to single shutter time rtcGetGeometryTransformFromScene(embreeScene, 0, shutter.lower, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &motionTransform.transform); motionTransform.motionBlur = false; } } if (!motionTransform.motionBlur) { if (embreeGeometry) { rtcReleaseGeometry(embreeGeometry); embreeGeometry = nullptr; rtcReleaseScene(embreeScene); embreeScene = 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); } getSh()->nearClip = nearClip; getSh()->subImage.lower = imageStart; getSh()->subImage.upper = imageEnd; getSh()->shutter = shutter; getSh()->motionBlur = motionTransform.motionBlur; getSh()->scene = embreeScene; getSh()->globalShutter = shutterType == OSP_SHUTTER_GLOBAL; getSh()->rollingShutterHorizontal = (shutterType == OSP_SHUTTER_ROLLING_RIGHT || shutterType == OSP_SHUTTER_ROLLING_LEFT); getSh()->rollingShutterDuration = rollingShutterDuration; getSh()->needTimeSample = shutterType == OSP_SHUTTER_GLOBAL ? shutter.size() : rollingShutterDuration; getSh()->needLensSample = false; if (motionTransform.motionBlur) featureFlags |= FFO_CAMERA_MOTION_BLUR; else featureFlags = (FeatureFlagsOther)(featureFlags & ~FFO_CAMERA_MOTION_BLUR); } OSPTYPEFOR_DEFINITION(Camera *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/Camera.h000066400000000000000000000042201464752671100223210ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDeviceObject.h" #include "common/FeatureFlagsEnum.h" #include "common/MotionTransform.h" #include "common/ObjectFactory.h" #include "common/StructShared.h" // ispc shared #include "CameraShared.h" 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 AddStructShared, public ObjectFactory { Camera(api::ISPCDevice &device, const FeatureFlagsOther featureFlags); ~Camera() override; std::string toString() const override; void commit() override; // Project the bounding box to the screen // The projected box will be returned in normalized [0, 1] coordinates in // the framebuffer, the z coordinate will store the min and max depth, in // box.lower, box.upper respectively // Assume no motion blur nor depth of field (true for SciVis) virtual box3f projectBox(const box3f &b) const; FeatureFlags getFeatureFlags() const; // Data members // // if motionBlur in local camera space; otherwise in world-space: vec3f pos{0.f, 0.f, 0.f}; // position of the camera vec3f dir{0.f, 0.f, 1.f}; // main direction of the camera vec3f up{0.f, 1.f, 0.f}; // up direction of the camera float nearClip{1e-6f}; // near clipping distance // definition of the image region, may even be outside of [0..1]^2 // to simulate sensor shift vec2f imageStart{0.f, 0.f}; // lower left corner vec2f imageEnd{1.f, 1.f}; // 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}; private: RTCGeometry embreeGeometry{nullptr}; RTCScene embreeScene{nullptr}; MotionTransform motionTransform; FeatureFlagsOther featureFlags{FFO_NONE}; }; OSPTYPEFOR_SPECIALIZATION(Camera *, OSP_CAMERA); inline FeatureFlags Camera::getFeatureFlags() const { FeatureFlags ff; ff.other = featureFlags; return ff; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/Camera.ih000066400000000000000000000022051464752671100224730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // camera.ih Defines the abstract base class of an ISPC-side camera #pragma once #include "common/Ray.ih" #include "common/RayCone.ih" #include "rkcommon/math/box.ih" // c++ shared #include "CameraShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE struct FeatureFlagsHandler; // Specifies the input parameters (time, screen, and lens // samples) required for 'initRay' to generate a primary ray struct CameraSample { vec2f screen; // normalized screen sample, in [0..1] vec2f lens; float time; vec2f pixel_center; }; 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 vec2f &screen, float time) { 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)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/CameraDispatch.ih000066400000000000000000000005761464752671100241640ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void Camera_dispatch_initRay(const Camera *uniform self, varying Ray &ray, varying RayCone &, const varying CameraSample &sample, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/CameraDispatch.ispc000066400000000000000000000024221464752671100245120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Camera.ih" #include "CameraDispatch.ih" #include "OrthographicCamera.ih" #include "PanoramicCamera.ih" #include "PerspectiveCamera.ih" #include "common/FeatureFlagsEnum.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void Camera_dispatch_initRay(const Camera *uniform self, varying Ray &ray, varying RayCone &rayCone, const varying CameraSample &sample, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->type == CAMERA_TYPE_PERSPECTIVE) && (ffo & FFO_CAMERA_PERSPECTIVE)) { if (self->motionBlur && (ffo & FFO_CAMERA_MOTION_BLUR)) PerspectiveCamera_initRayMB(self, ray, rayCone, sample, ffh); else PerspectiveCamera_initRay(self, ray, rayCone, sample, ffh); } else if ((self->type == CAMERA_TYPE_ORTHOGRAPHIC) && (ffo & FFO_CAMERA_ORTHOGRAPHIC)) { OrthographicCamera_initRay(self, ray, rayCone, sample, ffh); } else if ((self->type == CAMERA_TYPE_PANORAMIC) && (ffo & FFO_CAMERA_PANORAMIC)) { PanoramicCamera_initRay(self, ray, rayCone, sample, ffh); } else { #ifndef OSPRAY_TARGET_SYCL self->initRay(self, ray, rayCone, sample); #endif } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/CameraShared.h000066400000000000000000000033541464752671100234570ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *Camera_initRay; #else struct Camera; struct CameraSample; struct Ray; struct RayCone; // Fct pointer type for 'virtual' method that sets a pixel, // generated ray.dir must be normalized to ensure ray.t is world-space distance // generated rayCone is in normalized camera coordinates for y (height) typedef void (*Camera_initRay)(const Camera *uniform, varying Ray &ray, varying RayCone &rayCone, const varying CameraSample &sample); #endif enum CameraType { CAMERA_TYPE_PERSPECTIVE, CAMERA_TYPE_ORTHOGRAPHIC, CAMERA_TYPE_PANORAMIC, CAMERA_TYPE_UNKNOWN, }; struct Camera { CameraType type; Camera_initRay initRay; // the 'virtual' initRay() method 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 motionBlur; // for the camera itself only, not in general bool needLensSample; bool needTimeSample; bool rollingShutterHorizontal; float rollingShutterDuration; RTCScene scene; // only to call rtcGetGeometryTransformFromScene #ifdef __cplusplus Camera() : type(CAMERA_TYPE_UNKNOWN), initRay(nullptr), nearClip(1e-6f), subImage(0.f), shutter(0.f), globalShutter(false), motionBlur(false), needLensSample(false), needTimeSample(false), rollingShutterHorizontal(false), rollingShutterDuration(0.f), scene(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/camera/OrthographicCamera.cpp000066400000000000000000000061241464752671100252330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "OrthographicCamera.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "camera/OrthographicCamera_ispc.h" #endif namespace ospray { OrthographicCamera::OrthographicCamera(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_CAMERA_ORTHOGRAPHIC) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.initRay = reinterpret_cast( ispc::OrthographicCamera_initRay_addr()); #endif } std::string OrthographicCamera::toString() const { return "ospray::OrthographicCamera"; } void OrthographicCamera::commit() { Camera::commit(); height = getParam("height", 1.f); aspect = getParam("aspect", 1.f); vec2f size = height; size.x *= aspect; if (getSh()->super.motionBlur) { getSh()->dir = dir; getSh()->du_size = vec3f(size.x, size.y, 1.0f); getSh()->dv_up = up; getSh()->org = pos; } else { getSh()->dir = normalize(dir); getSh()->du_size = normalize(cross(getSh()->dir, up)); getSh()->dv_up = cross(getSh()->du_size, getSh()->dir) * size.y; getSh()->du_size = getSh()->du_size * size.x; getSh()->org = pos - 0.5f * getSh()->du_size - 0.5f * getSh()->dv_up; // shift } getSh()->height = height; } box3f OrthographicCamera::projectBox(const box3f &b) const { box3f projection; // normalize to image plane size const vec3f dun = getSh()->du_size / dot(getSh()->du_size, getSh()->du_size); const vec3f dvn = getSh()->dv_up / dot(getSh()->dv_up, getSh()->dv_up); vec3f projectedPt(-1.f, -1.f, 1e20f); for (uint32_t i = 0; i < 8; ++i) { // Get the point we should be projecting vec3f p; switch (i) { case 0: p = b.lower; break; case 1: p.x = b.upper.x; p.y = b.lower.y; p.z = b.lower.z; break; case 2: p.x = b.upper.x; p.y = b.upper.y; p.z = b.lower.z; break; case 3: p.x = b.lower.x; p.y = b.upper.y; p.z = b.lower.z; break; case 4: p.x = b.lower.x; p.y = b.lower.y; p.z = b.upper.z; break; case 5: p.x = b.upper.x; p.y = b.lower.y; p.z = b.upper.z; break; case 6: p = b.upper; break; case 7: p.x = b.lower.x; p.y = b.upper.y; p.z = b.upper.z; break; } // Project the point on to the film plane const float depth = dot(p - getSh()->org, getSh()->dir); const vec3f screenPt = p - depth * getSh()->dir; const vec3f screenDir = screenPt - getSh()->org; projectedPt.x = dot(screenDir, dun); projectedPt.y = dot(screenDir, dvn); projectedPt.z = depth; projection.lower.x = min(projectedPt.x, projection.lower.x); projection.lower.y = min(projectedPt.y, projection.lower.y); projection.lower.z = min(projectedPt.z, projection.lower.z); projection.upper.x = max(projectedPt.x, projection.upper.x); projection.upper.y = max(projectedPt.y, projection.upper.y); projection.upper.z = max(projectedPt.z, projection.upper.z); } return projection; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/OrthographicCamera.h000066400000000000000000000021041464752671100246720ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "camera/Camera.h" // ispc shared #include "OrthographicCameraShared.h" namespace ospray { // The Orthographic Camera ("orthographic") // // Implements a straightforward orthographic camera for orthographic // projections, without support for Depth of Field // // A simple orthographic camera. This camera type is loaded by passing // the type string "orthographic" to ospNewCamera // // The functionality for a orthographic camera is implemented via the // ospray::OrthographicCamera class. struct OSPRAY_SDK_INTERFACE OrthographicCamera : public AddStructShared { OrthographicCamera(api::ISPCDevice &device); ~OrthographicCamera() override = default; virtual std::string toString() const override; virtual void commit() override; box3f projectBox(const box3f &b) const override; // Data members // float height{ 1.f}; // size of the camera's image plane in y, in world coordinates float aspect{1.f}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/OrthographicCamera.ih000066400000000000000000000005361464752671100250520ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "camera/Camera.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void OrthographicCamera_initRay(const Camera *uniform, varying Ray &, varying RayCone &, const varying CameraSample &, const uniform FeatureFlagsHandler &); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/OrthographicCamera.ispc000066400000000000000000000040251464752671100254050ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Camera.ih" #include "common/Embree.h" #include "common/FeatureFlags.ih" // c++ shared #include "OrthographicCameraShared.h" #include "rkcommon/math/AffineSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void OrthographicCamera_initRay(const Camera *uniform _self, varying Ray &ray, varying RayCone &rayCone, const varying CameraSample &sample, const uniform FeatureFlagsHandler &ffh) { const OrthographicCamera *uniform self = (const OrthographicCamera *uniform)_self; const vec2f screen = Camera_subRegion(_self, sample.screen); const float time = Camera_shutterTime(_self, screen, sample.time); vec3f dir; vec3f org; const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if (self->super.motionBlur && (ffo & FFO_CAMERA_MOTION_BLUR)) { AffineSpace3f xfm; rtcGetGeometryTransformFromScene( self->super.scene, 0, time, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm); // we cannot just transform the final org & dir, because interpolated // transforms can scale (even if original transforms are without scale) dir = normalize(xfmVector(xfm, self->dir)); const vec3f up = xfmVector(xfm, self->dv_up); org = xfmPoint(xfm, self->org); const vec3f du = normalize(cross(dir, up)); const vec3f dv = cross(du, dir); const float x = (screen.x - 0.5f) * self->du_size.x; const float y = (screen.y - 0.5f) * self->du_size.y; org = org + x * du + y * dv; } else { dir = self->dir; org = self->org + screen.x * self->du_size + screen.y * self->dv_up; } setRay(ray, org, dir, self->super.nearClip, inf, time); const uniform vec2f subImageSize = box_size(self->super.subImage); rayCone.width = self->height * abs(subImageSize.y); rayCone.dwdt = 0.f; } // Exports (called from C++) ////////////////////////////////////////////////// export void *uniform OrthographicCamera_initRay_addr() { return (void *uniform)OrthographicCamera_initRay; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/OrthographicCameraShared.h000066400000000000000000000014221464752671100260230ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "CameraShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct OrthographicCamera { Camera super; vec3f dir; // below are essentially unions: 1. if no motionBlur; 2. if motionBlur vec3f org; // lower left position of the camera image plane; // origin of camera vec3f du_size; // sensor size (in x and y) vec3f dv_up; // up vector with magnitude equal to the imagePlane size in y float height; // size of the imagePlane in y #ifdef __cplusplus OrthographicCamera() : dir(0.f), org(0.f), du_size(0.f), dv_up(0.f), height(1.f) { super.type = CAMERA_TYPE_ORTHOGRAPHIC; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/camera/PanoramicCamera.cpp000066400000000000000000000025671464752671100245220ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "PanoramicCamera.h" // ispc exports #ifndef OSPRAY_TARGET_SYCL #include "camera/PanoramicCamera_ispc.h" #else namespace ispc { void *PanoramicCamera_initRay_addr(); } #endif namespace ospray { PanoramicCamera::PanoramicCamera(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_CAMERA_PANORAMIC) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.initRay = reinterpret_cast( ispc::PanoramicCamera_initRay_addr()); #endif } std::string PanoramicCamera::toString() const { return "ospray::PanoramicCamera"; } void PanoramicCamera::commit() { Camera::commit(); getSh()->org = pos; if (getSh()->super.motionBlur) { getSh()->frame.vz = -dir; getSh()->frame.vy = up; } else { getSh()->frame.vz = -normalize(dir); getSh()->frame.vx = normalize(cross(up, getSh()->frame.vz)); getSh()->frame.vy = cross(getSh()->frame.vz, getSh()->frame.vx); } getSh()->stereoMode = (OSPStereoMode)getParam("stereoMode", OSP_STEREO_NONE); getSh()->ipd_offset = 0.5f * getParam("interpupillaryDistance", 0.0635f); // flip offset to have left eye at top (image coord origin at lower left) if (getSh()->stereoMode == OSP_STEREO_TOP_BOTTOM) getSh()->ipd_offset = -getSh()->ipd_offset; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/PanoramicCamera.h000066400000000000000000000010621464752671100241540ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "camera/Camera.h" // ispc shared #include "PanoramicCameraShared.h" namespace ospray { // Implements a panoramic camera with latitude/longitude mapping struct OSPRAY_SDK_INTERFACE PanoramicCamera : public AddStructShared { PanoramicCamera(api::ISPCDevice &device); virtual ~PanoramicCamera() override = default; virtual std::string toString() const override; virtual void commit() override; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/PanoramicCamera.ih000066400000000000000000000005321464752671100243260ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "camera/Camera.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void PanoramicCamera_initRay(const Camera *uniform, varying Ray &, varying RayCone &, const varying CameraSample &, const uniform FeatureFlagsHandler &); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/PanoramicCamera.ispc000066400000000000000000000061301464752671100246640ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Camera.ih" #include "common/Embree.h" #include "common/FeatureFlags.ih" #include "math/sampling.ih" #include "ospray/OSPEnums.h" // c++ shared #include "PanoramicCameraShared.h" #include "rkcommon/math/AffineSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void PanoramicCamera_initRay(const Camera *uniform _self, varying Ray &ray, varying RayCone &rayCone, const varying CameraSample &sample, const uniform FeatureFlagsHandler &ffh) { const PanoramicCamera *uniform self = (const PanoramicCamera *uniform)_self; vec2f screen = sample.screen; float pixel_center = self->stereoMode == OSP_STEREO_SIDE_BY_SIDE ? sample.pixel_center.x : sample.pixel_center.y; varying float *uniform split = self->stereoMode == OSP_STEREO_SIDE_BY_SIDE ? &screen.x : &screen.y; float offset = 0.f; switch (self->stereoMode) { case OSP_STEREO_LEFT: offset = -self->ipd_offset; break; case OSP_STEREO_RIGHT: offset = self->ipd_offset; break; case OSP_STEREO_SIDE_BY_SIDE: case OSP_STEREO_TOP_BOTTOM: *split *= 2.f; if (pixel_center < 0.5f) { offset = -self->ipd_offset; } else { offset = self->ipd_offset; *split -= 1.f; } break; } screen = Camera_subRegion(_self, screen); const float phi = (float)two_pi * screen.x; const float theta = (float)pi * screen.y; float sinTheta, cosTheta; sincos(theta, &sinTheta, &cosTheta); const vec3f localDir = cartesian(phi, sinTheta, cosTheta); const float time = Camera_shutterTime(_self, screen, sample.time); // transform to camera- and then to world-space vec3f dir; vec3f org; const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if (self->super.motionBlur && (ffo & FFO_CAMERA_MOTION_BLUR)) { AffineSpace3f xfm; rtcGetGeometryTransformFromScene( self->super.scene, 0, time, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm); // we cannot just transform the final org & dir, because interpolated // transforms can scale (even if original transforms are without scale) linear3f frameMB; frameMB.vz = normalize(xfmVector(xfm, self->frame.vz)); frameMB.vx = normalize(cross(xfmVector(xfm, self->frame.vy), frameMB.vz)); frameMB.vy = cross(frameMB.vz, frameMB.vx); dir = frameMB * make_vec3f(-localDir.y, -localDir.z, localDir.x); org = xfmPoint(xfm, self->org) + offset * cross(dir, frameMB.vy); } else { dir = self->frame * make_vec3f(-localDir.y, -localDir.z, localDir.x); org = self->org + offset * cross(dir, self->frame.vy); } setRay(ray, org, dir, self->super.nearClip, inf, time); rayCone.width = 0.f; rayCone.dwdt = pi * sinTheta; const uniform vec2f subImageSize = box_size(self->super.subImage); rayCone.dwdt *= abs(subImageSize.y); if (self->stereoMode == OSP_STEREO_TOP_BOTTOM) rayCone.dwdt *= 2.f; } // Exports (called from C++) ////////////////////////////////////////////////// export void *uniform PanoramicCamera_initRay_addr() { return (void *uniform)PanoramicCamera_initRay; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/PanoramicCameraShared.h000066400000000000000000000011361464752671100253050ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "CameraShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct PanoramicCamera { Camera super; vec3f org; linear3f frame; // union: precomputed frame; or (xxx, up, -dir) if motion blur int stereoMode; float ipd_offset; // half of the interpupillary distance #ifdef __cplusplus PanoramicCamera() : org(0.f), frame(one), stereoMode(OSP_STEREO_NONE), ipd_offset(0.f) { super.type = CAMERA_TYPE_PANORAMIC; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/camera/PerspectiveCamera.cpp000066400000000000000000000142441464752671100250750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "PerspectiveCamera.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "camera/PerspectiveCamera_ispc.h" #endif namespace ospray { PerspectiveCamera::PerspectiveCamera(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_CAMERA_PERSPECTIVE) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.initRay = reinterpret_cast( ispc::PerspectiveCamera_initRay_addr()); #endif } std::string PerspectiveCamera::toString() const { return "ospray::PerspectiveCamera"; } void PerspectiveCamera::commit() { Camera::commit(); fovy = getParam("fovy", 60.f); aspect = getParam("aspect", 1.f); apertureRadius = getParam("apertureRadius", 0.f); focusDistance = getParam("focusDistance", 1.f); architectural = getParam("architectural", false); stereoMode = (OSPStereoMode)getParam("stereoMode", OSP_STEREO_NONE); // the default 63.5mm represents the average human IPD interpupillaryDistance = getParam("interpupillaryDistance", 0.0635f); switch (stereoMode) { case OSP_STEREO_SIDE_BY_SIDE: aspect *= 0.5f; break; case OSP_STEREO_TOP_BOTTOM: aspect *= 2.f; break; default: break; } vec2f imgPlaneSize; imgPlaneSize.y = 2.f * tanf(deg2rad(0.5f * fovy)); imgPlaneSize.x = imgPlaneSize.y * aspect; // Set shared structure members { getSh()->scaledAperture = apertureRadius ? apertureRadius / (imgPlaneSize.x * focusDistance) : 0.0f; getSh()->super.needLensSample = getSh()->scaledAperture; getSh()->aspect = aspect; getSh()->stereoMode = stereoMode; getSh()->dir_00 = normalize(dir); getSh()->org = pos; getSh()->imgPlaneSize = imgPlaneSize; if (getSh()->super.motionBlur) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.initRay = reinterpret_cast( ispc::PerspectiveCamera_initRayMB_addr()); #endif getSh()->du_size = vec3f(imgPlaneSize.x, imgPlaneSize.y, architectural); getSh()->dv_up = up; getSh()->ipd_offset = vec3f(0.5f * interpupillaryDistance, focusDistance, 0.0f); } else { #ifndef OSPRAY_TARGET_SYCL getSh()->super.initRay = reinterpret_cast( ispc::PerspectiveCamera_initRay_addr()); #endif getSh()->du_size = normalize(cross(getSh()->dir_00, up)); if (architectural) // orient film to be parallel to 'up' getSh()->dv_up = normalize(up); else // rotate film to be perpendicular to 'dir' getSh()->dv_up = cross(getSh()->du_size, getSh()->dir_00); getSh()->ipd_offset = 0.5f * interpupillaryDistance * getSh()->du_size; switch (stereoMode) { case OSP_STEREO_LEFT: getSh()->org = getSh()->org - getSh()->ipd_offset; break; case OSP_STEREO_RIGHT: getSh()->org = getSh()->org + getSh()->ipd_offset; break; case OSP_STEREO_TOP_BOTTOM: // flip offset to have left eye at top (image coord origin at lower // left) getSh()->ipd_offset = -getSh()->ipd_offset; break; default: break; } getSh()->du_size = getSh()->du_size * imgPlaneSize.x; getSh()->dv_up = getSh()->dv_up * imgPlaneSize.y; getSh()->dir_00 = getSh()->dir_00 - 0.5f * getSh()->du_size - 0.5f * getSh()->dv_up; // prescale to focal plane if (getSh()->scaledAperture > 0.f) { getSh()->du_size = getSh()->du_size * focusDistance; getSh()->dv_up = getSh()->dv_up * focusDistance; getSh()->dir_00 = getSh()->dir_00 * focusDistance; } } } } box3f PerspectiveCamera::projectBox(const box3f &b) const { if (stereoMode != OSP_STEREO_NONE) { return box3f(vec3f(0.f), vec3f(1.f)); } box3f projection; const vec3f dir = normalize( getSh()->dir_00 + 0.5f * getSh()->du_size + 0.5f * getSh()->dv_up); const vec3f dun = normalize(getSh()->du_size) / getSh()->imgPlaneSize.x; const vec3f dvn = normalize(getSh()->dv_up) / getSh()->imgPlaneSize.y; vec3f projectedPt(-1.f, -1.f, 1e20f); for (uint32_t i = 0; i < 8; ++i) { // Get the point we should be projecting vec3f p; switch (i) { case 0: p = b.lower; break; case 1: p.x = b.upper.x; p.y = b.lower.y; p.z = b.lower.z; break; case 2: p.x = b.upper.x; p.y = b.upper.y; p.z = b.lower.z; break; case 3: p.x = b.lower.x; p.y = b.upper.y; p.z = b.lower.z; break; case 4: p.x = b.lower.x; p.y = b.lower.y; p.z = b.upper.z; break; case 5: p.x = b.upper.x; p.y = b.lower.y; p.z = b.upper.z; break; case 6: p = b.upper; break; case 7: p.x = b.lower.x; p.y = b.upper.y; p.z = b.upper.z; break; } // We find the intersection of the ray through the point with the virtual // film plane, then find the vector to this point from the origin of the // film plane (screenDir) and project this point onto the x/y axes of // the plane. const vec3f v = p - getSh()->org; const vec3f r = normalize(v); const float denom = dot(-r, -dir); if (denom != 0.f) { float t = 1.f / denom; const vec3f screenDir = r * t - getSh()->dir_00; projectedPt.x = dot(screenDir, dun); projectedPt.y = dot(screenDir, dvn); projectedPt.z = std::signbit(t) ? -length(v) : length(v); projection.lower.x = min(projectedPt.x, projection.lower.x); projection.lower.y = min(projectedPt.y, projection.lower.y); projection.lower.z = min(projectedPt.z, projection.lower.z); projection.upper.x = max(projectedPt.x, projection.upper.x); projection.upper.y = max(projectedPt.y, projection.upper.y); projection.upper.z = max(projectedPt.z, projection.upper.z); } } // If some points are behind and some are in front mark the box // as covering the full screen if (projection.lower.z < 0.f && projection.upper.z > 0.f) { projection.lower.x = 0.f; projection.lower.y = 0.f; projection.upper.x = 1.f; projection.upper.y = 1.f; } return projection; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/PerspectiveCamera.h000066400000000000000000000017161464752671100245420ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "camera/Camera.h" #include "rkcommon/math/box.h" // ispc shared #include "PerspectiveCameraShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE PerspectiveCamera : public AddStructShared { PerspectiveCamera(api::ISPCDevice &device); virtual ~PerspectiveCamera() override = default; virtual std::string toString() const override; virtual void commit() override; box3f projectBox(const box3f &b) const override; // Data members // float fovy{60.f}; float aspect{1.f}; float apertureRadius{0.f}; float focusDistance{1.f}; bool architectural{false}; // orient image plane to be parallel to 'up' and // shift the lens OSPStereoMode stereoMode{OSP_STEREO_NONE}; float interpupillaryDistance{ 0.0635f}; // distance between the two cameras (stereo) }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/PerspectiveCamera.ih000066400000000000000000000010311464752671100247010ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "camera/Camera.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void PerspectiveCamera_initRay(const Camera *uniform, varying Ray &, varying RayCone &, const varying CameraSample &, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL void PerspectiveCamera_initRayMB(const Camera *uniform, varying Ray &, varying RayCone &, const varying CameraSample &, const uniform FeatureFlagsHandler &); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/PerspectiveCamera.ispc000066400000000000000000000117671464752671100252600ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Camera.ih" #include "common/Embree.h" #include "common/FeatureFlags.ih" #include "math/sampling.ih" #include "ospray/OSPEnums.h" // c++ shared #include "PerspectiveCameraShared.h" #include "rkcommon/math/AffineSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void PerspectiveCamera_initRay(const Camera *uniform _self, varying Ray &ray, varying RayCone &rayCone, const varying CameraSample &sample, const uniform FeatureFlagsHandler &) { const PerspectiveCamera *uniform self = (const PerspectiveCamera *uniform)_self; vec2f screen = sample.screen; vec3f org = self->org; const uniform bool sbs = self->stereoMode == OSP_STEREO_SIDE_BY_SIDE; varying float *uniform split = sbs ? &screen.x : &screen.y; float pixel_center = sbs ? sample.pixel_center.x : sample.pixel_center.y; if (sbs || self->stereoMode == OSP_STEREO_TOP_BOTTOM) { *split *= 2.f; if (pixel_center < 0.5f) { org = org - self->ipd_offset; } else { org = org + self->ipd_offset; *split -= 1.f; } } screen = Camera_subRegion(_self, screen); vec3f dir = self->dir_00 + screen.x * self->du_size + screen.y * self->dv_up; const float coneShortening = rsqrt(dot(dir, dir)); if (self->scaledAperture > 0.f) { const vec3f llp = uniformSampleDisk(self->scaledAperture, sample.lens); // transform local lens point to focal plane (dir_XX are prescaled) const vec3f lp = (llp.x * self->du_size) + ((llp.y * self->aspect) * self->dv_up); org = org + lp; dir = dir - lp; } const float time = Camera_shutterTime(_self, screen, sample.time); setRay(ray, org, normalize(dir), self->super.nearClip, inf, time); rayCone.width = 0.f; const uniform vec2f subImageSize = box_size(self->super.subImage); rayCone.dwdt = self->imgPlaneSize.y * abs(subImageSize.y) * coneShortening; // coneShortening is 1 for pixel at the center if (self->stereoMode == OSP_STEREO_TOP_BOTTOM) rayCone.dwdt *= 2.f; } SYCL_EXTERNAL void PerspectiveCamera_initRayMB(const Camera *uniform _self, varying Ray &ray, varying RayCone &rayCone, const varying CameraSample &sample, const uniform FeatureFlagsHandler &) { const PerspectiveCamera *uniform self = (const PerspectiveCamera *uniform)_self; 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 (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); AffineSpace3f xfm; rtcGetGeometryTransformFromScene( self->super.scene, 0, time, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm); vec3f org = xfmPoint(xfm, self->org); vec3f dir = normalize(xfmVector(xfm, self->dir_00)); const vec3f up = xfmVector(xfm, self->dv_up); vec3f du = normalize(cross(dir, up)); vec3f dv; if (self->du_size.z > 0.f) // architectural: orient img to be parallel to 'up' dv = normalize(up); else // rotate film to be perpendicular to 'dir' dv = cross(du, dir); 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; default: break; } du = du * self->du_size.x; dv = dv * self->du_size.y; dir = dir - 0.5f * du - 0.5f * dv; // prescale to focal plane if (self->scaledAperture > 0.f) { du = du * self->ipd_offset.y; // focusDistance dv = dv * self->ipd_offset.y; // focusDistance dir = dir * self->ipd_offset.y; // focusDistance } dir = dir + screen.x * du + screen.y * dv; if (self->scaledAperture > 0.f) { const vec3f llp = uniformSampleDisk(self->scaledAperture, sample.lens); // transform local lens point to focal plane (dir_XX are prescaled) const vec3f lp = (llp.x * du) + ((llp.y * self->aspect) * dv); org = org + lp; dir = dir - lp; } const float coneShortening = rsqrt(dot(dir, dir)); setRay(ray, org, normalize(dir), self->super.nearClip, inf, time); rayCone.width = 0.f; const uniform vec2f subImageSize = box_size(self->super.subImage); rayCone.dwdt = self->imgPlaneSize.y * abs(subImageSize.y) * coneShortening; // cone shortening is 1 for pixel at the center if (self->stereoMode == OSP_STEREO_TOP_BOTTOM) rayCone.dwdt *= 2.f; } // Exports (called from C++) ////////////////////////////////////////////////// export void *uniform PerspectiveCamera_initRay_addr() { return (void *uniform)PerspectiveCamera_initRay; } export void *uniform PerspectiveCamera_initRayMB_addr() { return (void *uniform)PerspectiveCamera_initRayMB; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/camera/PerspectiveCameraShared.h000066400000000000000000000027321464752671100256700ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "CameraShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct PerspectiveCamera { Camera super; vec3f org; // position of camera, already contains shift when // STEREO_{LEFT|RIGHT} vec3f dir_00; // direction of ray with screenSample=(0,0); scaled to // focusDistance if no motionBlur // below are essentially unions: 1. if no motionBlur; 2. if motionBlur vec3f du_size; // delta of ray direction between two pixels in x, scaled to // focusDistance; sensor size (in x and y) and architectural vec3f dv_up; // up vector with magnitude equal to the imagePlane size in y vec3f ipd_offset; // shift of camera position for left/right eye (only when // SIDE_BY_SIDE or TOP_BOTTOM); (0.5*ipd, focusDistance, 0) vec2f imgPlaneSize; float scaledAperture; // radius of aperture prescaled to focal plane, i.e., // divided by horizontal image plane size float aspect; // image plane size x / y int stereoMode; #ifdef __cplusplus PerspectiveCamera() : org(0.f), dir_00(0.f), du_size(0.f), dv_up(0.f), ipd_offset(0.f), imgPlaneSize(0.f), scaledAperture(0.f), aspect(1.f), stereoMode(OSP_STEREO_NONE) { super.type = CAMERA_TYPE_PERSPECTIVE; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/camera/registration.cpp000066400000000000000000000006361464752671100242050ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "OrthographicCamera.h" #include "PanoramicCamera.h" #include "PerspectiveCamera.h" namespace ospray { void registerAllCameras() { Camera::registerType("orthographic"); Camera::registerType("panoramic"); Camera::registerType("perspective"); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/camera/registration.h000066400000000000000000000002221464752671100236410ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllCameras(); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/000077500000000000000000000000001464752671100210225ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/common/Clipping.ih000066400000000000000000000023031464752671100231070ustar00rootroot00000000000000// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "rkcommon/math/AffineSpace.ih" #include "rkcommon/math/box.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Array of all ray intervals across ray #define CLIPPING_INTERVALS_MAX_COUNT 64 struct RayIntervals { uint32 count; range1f intervals[CLIPPING_INTERVALS_MAX_COUNT]; }; // Maximum number of intersections with clipping geometries #define CLIPPING_HITS_MAX_COUNT ((CLIPPING_INTERVALS_MAX_COUNT - 1) * 2) // Single clipping hit structure struct ClippingHit { float t; int primID; int geomID; int instID; }; // Compare two floats using ULP distance inline bool floatUlpCompare(float a, float b, uniform unsigned int ulpMaxDiff) { if (a == b) return true; int ulpDiff = (int)intbits(a) - (int)intbits(b); // Integer absolute value, equivalent to: // if (ulpDiff < 0) ulpDiff = -ulpDiff; int mask = (ulpDiff >> 31); unsigned int ulpDiffUnsigned = (ulpDiff ^ mask) - mask; if (ulpDiffUnsigned <= ulpMaxDiff) return true; return false; } inline bool overlapped(const range1f &a, const range1f &b) { return (a.upper > b.lower) && (a.lower < b.upper); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/DGEnum.h000066400000000000000000000014371464752671100223170ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ospray { #endif // __cplusplus typedef enum { DG_FACEFORWARD = (1 << 0), // face-forward normals DG_NORMALIZE = (1 << 1), // normalize normals DG_NG = (1 << 2), // need geometry normal Ng DG_NS = (1 << 3), // need shading normal Ns DG_COLOR = (1 << 5), // hack for now - need interpolated vertex color DG_TEXCOORD = (1 << 6), // calculate texture coords st DG_TANGENTS = (1 << 7), // calculate tangents, i.e. the partial derivatives of // position wrt. texture coordinates DG_MOTIONBLUR = (1 << 8), // calculate interpolated transformations for MB } DG_PostIntersectFlags; #ifdef __cplusplus } // namespace ospray #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/common/Data.cpp000066400000000000000000000142361464752671100224050ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Data.h" #include "ospray/ospray.h" #include "rkcommon/utility/getEnvVar.h" #include "rkcommon/utility/multidim_index_sequence.h" namespace ospray { Data::Data(api::ISPCDevice &device, const void *sharedData, OSPDataType type, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback freeFunction, const void *userData) : ISPCDeviceObject(device), appSharedPtr((char *)sharedData), shared(true), type(type), numItems(numItems), byteStride(byteStride), freeFunction(freeFunction), userData(userData) { if (sharedData == nullptr) { throw std::runtime_error("OSPData: shared buffer is NULL"); } addr = appSharedPtr; init(); if (isObjectType(type)) { for (auto &&child : as()) { if (child) child->refInc(); } } } Data::Data(api::ISPCDevice &device, OSPDataType type, const vec3ul &numItems) : ISPCDeviceObject(device), shared(false), type(type), numItems(numItems), byteStride(0) { // TODO: is this pad out by 16 still needed? view = devicert::make_buffer_shared_unique( device.getDRTDevice(), size() * sizeOf(type) + 16); addr = view->data(); init(); if (isObjectType(type)) // XXX initialize always? or never? memset(addr, 0, size() * sizeOf(type)); } Data::~Data() { if (isObjectType(type)) { for (auto &&child : as()) { if (child) child->refDec(); } } if (freeFunction) { freeFunction(userData, appSharedPtr); } } ispc::Data1D Data::emptyData1D; void Data::init() { managedObjectType = OSP_DATA; if (reduce_min(numItems) == 0) throw std::out_of_range("OSPData: all numItems must be positive"); dimensions = std::max(1, (numItems.x > 1) + (numItems.y > 1) + (numItems.z > 1)); // compute strides if requested if (byteStride.x == 0) byteStride.x = sizeOf(type); if (byteStride.y == 0) byteStride.y = numItems.x * byteStride.x; if (byteStride.z == 0) byteStride.z = numItems.y * byteStride.y; #ifdef OSPRAY_TARGET_SYCL // Check if the shared data the app gave is actually in USM, if not we still // need to make a copy of it internally so it's accessible on the GPU if (shared) { devicert::Device &device = getISPCDevice().getDRTDevice(); const size_t sizeBytes = byteStride.z * numItems.z; auto memType = device.getPointerType(addr); switch (memType) { case devicert::Alloc::Host: default: // std::cerr << "HOST..COPYING" << std::endl; shared = false; view = devicert::make_buffer_shared_unique(device, sizeBytes); addr = view->data(); std::memcpy(addr, appSharedPtr, sizeBytes); break; case devicert::Alloc::Shared: // std::cerr << "SHARED..USE IN PLACE" << std::endl; break; case devicert::Alloc::Device: static bool useDeviceMemory = (rkcommon::utility::getEnvVar("OSPRAY_ALLOW_DEVICE_MEMORY") .value_or(0) != 0); if (useDeviceMemory) { // std::cerr << "DEVICE..USE IN PLACE" << std::endl; addr = appSharedPtr; } else { // std::cerr << "DEVICE..COPYING" << std::endl; shared = false; // make ospray's shared buffer view = devicert::make_buffer_shared_unique(device, sizeBytes); // copy to it device.memcpy(view->sharedPtr(), appSharedPtr, sizeBytes); addr = view->data(); } break; } } #endif // precompute dominant axis and set at ispc-side proxy if (dimensions != 1) return; ispc.byteStride = byteStride.x; size_t numItems1D = numItems.x; if (numItems.y > 1) { ispc.byteStride = byteStride.y; numItems1D = numItems.y; } else if (numItems.z > 1) { ispc.byteStride = byteStride.z; numItems1D = numItems.z; } // finalize ispc-side ispc.addr = reinterpret_cast(addr); ispc.huge = std::abs(ispc.byteStride) * numItems1D > (size_t)std::numeric_limits::max(); ispc.numItems = (uint32_t)numItems1D; } bool Data::compact() const { return data() + sizeOf(type) * (size() - 1) == data(numItems - 1); } void Data::copy(const Data &source, const vec3ul &destinationIndex) { if (type != source.type && !(type == OSP_OBJECT && isObjectType(source.type))) { throw std::runtime_error(toString() + "::copy: types must match (cannot copy '" + stringFor(source.type) + "' into '" + stringFor(type) + "')"); } if (shared && !source.shared) { throw std::runtime_error( "OSPData::copy: cannot copy opaque (non-shared) data into shared " "data"); } if (anyLessThan(numItems, destinationIndex + source.numItems)) { throw std::out_of_range( "OSPData::copy: source does not fit into destination"); } if (byteStride == source.byteStride && data(destinationIndex) == source.data()) { // NoOP, no need to copy identical region // TODO markDirty(destinationIndex, destinationIndex + source.numItems); return; } index_sequence_3D srcIndices(source.numItems); for (auto srcIdx : srcIndices) { char *dst = data(srcIdx + destinationIndex); const char *src = source.data(srcIdx); if (isObjectType(type)) { const ManagedObject **srcO = (const ManagedObject **)src; if (*srcO) (*srcO)->refInc(); const ManagedObject **dstO = (const ManagedObject **)dst; if (*dstO) (*dstO)->refDec(); *dstO = *srcO; } else { memcpy(dst, src, sizeOf(type)); } } } #ifdef OSPRAY_TARGET_SYCL void Data::commit() { // If we were passed "shared" data that was not actually in USM we made a USM // copy of it, and need to update that copy on commit if (appSharedPtr && addr != appSharedPtr) { // FIXME: handle ISPCRT_ALLOC_TYPE_DEVICE memory (needs device copy) const size_t sizeBytes = byteStride.z * numItems.z; std::memcpy(addr, appSharedPtr, sizeBytes); } } #endif bool Data::isShared() const { return shared; } std::string Data::toString() const { return "ospray::Data"; } OSPTYPEFOR_DEFINITION(Data *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Data.h000066400000000000000000000236541464752671100220560ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "ISPCDeviceObject.h" #include "StructShared.h" // including "Data_ispc.h" breaks app code using SDK headers #ifndef __ISPC_STRUCT_Data1D__ #define __ISPC_STRUCT_Data1D__ namespace ispc { struct Data1D { uint8_t *addr; int64_t byteStride; uint32_t numItems; bool huge; }; } // namespace ispc #endif namespace ospray { template struct DataT; /*! \brief defines a data array (aka "buffer") type that contains 'n' items of a given type */ struct OSPRAY_SDK_INTERFACE Data : public ISPCDeviceObject { Data(api::ISPCDevice &device, const void *sharedData, OSPDataType, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback freeFunction = nullptr, const void *userData = nullptr); Data(api::ISPCDevice &device, OSPDataType, const vec3ul &numItems); virtual ~Data() override; virtual std::string toString() const override; size_t size() const; vec3l stride() const; char *data() const; char *data(const vec3ul &idx) const; bool compact() const; // all strides are natural void copy(const Data &source, const vec3ul &destinationIndex); #ifdef OSPRAY_TARGET_SYCL void commit() override; #endif bool isShared() const; template const DataT &as() const; template DataT &as(); template typename std::enable_if::value, bool>::type is() const; template typename std::enable_if::value, bool>::type is() const; protected: // The actual buffer storing the data BufferSharedUq view; char *addr{nullptr}; // We need to track the appSharedPtr separately for the GPU backend, if we // were passed a shared ptr to memory that was not in USM we made a copy that // addr points to and we need to keep it in sync with the shared data from the // app. char *appSharedPtr{nullptr}; bool shared; public: OSPDataType type{OSP_UNKNOWN}; vec3ul numItems; protected: vec3l byteStride; public: int dimensions{0}; ispc::Data1D ispc; static ispc::Data1D emptyData1D; // dummy, zero-initialized private: void init(); // init dimensions and byteStride protected: OSPDeleterCallback freeFunction{nullptr}; const void *userData{nullptr}; }; OSPTYPEFOR_SPECIALIZATION(Data *, OSP_DATA); template class Iter { const Data &data; vec3ul idx; public: using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T *; using reference = T &; Iter(const Data &data, vec3ul idx) : data(data), idx(idx) {} Iter &operator++() { if (++idx.x >= data.numItems.x) { idx.x = 0; if (++idx.y >= data.numItems.y) { idx.y = 0; ++idx.z; } } return *this; } Iter operator++(int) { Iter retv(*this); ++(*this); return retv; } bool operator!=(Iter &other) const { return &data != &other.data || idx != other.idx; } T &operator*() const { return *reinterpret_cast(data.data(idx)); } }; template class Iter1D { char *addr{nullptr}; int64_t byteStride{1}; public: using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T *; using reference = T &; Iter1D(char *addr, int64_t byteStride) : addr(addr), byteStride(byteStride) {} Iter1D &operator++() { addr += byteStride; return *this; } Iter1D operator++(int) { Iter1D retv(*this); ++(*this); return retv; } bool operator==(const Iter1D &other) const { return addr == other.addr; } bool operator!=(const Iter1D &other) const { return addr != other.addr; } T &operator*() const { return *reinterpret_cast(addr); } T *operator->() const { return reinterpret_cast(addr); } }; template struct DataT : public Data { static_assert(DIM == 2 || DIM == 3, "only 1D, 2D or 3D DataT supported"); using value_type = T; using iterator = Iter; Iter begin() const { return Iter(*this, vec3ul(0)); } Iter end() const { return Iter(*this, vec3ul(0, 0, numItems.z)); } T &operator[](const vec_t &idx) { return *reinterpret_cast(data(idx)); } const T &operator[](const vec_t &idx) const { return const_cast *>(this)->operator[](idx); } T *data() const { return reinterpret_cast(addr); } }; template struct DataT : public Data { using value_type = T; using iterator = Iter1D; Iter1D begin() const { return Iter1D(addr, ispc.byteStride); } Iter1D end() const { return Iter1D(addr + ispc.byteStride * size(), ispc.byteStride); } T &operator[](int64_t idx) { return *reinterpret_cast(addr + ispc.byteStride * idx); } const T &operator[](int64_t idx) const { return const_cast *>(this)->operator[](idx); } T *data() const { return reinterpret_cast(addr); } int64_t stride() const { return ispc.byteStride; } }; template struct OSPTypeFor *> { static constexpr OSPDataType value = OSP_DATA; }; // Inlined definitions ////////////////////////////////////////////////////// inline const ispc::Data1D *ispc(Ref &dataRef) { if (dataRef && dataRef->size() > std::numeric_limits::max()) throw std::runtime_error( "data array too large (over 4B elements, index is limited to 32bit"); return dataRef && dataRef->dimensions == 1 ? &dataRef->ispc : &Data::emptyData1D; } template const ispc::Data1D *ispc(Ref> &dataRef) { return dataRef ? &dataRef->ispc : &Data::emptyData1D; } template ispc::Data1D *ispc(Ref> &dataRef) { return dataRef ? &dataRef->ispc : &Data::emptyData1D; } inline size_t Data::size() const { return numItems.x * numItems.y * numItems.z; } inline vec3l Data::stride() const { return byteStride; } inline char *Data::data() const { return addr; } inline char *Data::data(const vec3ul &idx) const { return addr + idx.x * byteStride.x + idx.y * byteStride.y + idx.z * byteStride.z; } template inline typename std::enable_if::value, bool>::type Data::is() const { auto toType = OSPTypeFor::type>::type *>::value; return (type == toType || (toType == OSP_OBJECT && isObjectType(type))) && dimensions <= DIM; // can iterate with higher dimensionality } template inline typename std::enable_if::value, bool>::type Data::is() const { // can iterate with higher dimensionality return type == OSPTypeFor::value && dimensions <= DIM; } template inline const DataT &Data::as() const { if (is()) return (DataT &)*this; else { std::stringstream ss; ss << "Incompatible type or dimension for DataT; requested type[dim]: " << stringFor(OSPTypeFor::value) << "[" << DIM << "], actual: " << stringFor(type) << "[" << dimensions << "]."; throw std::runtime_error(ss.str()); } } template inline DataT &Data::as() { if (is()) return (DataT &)*this; else { std::stringstream ss; ss << "Incompatible type or dimension for DataT; requested type[dim]: " << stringFor(OSPTypeFor::value) << "[" << DIM << "], actual: " << stringFor(type) << "[" << dimensions << "]."; throw std::runtime_error(ss.str()); } } template inline const Ref> ISPCDeviceObject::getParamDataT( const char *name, bool required, bool promoteScalar) { Data *data = getParamObject(name); if (data && data->is()) return &(data->as()); // if no data array is found, look for single item of same type if (promoteScalar) { auto item = getOptParam(name); if (item) { // create data array and its reference object data = new Data(getISPCDevice(), OSPTypeFor::value, vec3ul(1)); Ref> refDataT = &data->as(); // 'data' reference counter equals to 2 now, // but we want it to be 1 and the 'data' to be referenced only by the // returned object for proper destruction data->refDec(); // place value into 'data' array T *p = refDataT->data(); *p = item.value(); // if we are inserting 'ManagedObject' we need to increase its reference // counter, too if (isObjectType(data->type)) (*data->as().begin())->refInc(); return refDataT; } } if (required) { std::string msg(toString() + " must have '" + name + "' " + std::to_string(DIM) + "D array with element type " + stringFor(OSPTypeFor::value)); if (data) msg.append(", found " + std::to_string(data->dimensions) + "D array with element type " + stringFor(data->type)); throw std::runtime_error(msg); } else { if (data) { postStatusMsg(OSP_LOG_DEBUG) << toString() << " ignoring '" << name << "' " << data->dimensions << "D array with element type " << stringFor(data->type) << " (while looking for " << DIM << "D array of " << stringFor(OSPTypeFor::value) << ")"; } return nullptr; } } template std::vector createArrayOfSh(const DataT &data) { std::vector retval; retval.reserve(data.size()); for (auto &&obj : data) retval.push_back(obj->getSh()); return retval; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Data.ih000066400000000000000000000067751464752671100222340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/LinearSpace.ih" #include "rkcommon/math/box.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Data1D { uint8 *addr; int64 byteStride; uint32 numItems; bool huge; // 64bit address calculation necessary }; inline void Data1D_Constructor(Data1D *uniform self) { self->addr = NULL; self->byteStride = 0; self->numItems = 0; self->huge = false; } // ok to pass-by-value, will be inlined and optimized inline uniform bool valid(const uniform Data1D data) { return data.addr != NULL; } // special 64-bit safe code: #define BITS 20 template inline varying T get(const uniform Data1D &data, const varying int index) { return *((const uniform T *)(data.addr + data.byteStride * index)); } // ok to pass-by-value, will be inlined and optimized #ifdef OSPRAY_TARGET_SYCL // SYCL execution in a thread is scalar // Old macro version (kept for compatibility with older code) #define __define_get(T) \ inline uniform T get_##T(const uniform Data1D data, const uniform int index) \ { \ return *((const T *)(data.addr + data.byteStride * index)); \ } #else #define __define_get(T) \ inline T get_##T(const uniform Data1D data, const varying int index) \ { \ if (data.huge) { \ T v; \ const int index_lo = index & ((1 << BITS) - 1); \ const int index_hi = index - index_lo; \ const int scaledIndexLo = index_lo * data.byteStride; \ foreach_unique (hi in index_hi) { \ /* uniform offset for upper bits */ \ const uniform uint64 scaledIndexHi = (uint64)(hi)*data.byteStride; \ /* properly shifted base address (shifted by 64-bits) */ \ const uint8 *uniform base_hi = data.addr + scaledIndexHi; \ v = *((const T *)(base_hi + scaledIndexLo)); \ } \ return v; \ } else \ return *((const T *)(data.addr + data.byteStride * index)); \ } \ inline uniform T get_##T(const uniform Data1D data, const uniform int index) \ { \ return *((const T *)(data.addr + data.byteStride * index)); \ } #endif __define_get(int32); __define_get(vec2i); __define_get(vec3i); __define_get(vec4i); __define_get(uint8); __define_get(uint32); __define_get(vec2ui); __define_get(vec3ui); __define_get(vec4ui); __define_get(float); __define_get(vec2f); __define_get(vec3f); __define_get(vec4f); __define_get(box1f); __define_get(box2f); __define_get(box3f); __define_get(box4f); __define_get(linear3f); #undef __define_get #undef BITS OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/DeviceRT.ih000066400000000000000000000174011464752671100230140ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #define ROUND_RANGE(global, group) ((global - 1) / group + 1) * group #ifdef ISPC #define DEFINE_RENDERER_KERNEL_LAUNCHER(kernel_name) \ task static void kernel_name##Task(Renderer *uniform renderer, \ FrameBuffer *uniform fb, \ Camera *uniform camera, \ World *uniform world, \ const uint32 *uniform taskIDs, \ const uniform FeatureFlagsHandler &ffh) \ { \ const uniform vec3ui itemIndex = make_vec3ui(0, 0, taskIndex2); \ kernel_name(itemIndex, renderer, fb, camera, world, taskIDs, ffh); \ } \ \ export void kernel_name##Launcher(void *uniform, \ void *uniform, \ const uniform vec3ui &itemDims, \ Renderer *uniform renderer, \ FrameBuffer *uniform fb, \ Camera *uniform camera, \ World *uniform world, \ const uint32 *uniform taskIDs, \ const uniform FeatureFlags &ff) \ { \ uniform FeatureFlagsHandler ffh; \ launch[1, 1, itemDims.z] kernel_name##Task( \ renderer, fb, camera, world, taskIDs, ffh); \ } #define DEFINE_FRAMEOP_KERNEL_LAUNCHER(kernel_name) \ task static void kernel_name##Task( \ const uniform vec2ui &itemDims, const FrameBufferView *uniform fbv) \ { \ const vec2ui itemIndex = \ make_vec2ui(taskIndex0 * programCount + programIndex, taskIndex1); \ if (itemIndex.x < itemDims.x) \ kernel_name(itemIndex, fbv); \ } \ \ export void kernel_name##Launcher(void *uniform, \ void *uniform, \ const uniform vec2ui &itemDims, \ const FrameBufferView *uniform fbv) \ { \ launch[ROUND_RANGE(itemDims.x, programCount), \ itemDims.y] kernel_name##Task(itemDims, fbv); \ } #else #define DEFINE_RENDERER_KERNEL_LAUNCHER(kernel_name) \ extern "C" void kernel_name##Launcher(void *queue, \ void *event, \ const vec3ui &itemDims, \ Renderer *renderer, \ FrameBuffer *fb, \ Camera *camera, \ World *world, \ const uint32_t *taskIDs, \ const FeatureFlags &ff) \ { \ sycl::queue *syclQueue = static_cast(queue); \ sycl::event *syclEvent = static_cast(event); \ /* Submit kernel to device */ \ sycl::nd_range<3> dispatchRange( \ {itemDims.x, itemDims.y, itemDims.z}, {itemDims.x, itemDims.y, 1}); \ *syclEvent = syclQueue->submit([&](sycl::handler &cgh) { \ cgh.set_specialization_constant(ff); \ cgh.parallel_for(dispatchRange, \ [=](sycl::nd_item<3> itemIndex, sycl::kernel_handler kh) { \ ispc::FeatureFlagsHandler ffh(kh); \ kernel_name(vec3ui(itemIndex.get_global_id(0), \ itemIndex.get_global_id(1), \ itemIndex.get_global_id(2)), \ renderer, \ fb, \ camera, \ world, \ taskIDs, \ ffh); \ }); \ }); \ } #define DEFINE_FRAMEOP_KERNEL_LAUNCHER(kernel_name) \ extern "C" void kernel_name##Launcher(void *queue, \ void *event, \ const vec2ui &itemDims, \ const FrameBufferView *fbv) \ { \ sycl::queue *syclQueue = static_cast(queue); \ sycl::event *syclEvent = static_cast(event); \ /* Submit kernel to device */ \ const vec2ui workgroupSize = vec2ui(16, 1); \ const vec2ui roundedSize = ROUND_RANGE(itemDims, workgroupSize); \ sycl::nd_range<2> dispatchRange( \ {roundedSize.x, roundedSize.y}, {workgroupSize.x, workgroupSize.y}); \ *syclEvent = syclQueue->submit([&](sycl::handler &cgh) { \ cgh.parallel_for(dispatchRange, [=](sycl::nd_item<2> itemIndex) { \ if (itemIndex.get_global_id(0) < itemDims.x) \ kernel_name( \ vec2ui(itemIndex.get_global_id(0), itemIndex.get_global_id(1)), \ fbv); \ }); \ }); \ } #endifRenderKit-ospray-85af292/modules/cpu/common/DeviceRTImpl.h000066400000000000000000000013211464752671100234570ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef OSPRAY_TARGET_SYCL #include "DeviceRTImpl_sycl.h" #else #include "DeviceRTImpl_ispc.h" #endif namespace ospray { namespace devicert { template inline std::unique_ptr make_device_unique(Args &&...args) { return std::unique_ptr(new DeviceImpl(std::forward(args)...)); } template inline std::unique_ptr> make_buffer_device_shadowed_unique(Args &&...args) { return std::unique_ptr>( new BufferDeviceShadowedImpl(std::forward(args)...)); } } // namespace devicert } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/DeviceRTImpl_ispc.cpp000066400000000000000000000215421464752671100250370ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DeviceRTImpl_ispc.h" #include "common/FeatureFlagsEnum.h" #include "rkcommon/memory/malloc.h" #include // for memcpy namespace ospray { namespace devicert { ///////////////////////////////////////////////////////////////////// // AsyncEvent implementation void AsyncEventImpl::jobScheduled() { std::lock_guard lock(mtx); ready = false; } void AsyncEventImpl::jobStarted() { std::lock_guard lock(mtx); timer.start(); } void AsyncEventImpl::jobFinished() { { std::lock_guard lock(mtx); timer.stop(); ready = true; } cv.notify_one(); } void AsyncEventImpl::wait() const { std::unique_lock lock(mtx); cv.wait(lock, [this] { return ready; }); } bool AsyncEventImpl::finished() const { std::lock_guard lock(mtx); return ready; } float AsyncEventImpl::getDuration() const { std::lock_guard lock(mtx); return timer.seconds(); } void *AsyncEventImpl::getSyclEventPtr() { return nullptr; } ///////////////////////////////////////////////////////////////////// // Device implementation // Base command class struct DeviceImpl::Command { Command() = default; Command(std::shared_ptr event) : event(event) {} virtual ~Command() = default; virtual bool execute() = 0; friend struct DeviceImpl; protected: std::shared_ptr event; }; // Shutdown device thread command struct DeviceImpl::CommandShutdown : public Command { bool execute() override { // Just return false for loop exit return false; } }; // MemCpy command struct DeviceImpl::CommandMemCpy : public Command { CommandMemCpy(void *dest, const void *src, std::size_t size, std::shared_ptr event) : Command(event), dest(dest), src(src), size(size) {} bool execute() override { // Do memory copying event->jobStarted(); std::memcpy(dest, src, size); event->jobFinished(); // Continue commands processing return true; } private: void *const dest; const void *const src; const std::size_t size; }; // Launch render kernel command struct DeviceImpl::CommandLaunchRenderKernel : public Command { CommandLaunchRenderKernel(const vec3ui &itemDims, RendererKernel kernel, ispc::Renderer *renderer, ispc::FrameBuffer *fb, ispc::Camera *camera, ispc::World *world, const uint32_t *taskIDs, const FeatureFlags &ff, std::shared_ptr event) : Command(event), itemDims(itemDims), rendererKernel(kernel), renderer(renderer), fb(fb), camera(camera), world(world), taskIDs(taskIDs), ff(ff) {} bool execute() override { // Run kernel event->jobStarted(); rendererKernel( nullptr, nullptr, itemDims, renderer, fb, camera, world, taskIDs, ff); event->jobFinished(); // Continue commands processing return true; } private: // Domain and kernel pointer const vec3ui itemDims; RendererKernel rendererKernel; // Kernel parameters ispc::Renderer *renderer; ispc::FrameBuffer *fb; ispc::Camera *camera; ispc::World *world; const uint32_t *taskIDs; const FeatureFlags ff; }; // Launch FrameOp kernel command struct DeviceImpl::CommandLaunchFrameOpKernel : public Command { CommandLaunchFrameOpKernel(const vec2ui &itemDims, FrameOpKernel kernel, const ispc::FrameBufferView *fbv, std::shared_ptr event) : Command(event), itemDims(itemDims), frameOpKernel(kernel), fbv(fbv) {} bool execute() override { // Run kernel event->jobStarted(); frameOpKernel(nullptr, nullptr, itemDims, fbv); event->jobFinished(); // Continue commands processing return true; } private: // Domain and kernel pointer const vec2ui itemDims; FrameOpKernel frameOpKernel; // Kernel parameters const ispc::FrameBufferView *fbv; }; // Run host task command struct DeviceImpl::CommandRunHostTask : public Command { CommandRunHostTask( const std::function task, std::shared_ptr event) : Command(event), hostTask(task) {} bool execute() override { // Run task event->jobStarted(); hostTask(); event->jobFinished(); // Continue commands processing return true; } private: const std::function hostTask; }; DeviceImpl::DeviceImpl(bool debug) : Device(debug), workerThread([this]() { // Main worker thread loop CommandPtr cmd; do { // Lock the mutex std::unique_lock lock(queueMtx); // Atomically release the mutex and wait. At this point, the mutex // is released, allowing main thread to acquire it queueCV.wait(lock, [this] { return !commandQueue.empty(); }); // When notified by the main thread and the condition is true, the // mutex is re-acquired by the wait function before returning so we // can safely retrieve command from the queue cmd = std::move(commandQueue.front()); commandQueue.pop(); // Process the command } while (cmd->execute()); }) {} DeviceImpl::DeviceImpl(uint32_t, bool debug) : DeviceImpl(debug) {} DeviceImpl::DeviceImpl(void *, void *, bool debug) : DeviceImpl(debug) {} DeviceImpl::~DeviceImpl() { // Signal the worker thread to terminate by adding shutdown command scheduleCommand(std::unique_ptr(new CommandShutdown())); // And finish worker thread workerThread.join(); } void DeviceImpl::scheduleCommand(CommandPtr cmd) { { std::lock_guard lock(queueMtx); if (cmd->event) cmd->event->jobScheduled(); commandQueue.push(std::move(cmd)); } queueCV.notify_one(); } void *DeviceImpl::deviceMalloc(std::size_t size) { return rkcommon::memory::alignedMalloc(size); } void *DeviceImpl::sharedMalloc(std::size_t size) { return rkcommon::memory::alignedMalloc(size); } void *DeviceImpl::hostMalloc(std::size_t size) { return rkcommon::memory::alignedMalloc(size); } void DeviceImpl::free(void *ptr) { rkcommon::memory::alignedFree(ptr); } Alloc DeviceImpl::getPointerType(void *) const { return Alloc::Host; } void DeviceImpl::wait() { // Get the last event if exists std::shared_ptr lastEvent; { std::lock_guard lock(queueMtx); if (commandQueue.empty()) return; lastEvent = commandQueue.back()->event; } // And wait for its completion lastEvent->wait(); } AsyncEvent DeviceImpl::createAsyncEvent() { std::shared_ptr eventImpl = std::make_shared(); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::memcpy(void *dest, const void *src, std::size_t size) { // Create a command with event auto eventImpl = std::make_shared(); CommandPtr cmd = std::unique_ptr(new CommandMemCpy(dest, src, size, eventImpl)); // Put the command into the queue and signal the worker thread scheduleCommand(std::move(cmd)); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::launchRendererKernel(const vec3ui &itemDims, RendererKernel kernel, ispc::Renderer *renderer, ispc::FrameBuffer *fb, ispc::Camera *camera, ispc::World *world, const uint32_t *taskIDs, const FeatureFlags &ff) { // Create a command with event auto eventImpl = std::make_shared(); CommandPtr cmd = std::unique_ptr(new CommandLaunchRenderKernel( itemDims, kernel, renderer, fb, camera, world, taskIDs, ff, eventImpl)); // Put the command into the queue and signal the worker thread scheduleCommand(std::move(cmd)); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::launchFrameOpKernel(const vec2ui &itemDims, FrameOpKernel kernel, const ispc::FrameBufferView *fbv) { // Create a command with event auto eventImpl = std::make_shared(); CommandPtr cmd = std::unique_ptr( new CommandLaunchFrameOpKernel(itemDims, kernel, fbv, eventImpl)); // Put the command into the queue and signal the worker thread scheduleCommand(std::move(cmd)); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::launchHostTask(const std::function &task) { // Create a command with event auto eventImpl = std::make_shared(); CommandPtr cmd = std::unique_ptr(new CommandRunHostTask(task, eventImpl)); // Put the command into the queue and signal the worker thread scheduleCommand(std::move(cmd)); return AsyncEvent(eventImpl); } void *DeviceImpl::getSyclDevicePtr() { // SYCL not used return nullptr; } void *DeviceImpl::getSyclContextPtr() { // SYCL not used return nullptr; } void *DeviceImpl::getSyclQueuePtr() { // SYCL not used return nullptr; } } // namespace devicert } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/DeviceRTImpl_ispc.h000066400000000000000000000105361464752671100245050ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/DeviceRT.h" #include "rkcommon/utility/CodeTimer.h" #include #include #include #include namespace ospray { namespace devicert { ///////////////////////////////////////////////////////////////////// // AsyncEvent interface struct OSPRAY_SDK_INTERFACE AsyncEventImpl : public AsyncEventIfc { // Signalling job state void jobScheduled(); void jobStarted(); void jobFinished(); // Wait for the event void wait() const override; // Return true if finished bool finished() const override; // Get event duration float getDuration() const override; // Get SYCL event pointer void *getSyclEventPtr() override; private: // Event state bool ready{true}; // Measure job time rkcommon::utility::CodeTimer timer; // Synchronization to wait on event mutable std::mutex mtx; mutable std::condition_variable cv; }; ///////////////////////////////////////////////////////////////////// // Device interface struct OSPRAY_SDK_INTERFACE DeviceImpl : public Device { // Construction & destruction DeviceImpl(bool debug); DeviceImpl(uint32_t deviceId, bool debug); DeviceImpl(void *devicePtr, void *contextPtr, bool debug); ~DeviceImpl() override; // Allocate device memory void *deviceMalloc(std::size_t size) override; // Allocate shared memory void *sharedMalloc(std::size_t size) override; // Allocate host memory void *hostMalloc(std::size_t size) override; // Release shared or device memory void free(void *ptr) override; // Get pointer allocation type Alloc getPointerType(void *ptr) const override; // Wait for device to finish its pending work void wait() override; // Create asynchronous event object AsyncEvent createAsyncEvent() override; // Copy memory from/to device AsyncEvent memcpy(void *dest, const void *src, std::size_t size) override; // Launch a kernel on a device AsyncEvent launchRendererKernel(const vec3ui &itemDims, RendererKernel kernel, ispc::Renderer *renderer, ispc::FrameBuffer *fb, ispc::Camera *camera, ispc::World *world, const uint32_t *taskIDs, const FeatureFlags &ff) override; AsyncEvent launchFrameOpKernel(const vec2ui &itemDims, FrameOpKernel kernel, const ispc::FrameBufferView *fbv) override; // Launch a given task on a host using device queue ordering AsyncEvent launchHostTask(const std::function &task) override; // For code (e.g. OIDN API) that is able to use SYCL without including it void *getSyclDevicePtr() override; void *getSyclContextPtr() override; void *getSyclQueuePtr() override; private: // Inner command classes class Command; class CommandShutdown; class CommandMemCpy; class CommandLaunchRenderKernel; class CommandLaunchFrameOpKernel; class CommandRunHostTask; using CommandPtr = std::unique_ptr; // Device command queue std::queue commandQueue; std::mutex queueMtx; std::condition_variable queueCV; // Device worker thread std::thread workerThread; // Schedule command for execution void scheduleCommand(CommandPtr cmd); }; ///////////////////////////////////////////////////////////////////// // Buffer in device memory with system memory shadow template struct BufferDeviceShadowedImpl : public BufferDeviceShadowed { // Inherit constructors BufferDeviceShadowedImpl(Device &device, std::size_t count); BufferDeviceShadowedImpl(Device &device, const std::vector &v); BufferDeviceShadowedImpl(Device &device, T *data, std::size_t count); protected: // Copy between device and shadow buffers AsyncEvent memcpy(T *, const T *, std::size_t) override { return AsyncEvent(); } }; template BufferDeviceShadowedImpl::BufferDeviceShadowedImpl( Device &device, std::size_t count) : BufferDeviceShadowed(device, nullptr, count) {} template BufferDeviceShadowedImpl::BufferDeviceShadowedImpl( Device &device, const std::vector &v) : BufferDeviceShadowed(device, nullptr, v) {} template BufferDeviceShadowedImpl::BufferDeviceShadowedImpl( Device &device, T *data, std::size_t count) : BufferDeviceShadowed(device, nullptr, data, count) {} } // namespace devicert } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/DeviceRTImpl_sycl.cpp000066400000000000000000000127231464752671100250540ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DeviceRTImpl_sycl.h" namespace ospray { namespace devicert { ///////////////////////////////////////////////////////////////////// // AsyncEvent implementation void AsyncEventImpl::wait() const { event.wait(); } bool AsyncEventImpl::finished() const { return (event.get_info() == sycl::info::event_command_status::complete); } float AsyncEventImpl::getDuration() const { try { const auto t0 = event.get_profiling_info(); const auto t1 = event.get_profiling_info(); return (t1 - t0) * 1.0e-9f; } catch (...) { // In case no profiling data is available return 0.f; } } void *AsyncEventImpl::getSyclEventPtr() { return &event; } ///////////////////////////////////////////////////////////////////// // Device implementation DeviceImpl::DeviceImpl(bool debug) : Device(debug), device(sycl::gpu_selector_v), context(device), queue(context, device, {sycl::property::queue::enable_profiling(), sycl::property::queue::in_order()}) { postStatusMsg(OSP_LOG_INFO) << "Using SYCL GPU device on " << device.get_info() << " device (default)"; } namespace { sycl::device getDeviceByIndex(uint32_t id) { auto gpuDevices = sycl::device::get_devices(sycl::info::device_type::gpu); return gpuDevices[id % gpuDevices.size()]; } } // namespace DeviceImpl::DeviceImpl(uint32_t deviceId, bool debug) : Device(debug), device(getDeviceByIndex(deviceId)), context(device), queue(context, device, {sycl::property::queue::enable_profiling(), sycl::property::queue::in_order()}) { postStatusMsg(OSP_LOG_INFO) << "Using SYCL GPU device on " << device.get_info() << " device (number: " << deviceId << ")"; } DeviceImpl::DeviceImpl(void *devicePtr, void *contextPtr, bool debug) : Device(debug), device(*static_cast(devicePtr)), context(*static_cast(contextPtr)), queue(context, device, {sycl::property::queue::enable_profiling(), sycl::property::queue::in_order()}) { postStatusMsg(OSP_LOG_INFO) << "Using SYCL GPU device on " << device.get_info() << " device (provided externally)"; } void *DeviceImpl::deviceMalloc(std::size_t size) { return sycl::malloc_device(size, queue); } void *DeviceImpl::sharedMalloc(std::size_t size) { return sycl::malloc_shared( size, queue, sycl::ext::oneapi::property::usm::device_read_only()); } void *DeviceImpl::hostMalloc(std::size_t size) { return sycl::malloc_host(size, queue); } void DeviceImpl::free(void *ptr) { sycl::free(ptr, queue); } Alloc DeviceImpl::getPointerType(void *ptr) const { sycl::usm::alloc type = sycl::get_pointer_type(ptr, queue.get_context()); switch (type) { case sycl::usm::alloc::host: return Alloc::Host; case sycl::usm::alloc::device: return Alloc::Device; case sycl::usm::alloc::shared: return Alloc::Shared; case sycl::usm::alloc::unknown: return Alloc::Unknown; } return Alloc::Unknown; } void DeviceImpl::wait() { queue.wait(); } AsyncEvent DeviceImpl::createAsyncEvent() { std::shared_ptr eventImpl = std::make_shared(); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::memcpy(void *dest, const void *src, std::size_t size) { // Create async event and do memory copying std::shared_ptr eventImpl = std::make_shared(); eventImpl->event = queue.memcpy(dest, src, size); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::launchRendererKernel(const vec3ui &itemDims, RendererKernel kernel, ispc::Renderer *renderer, ispc::FrameBuffer *fb, ispc::Camera *camera, ispc::World *world, const uint32_t *taskIDs, const FeatureFlags &ff) { // Create async event and launch a kernel std::shared_ptr eventImpl = std::make_shared(); kernel(&queue, &eventImpl->event, itemDims, renderer, fb, camera, world, taskIDs, ff); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::launchFrameOpKernel(const vec2ui &itemDims, FrameOpKernel kernel, const ispc::FrameBufferView *fbv) { // Create async event and launch a kernel std::shared_ptr eventImpl = std::make_shared(); kernel(&queue, &eventImpl->event, itemDims, fbv); return AsyncEvent(eventImpl); } AsyncEvent DeviceImpl::launchHostTask(const std::function &task) { // Create async event and launch a task std::shared_ptr eventImpl = std::make_shared(); eventImpl->event = queue.submit( [&](sycl::handler &cgh) { cgh.host_task([=]() { task(); }); }); return AsyncEvent(eventImpl); } void *DeviceImpl::getSyclDevicePtr() { // Return SYCL device pointer return &device; } void *DeviceImpl::getSyclContextPtr() { // Return SYCL context pointer return &context; } void *DeviceImpl::getSyclQueuePtr() { // Return SYCL command queue pointer return &queue; } } // namespace devicert } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/DeviceRTImpl_sycl.h000066400000000000000000000103521464752671100245150ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/DeviceRT.h" #include namespace ospray { namespace devicert { ///////////////////////////////////////////////////////////////////// // AsyncEvent interface struct OSPRAY_SDK_INTERFACE AsyncEventImpl : public AsyncEventIfc { // Wait for the event void wait() const override; // Return true if finished bool finished() const override; // Get event duration float getDuration() const override; // Allow DeviceImpl to access event friend struct DeviceImpl; // Get SYCL event pointer void *getSyclEventPtr() override; private: mutable sycl::event event; }; ///////////////////////////////////////////////////////////////////// // Device interface struct OSPRAY_SDK_INTERFACE DeviceImpl : public Device { // Construction & destruction DeviceImpl(bool debug); DeviceImpl(uint32_t deviceId, bool debug); DeviceImpl(void *devicePtr, void *contextPtr, bool debug); // Allocate device memory void *deviceMalloc(std::size_t size) override; // Allocate shared memory void *sharedMalloc(std::size_t size) override; // Allocate host memory void *hostMalloc(std::size_t size) override; // Release shared or device memory void free(void *ptr) override; // Get pointer allocation type Alloc getPointerType(void *ptr) const override; // Wait for device to finish its pending work void wait() override; // Create asynchronous event object AsyncEvent createAsyncEvent() override; // Copy memory from/to device AsyncEvent memcpy(void *dest, const void *src, std::size_t size) override; // Launch a kernel on a device AsyncEvent launchRendererKernel(const vec3ui &itemDims, RendererKernel kernel, ispc::Renderer *renderer, ispc::FrameBuffer *fb, ispc::Camera *camera, ispc::World *world, const uint32_t *taskIDs, const FeatureFlags &ff) override; AsyncEvent launchFrameOpKernel(const vec2ui &itemDims, FrameOpKernel kernel, const ispc::FrameBufferView *fbv) override; // Launch a given task on a host using device queue ordering AsyncEvent launchHostTask(const std::function &task) override; // For code (e.g. OIDN API) that is able to use SYCL without including it void *getSyclDevicePtr() override; void *getSyclContextPtr() override; void *getSyclQueuePtr() override; private: sycl::device device; sycl::context context; sycl::queue queue; }; ///////////////////////////////////////////////////////////////////// // Buffer in device memory with system memory shadow template struct BufferDeviceShadowedImpl : public BufferDeviceShadowed { // Bring these members into scope of derived class using BufferDeviceShadowed::device; using BufferDeviceShadowed::devPtr; // Inherit constructors BufferDeviceShadowedImpl(Device &device, std::size_t count); BufferDeviceShadowedImpl(Device &device, const std::vector &v); BufferDeviceShadowedImpl(Device &device, T *data, std::size_t count); ~BufferDeviceShadowedImpl() override; protected: // Copy between device and shadow buffers AsyncEvent memcpy(T *dest, const T *src, std::size_t count) override; }; template BufferDeviceShadowedImpl::BufferDeviceShadowedImpl( Device &device, std::size_t count) : BufferDeviceShadowed( device, static_cast(device.deviceMalloc(count * sizeof(T))), count) {} template BufferDeviceShadowedImpl::BufferDeviceShadowedImpl( Device &device, const std::vector &v) : BufferDeviceShadowed( device, static_cast(device.deviceMalloc(v.size() * sizeof(T))), v) {} template BufferDeviceShadowedImpl::BufferDeviceShadowedImpl( Device &device, T *data, std::size_t count) : BufferDeviceShadowed(device, static_cast(device.deviceMalloc(count * sizeof(T))), data, count) {} template BufferDeviceShadowedImpl::~BufferDeviceShadowedImpl() { device.free(devPtr); } template AsyncEvent BufferDeviceShadowedImpl::memcpy( T *dest, const T *src, std::size_t count) { return device.memcpy(dest, src, count * sizeof(T)); } } // namespace devicert } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/DifferentialGeometry.ih000066400000000000000000000042671464752671100254650ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "DGEnum.h" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct Renderer; /* differential geometry information that gives more detailed information on the actual geometry that a ray has hit */ struct DifferentialGeometry { vec3f P; // world space location of the hit-point, includes epsilon offset // towards front side vec3f lP; // local instance space location of the hit-point vec3f Ng; // geometry normal if DG_NG was set, possibly not // normalized/facefordwarded if DG_NORMALIZE and/or DG_FACEFORWARD // weren't specified vec3f Ns; // shading normal if DG_NS was set, possibly not // normalized/facefordwarded if DG_NORMALIZE and/or DG_FACEFORWARD // weren't specified vec3f dPds; // tangent, the partial derivative of the hit-point wrt. tc s vec3f dPdt; // bi-tangent, the partial derivative of the hit-point wrt. tc t vec2f st; // texture coordinates if DG_TEXCOORD was set vec4f color; // interpolated vertex color (rgba) if DG_COLOR was set; defaults // to vec4f(1.f) if queried but not present in geometry int32 primID; // hit primitive (-1 if no hit), e.g. for Ptex float areaPDF; // for geometryLights float epsilon; // adaptive epsilon, isotropic in object-space Material *material; // pointer to hit-point's material const Renderer *uniform renderer; // pointer to renderer being used unsigned int objID; // user definable model id (0xffff none) unsigned int instID; // user definable instance id (0xffff none) float pixelFootprint; // 1:1 mapping between pixels and texels }; // assumed precision of intersection routines #define ulpEpsilon 0x1.0fp-21f inline float calcEpsilon(const vec3f &P, float t) { return reduce_max(make_vec4f(abs(P), t)) * ulpEpsilon; } inline float calcEpsilon(const vec3f &P, const vec3f &dir, float t) { // convert ray-space t to object-/world-space using max(dir) instead of // costly length; the error is at most sqrt(3)~1.7, quite acceptable for eps return calcEpsilon(P, reduce_max(abs(dir)) * t); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/Embree.h000066400000000000000000000003511464752671100223710ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef OSPRAY_TARGET_SYCL #include #endif #ifdef ISPC #include "embree4/rtcore.isph" #else #include "embree4/rtcore.h" #endif RenderKit-ospray-85af292/modules/cpu/common/FeatureFlags.ih000066400000000000000000000026001464752671100237120ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef OSPRAY_TARGET_SYCL #include #endif #include "FeatureFlagsEnum.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; inline constexpr sycl::specialization_id specFeatureFlags; #endif struct FeatureFlagsHandler { #ifdef OSPRAY_TARGET_SYCL sycl::kernel_handler &kernel_handler; FeatureFlagsHandler(sycl::kernel_handler &kh) : kernel_handler(kh) {} #endif }; inline uniform FeatureFlags ffAll() { uniform FeatureFlags ff; ff.geometry = FFG_ALL; #ifdef OSPRAY_ENABLE_VOLUMES ff.volume = VKL_FEATURE_FLAGS_DEFAULT; #endif ff.other = FFO_ALL; return ff; } inline uniform FeatureFlags getFeatureFlags( const uniform FeatureFlagsHandler &ffh) { #ifdef OSPRAY_TARGET_SYCL return ffh.kernel_handler.get_specialization_constant(); #else return ffAll(); #endif } // For working around https://github.com/ispc/ispc/issues/2533 inline uniform FeatureFlagsGeometry getFeatureFlagsGeometry( const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); return ff.geometry; } inline uniform FeatureFlagsOther getFeatureFlagsOther( const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); return ff.other; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/FeatureFlagsEnum.h000066400000000000000000000133111464752671100243670ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef OSPRAY_ENABLE_VOLUMES #ifdef ISPC #include #else #include #endif #endif #include "common/Embree.h" #ifdef __cplusplus #include #include namespace ospray { #endif // __cplusplus enum FeatureFlagsGeometry #ifdef __cplusplus : uint32_t #endif { FFG_NONE = RTC_FEATURE_FLAG_NONE, FFG_MOTION_BLUR = RTC_FEATURE_FLAG_MOTION_BLUR, FFG_TRIANGLE = RTC_FEATURE_FLAG_TRIANGLE, FFG_QUAD = RTC_FEATURE_FLAG_QUAD, FFG_GRID = RTC_FEATURE_FLAG_GRID, FFG_SUBDIVISION = RTC_FEATURE_FLAG_SUBDIVISION, FFG_CONE_LINEAR_CURVE = RTC_FEATURE_FLAG_CONE_LINEAR_CURVE, FFG_ROUND_LINEAR_CURVE = RTC_FEATURE_FLAG_ROUND_LINEAR_CURVE, FFG_FLAT_LINEAR_CURVE = RTC_FEATURE_FLAG_FLAT_LINEAR_CURVE, FFG_LINEAR_CURVE = RTC_FEATURE_FLAG_LINEAR_CURVES, FFG_ROUND_BEZIER_CURVE = RTC_FEATURE_FLAG_ROUND_BEZIER_CURVE, FFG_FLAT_BEZIER_CURVE = RTC_FEATURE_FLAG_FLAT_BEZIER_CURVE, FFG_NORMAL_ORIENTED_BEZIER_CURVE = RTC_FEATURE_FLAG_NORMAL_ORIENTED_BEZIER_CURVE, FFG_BEZIER_CURVE = RTC_FEATURE_FLAG_BEZIER_CURVES, FFG_ROUND_BSPLINE_CURVE = RTC_FEATURE_FLAG_ROUND_BSPLINE_CURVE, FFG_FLAT_BSPLINE_CURVE = RTC_FEATURE_FLAG_FLAT_BSPLINE_CURVE, FFG_NORMAL_ORIENTED_BSPLINE_CURVE = RTC_FEATURE_FLAG_NORMAL_ORIENTED_BSPLINE_CURVE, FFG_BSPLINE_CURVE = RTC_FEATURE_FLAG_BSPLINE_CURVES, FFG_ROUND_HERMITE_CURVE = RTC_FEATURE_FLAG_ROUND_HERMITE_CURVE, FFG_FLAT_HERMITE_CURVE = RTC_FEATURE_FLAG_FLAT_HERMITE_CURVE, FFG_NORMAL_ORIENTED_HERMITE_CURVE = RTC_FEATURE_FLAG_NORMAL_ORIENTED_HERMITE_CURVE, FFG_HERMITE_CURVE = RTC_FEATURE_FLAG_HERMITE_CURVES, FFG_ROUND_CATMULL_ROM_CURVE = RTC_FEATURE_FLAG_ROUND_CATMULL_ROM_CURVE, FFG_FLAT_CATMULL_ROM_CURVE = RTC_FEATURE_FLAG_FLAT_CATMULL_ROM_CURVE, FFG_NORMAL_ORIENTED_CATMULL_ROM_CURVE = RTC_FEATURE_FLAG_NORMAL_ORIENTED_CATMULL_ROM_CURVE, FFG_CATMULL_ROM_CURVE = 0 | RTC_FEATURE_FLAG_ROUND_CATMULL_ROM_CURVE | RTC_FEATURE_FLAG_FLAT_CATMULL_ROM_CURVE | RTC_FEATURE_FLAG_NORMAL_ORIENTED_CATMULL_ROM_CURVE, FFG_SPHERE = RTC_FEATURE_FLAG_SPHERE_POINT, FFG_DISC_POINT = RTC_FEATURE_FLAG_DISC_POINT, FFG_ORIENTED_DISC_POINT = RTC_FEATURE_FLAG_ORIENTED_DISC_POINT, FFG_SPHERES = RTC_FEATURE_FLAG_POINT, FFG_CURVES = RTC_FEATURE_FLAG_CURVES, // OSPRay specific flags // repurposing unused flags below from Embree for FFG_BOX/PLANE/ISOSURFACE FFG_OSPRAY_MASK = 0 | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY | RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_GEOMETRY | RTC_FEATURE_FLAG_32_BIT_RAY_MASK, FFG_BOX = 0 | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY, FFG_PLANE = 0 | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS | RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_GEOMETRY, FFG_ISOSURFACE = 0 | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS | RTC_FEATURE_FLAG_32_BIT_RAY_MASK, FFG_ALL = RTC_FEATURE_FLAG_ALL }; enum FeatureFlagsOther #ifdef __cplusplus : uint32_t #endif { FFO_NONE = 0, FFO_FB_LOCAL = 1 << 0, FFO_FB_SPARSE = 1 << 1, FFO_CAMERA_PERSPECTIVE = 1 << 2, FFO_CAMERA_ORTHOGRAPHIC = 1 << 3, FFO_CAMERA_PANORAMIC = 1 << 4, FFO_LIGHT_AMBIENT = 1 << 5, FFO_LIGHT_CYLINDER = 1 << 6, FFO_LIGHT_DIRECTIONAL = 1 << 7, FFO_LIGHT_HDRI = 1 << 8, FFO_LIGHT_POINT = 1 << 9, FFO_LIGHT_QUAD = 1 << 10, FFO_LIGHT_SPOT = 1 << 11, FFO_LIGHT_GEOMETRY = 1 << 12, FFO_MATERIAL_ALLOY = 1 << 13, FFO_MATERIAL_CARPAINT = 1 << 14, FFO_MATERIAL_GLASS = 1 << 15, FFO_MATERIAL_LUMINOUS = 1 << 16, FFO_MATERIAL_METAL = 1 << 17, FFO_MATERIAL_METALLICPAINT = 1 << 18, FFO_MATERIAL_MIX = 1 << 19, FFO_MATERIAL_OBJ = 1 << 20, FFO_MATERIAL_PLASTIC = 1 << 21, FFO_MATERIAL_PRINCIPLED = 1 << 22, FFO_MATERIAL_THINGLASS = 1 << 23, FFO_MATERIAL_VELVET = 1 << 24, FFO_TEXTURE_IN_MATERIAL = 1 << 25, FFO_TEXTURE_IN_RENDERER = 1 << 26, // We track if there's a volume object in the scene separately from the volume // feature flags to distinguish between needing the volume rendering/sampling // code paths or just needing the isosurface traversal code path. FFO_VOLUME_IN_SCENE = 1 << 27, // Volume shading in SciVis renderer FFO_VOLUME_SCIVIS_SHADING = 1 << 28, FFO_CAMERA_MOTION_BLUR = 1 << 29, FFO_ALL = 0xffffffff }; struct FeatureFlags { FeatureFlagsGeometry geometry; FeatureFlagsOther other; #ifdef OSPRAY_ENABLE_VOLUMES VKLFeatureFlags volume; #endif #ifdef __cplusplus constexpr FeatureFlags() : geometry(FFG_NONE), other(FFO_NONE) #ifdef OSPRAY_ENABLE_VOLUMES , volume(VKL_FEATURE_FLAGS_NONE) #endif {} void reset() { geometry = FFG_NONE; other = FFO_NONE; #ifdef OSPRAY_ENABLE_VOLUMES volume = VKL_FEATURE_FLAGS_NONE; #endif } #endif }; #ifdef __cplusplus template ::value>::type> inline T operator|(T a, T b) { return static_cast(static_cast(a) | static_cast(b)); } template ::value>::type> inline T &operator|=(T &a, T b) { return a = a | b; } inline FeatureFlags operator|(const FeatureFlags &a, const FeatureFlags &b) { FeatureFlags ff; ff.geometry = a.geometry | b.geometry; #ifdef OSPRAY_ENABLE_VOLUMES ff.volume = a.volume | b.volume; #endif ff.other = a.other | b.other; return ff; } inline FeatureFlags &operator|=(FeatureFlags &a, const FeatureFlags &b) { a.geometry |= b.geometry; #ifdef OSPRAY_ENABLE_VOLUMES a.volume |= b.volume; #endif a.other |= b.other; return a; } #endif #ifdef __cplusplus } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/common/FilterIntersect.ih000066400000000000000000000062021464752671100244520ustar00rootroot00000000000000// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Intersect.ih" #include "Ray.ih" #include "RayQueryContext.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #ifndef OSPRAY_TARGET_SYCL unmasked void clippingIntersectionFilterV( const RTCFilterFunctionNArguments *uniform args); inline bool filterCall(const RTCIntersectFunctionNArguments *uniform args, const RTCHit &rtcHitTemp) { varying int imask; varying bool mask = __mask; unmasked { imask = mask ? -1 : 0; } // call filter intersection callback uniform RTCFilterFunctionNArguments filterArgs; filterArgs.valid = (int *uniform) & imask; filterArgs.geometryUserPtr = args->geometryUserPtr; filterArgs.context = args->context; filterArgs.ray = (RTCRayN * uniform) args->rayhit; filterArgs.hit = (RTCHitN * uniform) & rtcHitTemp; filterArgs.N = args->N; clippingIntersectionFilterV(&filterArgs); // return true if hit has been accepted return imask == -1; } #endif inline bool filterIntersectionSingle( const RTCIntersectFunctionNArguments *uniform args, const Hit &hit, const uniform bool isOcclusionTest, const uniform bool alwaysReject) { // if there is a hit varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; if (hit.hit && hit.t > ray->t0 && hit.t <= ray->t) { // set a new hit value const float tOld = ray->t; ray->t = hit.t; // prepare temporary hit structure RTCHit rtcHitTemp; rtcHitTemp.Ng_x = hit.N.x; rtcHitTemp.Ng_y = hit.N.y; rtcHitTemp.Ng_z = hit.N.z; rtcHitTemp.u = hit.u; rtcHitTemp.v = 0.f; rtcHitTemp.primID = args->primID; rtcHitTemp.geomID = args->geomID; rtcHitTemp.instID[0] = args->context->instID[0]; // call filter intersection callback if needed #ifndef OSPRAY_TARGET_SYCL RayQueryContextDefault *uniform ctx = (RayQueryContextDefault * uniform) args->context; const uniform bool noFilter = ctx->type != RQCT_CLIPPING; const bool accept = noFilter || filterCall(args, rtcHitTemp); #else const bool accept = true; #endif if (alwaysReject) { // the hit is always rejected ray->t = tOld; } else { if (accept) { // hit has been accepted if (isOcclusionTest) { ray->t = neg_inf; } else { ray->Ng.x = hit.N.x; ray->Ng.y = hit.N.y; ray->Ng.z = hit.N.z; ray->u = hit.u; ray->v = 0.f; ray->primID = args->primID; ray->geomID = args->geomID; ray->instID = args->context->instID[0]; } return true; } else { // the hit has been rejected in the filter function, // restore initial ray dimensions ray->t = tOld; } } } // no hit or not accepted return false; } inline bool filterIntersectionBoth( const RTCIntersectFunctionNArguments *uniform args, const Intersections &isect, const uniform bool isOcclusionTest) { if (!filterIntersectionSingle(args, isect.entry, isOcclusionTest, false)) { return filterIntersectionSingle(args, isect.exit, isOcclusionTest, false); } return true; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/Future.cpp000066400000000000000000000004521464752671100230010ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Future.h" namespace ospray { Future::Future() { managedObjectType = OSP_FUTURE; } std::string Future::toString() const { return "ospray::Future"; } OSPTYPEFOR_DEFINITION(Future *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Future.h000066400000000000000000000011121464752671100224400ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "./Managed.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Future : public ManagedObject { Future(); ~Future() override = default; std::string toString() const override; virtual bool isFinished(OSPSyncEvent = OSP_TASK_FINISHED) = 0; virtual void wait(OSPSyncEvent = OSP_TASK_FINISHED) = 0; virtual void cancel() = 0; virtual float getProgress() = 0; virtual float getTaskDuration() = 0; }; OSPTYPEFOR_SPECIALIZATION(Future *, OSP_FUTURE); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Group.cpp000066400000000000000000000147031464752671100226270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Group.h" #include "ISPCDevice.h" #include "geometry/GeometricModel.h" #include "lights/Light.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/VolumetricModel.h" #endif namespace ospray { // Embree helper functions ////////////////////////////////////////////////// template inline void createEmbreeScene(RTCScene &scene, FeatureFlags &featureFlags, const DataT &objects, const int embreeFlags, const RTCBuildQuality buildQuality) { for (auto &&obj : objects) { rtcAttachGeometry(scene, obj->embreeGeometryHandle()); featureFlags |= obj->getFeatureFlags(); } rtcSetSceneFlags(scene, static_cast(embreeFlags)); rtcSetSceneBuildQuality(scene, buildQuality); } static void freeAndNullifyEmbreeScene(RTCScene &scene) { if (scene) rtcReleaseScene(scene); scene = nullptr; } // Group definitions //////////////////////////////////////////////////////// Group::Group(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { managedObjectType = OSP_GROUP; } Group::~Group() { freeAndNullifyEmbreeScene(sceneGeometries); #ifdef OSPRAY_ENABLE_VOLUMES freeAndNullifyEmbreeScene(sceneVolumes); #endif freeAndNullifyEmbreeScene(sceneClippers); getSh()->geometricModels = nullptr; #ifdef OSPRAY_ENABLE_VOLUMES getSh()->volumetricModels = nullptr; #endif getSh()->clipModels = nullptr; } std::string Group::toString() const { return "ospray::Group"; } void Group::commit() { geometricModels = getParamDataT("geometry"); #ifdef OSPRAY_ENABLE_VOLUMES volumetricModels = getParamDataT("volume"); #endif clipModels = getParamDataT("clippingGeometry"); lights = getParamDataT("light"); size_t numGeometries = geometricModels ? geometricModels->size() : 0; #ifdef OSPRAY_ENABLE_VOLUMES size_t numVolumes = volumetricModels ? volumetricModels->size() : 0; #endif 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, " #ifdef OSPRAY_ENABLE_VOLUMES << numVolumes << " volumes, " #endif << numClippers << " clipping geometries and " << numLights << " lights"; int sceneFlags = RTC_SCENE_FLAG_NONE; RTCBuildQuality buildQuality = RTC_BUILD_QUALITY_HIGH; if (getParam("dynamicScene", false)) { sceneFlags |= RTC_SCENE_FLAG_DYNAMIC; buildQuality = RTC_BUILD_QUALITY_LOW; } sceneFlags |= (getParam("compactMode", false) ? RTC_SCENE_FLAG_COMPACT : 0); sceneFlags |= (getParam("robustMode", false) ? RTC_SCENE_FLAG_ROBUST : 0); freeAndNullifyEmbreeScene(sceneGeometries); #ifdef OSPRAY_ENABLE_VOLUMES freeAndNullifyEmbreeScene(sceneVolumes); #endif freeAndNullifyEmbreeScene(sceneClippers); geometricModelsArray = nullptr; #ifdef OSPRAY_ENABLE_VOLUMES volumetricModelsArray = nullptr; #endif clipModelsArray = nullptr; getSh()->geometricModels = nullptr; #ifdef OSPRAY_ENABLE_VOLUMES getSh()->volumetricModels = nullptr; #endif getSh()->clipModels = nullptr; RTCDevice embreeDevice = getISPCDevice().getEmbreeDevice(); if (!embreeDevice) { throw std::runtime_error("invalid Embree device"); } featureFlags.reset(); if (numGeometries > 0) { sceneGeometries = rtcNewScene(embreeDevice); createEmbreeScene(sceneGeometries, featureFlags, *geometricModels, sceneFlags, buildQuality); geometricModelsArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), createArrayOfSh(*geometricModels)); getSh()->geometricModels = geometricModelsArray->sharedPtr(); rtcCommitScene(sceneGeometries); } #ifdef OSPRAY_ENABLE_VOLUMES if (numVolumes > 0) { sceneVolumes = rtcNewScene(embreeDevice); createEmbreeScene(sceneVolumes, featureFlags, *volumetricModels, sceneFlags, buildQuality); volumetricModelsArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), createArrayOfSh(*volumetricModels)); getSh()->volumetricModels = volumetricModelsArray->sharedPtr(); rtcCommitScene(sceneVolumes); } #endif if (numClippers > 0) { sceneClippers = rtcNewScene(embreeDevice); createEmbreeScene(sceneClippers, featureFlags, *clipModels, sceneFlags | RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS | RTC_SCENE_FLAG_ROBUST, buildQuality); clipModelsArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), createArrayOfSh(*clipModels)); getSh()->clipModels = clipModelsArray->sharedPtr(); numInvertedClippers = 0; for (auto &&obj : *clipModels) numInvertedClippers += obj->invertedNormals() ? 1 : 0; rtcCommitScene(sceneClippers); } getSh()->numGeometricModels = numGeometries; #ifdef OSPRAY_ENABLE_VOLUMES getSh()->numVolumetricModels = numVolumes; #endif getSh()->numClipModels = numClippers; if (numLights > 0) { // Gather light types for (auto &&light : *lights) featureFlags |= light->getFeatureFlags(); // 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 ((numGeometries == 0) #ifdef OSPRAY_ENABLE_VOLUMES && (numVolumes == 0) #endif && (numClippers == 0)) { sceneGeometries = rtcNewScene(embreeDevice); rtcCommitScene(sceneGeometries); } } } box3f Group::getBounds() const { box3f sceneBounds; box4f bounds; // NOTE(jda) - Embree expects box4f, NOT box3f... if (sceneGeometries) { rtcGetSceneBounds(sceneGeometries, (RTCBounds *)&bounds); sceneBounds.extend(box3f(vec3f(&bounds.lower[0]), vec3f(&bounds.upper[0]))); } #ifdef OSPRAY_ENABLE_VOLUMES if (sceneVolumes) { rtcGetSceneBounds(sceneVolumes, (RTCBounds *)&bounds); sceneBounds.extend(box3f(vec3f(&bounds.lower[0]), vec3f(&bounds.upper[0]))); } #endif return sceneBounds; } OSPTYPEFOR_DEFINITION(Group *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Group.h000066400000000000000000000030151464752671100222660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray stuff #include "Data.h" #include "FeatureFlagsEnum.h" #include "ISPCDeviceObject.h" #include "StructShared.h" // stl #include // ispc shared #include "GroupShared.h" namespace ospray { struct GeometricModel; #ifdef OSPRAY_ENABLE_VOLUMES struct VolumetricModel; #endif struct Light; struct OSPRAY_SDK_INTERFACE Group : public AddStructShared { Group(api::ISPCDevice &device); ~Group() override; std::string toString() const override; void commit() override; box3f getBounds() const override; // Data members // Ref> geometricModels; #ifdef OSPRAY_ENABLE_VOLUMES Ref> volumetricModels; #endif Ref> clipModels; int numInvertedClippers{0}; Ref> lights; RTCScene sceneGeometries{nullptr}; #ifdef OSPRAY_ENABLE_VOLUMES RTCScene sceneVolumes{nullptr}; #endif RTCScene sceneClippers{nullptr}; const FeatureFlags &getFeatureFlags() const; private: FeatureFlags featureFlags; BufferSharedUq geometricModelsArray; #ifdef OSPRAY_ENABLE_VOLUMES BufferSharedUq volumetricModelsArray; #endif BufferSharedUq clipModelsArray; }; OSPTYPEFOR_SPECIALIZATION(Group *, OSP_GROUP); inline const FeatureFlags &Group::getFeatureFlags() const { return featureFlags; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/GroupShared.h000066400000000000000000000014161464752671100234200ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct GeometricModel; #ifdef OSPRAY_ENABLE_VOLUMES struct VolumetricModel; #endif struct Group { GeometricModel **geometricModels; int32 numGeometricModels; #ifdef OSPRAY_ENABLE_VOLUMES VolumetricModel **volumetricModels; int32 numVolumetricModels; #endif GeometricModel **clipModels; int32 numClipModels; #ifdef __cplusplus Group() : geometricModels(nullptr), numGeometricModels(0), #ifdef OSPRAY_ENABLE_VOLUMES volumetricModels(nullptr), numVolumetricModels(0), #endif clipModels(nullptr), numClipModels(0) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/common/Instance.cpp000066400000000000000000000040331464752671100232720ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Instance.h" namespace ospray { Instance::Instance(api::ISPCDevice &device, Group *_group) : AddStructShared(device.getDRTDevice(), device), groupAPI(_group) { managedObjectType = OSP_INSTANCE; } std::string Instance::toString() const { return "ospray::Instance"; } void Instance::commit() { group = getParamObject("group", groupAPI.ptr); if (!group) throw std::runtime_error(toString() + " received NULL 'group'"); motionTransform.readParams(*this); // Initialize shared structure getSh()->group = group->getSh(); getSh()->xfm = motionTransform.transform; getSh()->rcp_xfm = rcp(getSh()->xfm); getSh()->motionBlur = motionTransform.motionBlur; getSh()->userID = getParam("id", RTC_INVALID_GEOMETRY_ID); } box3f Instance::getBounds() const { box3f bounds; const box3f groupBounds = group->getBounds(); // TODO get better bounds: // - 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 // - 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; } void Instance::setEmbreeGeom(RTCScene scene, unsigned int geomID) { RTCGeometry geom = rtcGetGeometry(scene, geomID); motionTransform.setEmbreeTransform(geom); getSh()->scene = scene; getSh()->geomID = geomID; if (getSh()->motionBlur) { rtcGetGeometryTransformFromScene(scene, geomID, .5f, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &getSh()->xfm); // for SciVis getSh()->rcp_xfm = rcp(getSh()->xfm); } } OSPTYPEFOR_DEFINITION(Instance *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Instance.h000066400000000000000000000013401464752671100227350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray stuff #include "Group.h" #include "MotionTransform.h" // ispc shared #include "InstanceShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Instance : public AddStructShared { Instance(api::ISPCDevice &device, Group *group); ~Instance() override = default; std::string toString() const override; void commit() override; box3f getBounds() const override; void setEmbreeGeom(RTCScene scene, unsigned int geomID); Ref group; const Ref groupAPI; MotionTransform motionTransform; }; OSPTYPEFOR_SPECIALIZATION(Instance *, OSP_INSTANCE); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/Instance.ih000066400000000000000000000063041464752671100231130ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray stuff #include "../geometry/GeometricModel.ih" #include "DifferentialGeometry.ih" #include "OSPCommon.ih" #include "Ray.ih" // c++ shared #include "GroupShared.h" #include "InstanceShared.h" #include "common/FeatureFlagsEnum.h" #include "rkcommon/math/AffineSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Renderer; inline uniform AffineSpace3f Instance_getTransform( const Instance *uniform self, const uniform float time) { uniform AffineSpace3f xfm; rtcGetGeometryTransformFromScene( self->scene, self->geomID, time, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm); return xfm; } #ifndef OSPRAY_TARGET_SYCL inline AffineSpace3f Instance_getTransform( const Instance *uniform self, const float time) { AffineSpace3f xfm; rtcGetGeometryTransformFromScene( self->scene, self->geomID, time, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm); return xfm; } #endif inline void Instance_postIntersect(const Instance *uniform self, const Renderer *uniform renderer, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform bool clip, const uniform FeatureFlagsHandler &ffh) { GeometricModel **uniform models = clip ? self->group->clipModels : self->group->geometricModels; foreach_unique (geomID in ray.geomID) GeometricModel_postIntersect(models[geomID], renderer, dg, ray, flags, ffh); dg.instID = (self->userID == RTC_INVALID_GEOMETRY_ID) ? ray.instID : self->userID; uniform AffineSpace3f uxfm = self->xfm; uniform AffineSpace3f rcp_uxfm = self->rcp_xfm; const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); if ((flags & DG_MOTIONBLUR) == DG_MOTIONBLUR && self->motionBlur && (ffg & FFG_MOTION_BLUR)) { uniform float utime = 0.f; uniform int cnt = 0; foreach_unique (t in ray.time) { utime = t; cnt++; } if (cnt > 1) { // varying xfm const AffineSpace3f xfm = Instance_getTransform(self, ray.time); const AffineSpace3f rcp_xfm = rcp(xfm); dg.lP = xfmPoint(rcp_xfm, dg.P); dg.Ns = xfmVector(transposed(rcp_xfm.l), dg.Ns); dg.Ng = xfmVector(transposed(rcp_xfm.l), dg.Ng); // scale dg.epsilon by max (epsilon is scalar and thus assumed to be // isotropic anyway and hence cannot better handle non-uniform scaling) dg.epsilon *= max(abs(xfm.l.vx.x), max(abs(xfm.l.vy.y), abs(xfm.l.vz.z))); if (flags & DG_TANGENTS) { dg.dPds = xfmVector(xfm, dg.dPds); dg.dPdt = xfmVector(xfm, dg.dPdt); } return; } else { // uniform xfm uxfm = Instance_getTransform(self, utime); rcp_uxfm = rcp(uxfm); } } dg.lP = xfmPoint(rcp_uxfm, dg.P); dg.Ns = xfmVector(transposed(rcp_uxfm.l), dg.Ns); dg.Ng = xfmVector(transposed(rcp_uxfm.l), dg.Ng); // scale dg.epsilon by max (epsilon is scalar and thus assumed to be // isotropic anyway and hence cannot better handle non-uniform scaling) dg.epsilon *= max(abs(uxfm.l.vx.x), max(abs(uxfm.l.vy.y), abs(uxfm.l.vz.z))); if (flags & DG_TANGENTS) { dg.dPds = xfmVector(uxfm, dg.dPds); dg.dPdt = xfmVector(uxfm, dg.dPdt); } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/InstanceShared.h000066400000000000000000000012701464752671100240660ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Group; struct Instance { Group *group; // Scene and geomID are used to call rtcGetGeometryTransformFromScene only RTCScene scene; unsigned int geomID; AffineSpace3f xfm; AffineSpace3f rcp_xfm; bool motionBlur; // user defined id. Typically used for picking uint32 userID; #ifdef __cplusplus Instance() : group(nullptr), scene(nullptr), geomID(0), xfm(one), rcp_xfm(one), motionBlur(false), userID(-1u) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/common/Intersect.ih000066400000000000000000000162061464752671100233110ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/box.ih" // Ray intersection structures ////////////////////////////////////////////// OSPRAY_BEGIN_ISPC_NAMESPACE struct Hit { bool hit; float t; vec3f N; float u; }; struct Intersections { Hit entry; Hit exit; }; // Ray intersection helpers /////////////////////////////////////////////////// // robust ray-sphere intersection inline Intersections intersectSphere(const vec3f &rayOrg, const vec3f &rayDir, const uniform vec3f ¢er, const uniform float radius) { Intersections isect; isect.entry.hit = false; isect.exit.hit = false; isect.entry.t = inf; isect.exit.t = -(float)inf; const vec3f d = rayDir; const float rd2 = 1.0f / dot(d, d); // 1/a const vec3f CO = center - rayOrg; // transformation to avoid missing a small sphere which is far away: // the standard c=CO^2-r^2 would quickly loose term r due to float arithmetic const float projCO = dot(CO, d) * rd2; // in ray-space const vec3f perp = CO - projCO * d; const float l2 = dot(perp, perp); const uniform float r2 = sqr(radius); if (l2 > r2) return isect; float td = sqrt((r2 - l2) * rd2); isect.entry.hit = true; isect.exit.hit = true; isect.entry.t = projCO - td; isect.exit.t = projCO + td; // above solutions are problematic if rays starts close to the sphere // (due to catastrophic cancellation, because then |projCO| ~ td) // the usual recommendation is to choose the one solution with same sign: // const float t1 = projCO + floatbits(signbits(projCO)|intbits(td)); // and compute the other solution via t1*t2=c/a: // const float t2 = (dot(CO, CO) - r2) / t1 * rd2; // this is more precise, but still problematic in particular for large // spheres, because |CO| ~ r; slightly better alternative, but costly sqrt: // const float f = sqrt(dot(CO, CO)); // const float t2 = (f - radius) * (f + radius) / t1 * rd2; // the only variant I found that has high enough precision to avoid // self-intersections of 2ndary rays is to (re-)compute most terms (CO, dot, // r2, t2) with doubles; large spheres are a rare usecase for OSPRay, thus we // use instead as a workaround an additional, radius-dependent epsilon // cannot easily be moved to postIntersect // we need hit in object space, in postIntersect it is in world-space isect.entry.N = -td * d - perp; isect.exit.N = td * d - perp; return isect; } inline Intersections intersectCylinder(const vec3f &rayOrg, const vec3f &rayDir, const uniform vec3f &v0, const uniform vec3f &v1, const uniform float radius) { Intersections isect; isect.entry.hit = false; isect.exit.hit = false; isect.entry.t = inf; isect.exit.t = -(float)inf; const uniform vec3f cZ = v1 - v0; const vec3f q = rayOrg - v0; 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; } radical = sqrt(radical); const float tin = (-B - radical) / A; const float tout = (-B + radical) / A; // 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.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.f : 1.f; isect.entry.N = cZ * us / z2; } } // 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.f : 1.f; isect.exit.N = cZ * us / z2; } } return isect; } inline Intersections intersectCapsule(const vec3f &rayOrg, const vec3f &rayDir, const uniform vec3f &v0, const uniform vec3f &v1, const uniform float radius) { Intersections isect_pipe = intersectCylinder(rayOrg, rayDir, v0, v1, radius); const Intersections isect_sph1 = intersectSphere(rayOrg, rayDir, v0, radius); const Intersections isect_sph2 = intersectSphere(rayOrg, rayDir, v1, radius); const float t_in = min(min(isect_sph1.entry.t, isect_sph2.entry.t), isect_pipe.entry.t); const float t_out = max(max(isect_sph1.exit.t, isect_sph2.exit.t), isect_pipe.exit.t); isect_pipe.entry.hit |= isect_sph1.entry.hit | isect_sph2.entry.hit; isect_pipe.entry.t = t_in; isect_pipe.exit.hit |= isect_sph1.exit.hit | isect_sph2.exit.hit; isect_pipe.exit.t = t_out; if (isect_sph1.entry.t == t_in) { isect_pipe.entry.u = 0.f; isect_pipe.entry.N = isect_sph1.entry.N; } else if (isect_sph2.entry.t == t_in) { isect_pipe.entry.u = 1.f; isect_pipe.entry.N = isect_sph2.entry.N; } if (isect_sph1.exit.t == t_out) { isect_pipe.exit.u = 0.f; isect_pipe.exit.N = isect_sph1.exit.N; } else if (isect_sph2.exit.t == t_out) { isect_pipe.exit.u = 1.f; isect_pipe.exit.N = isect_sph2.exit.N; } return isect_pipe; } inline Intersections intersectBox( const vec3f &rayOrg, const vec3f &rayDir, const uniform box3f &box) { Intersections isect; const vec3f mins = (box.lower - rayOrg) * rcp_safe(rayDir); const vec3f maxs = (box.upper - rayOrg) * rcp_safe(rayDir); const vec3f nears = min(mins, maxs); const vec3f fars = max(mins, maxs); isect.entry.t = reduce_max(nears); if (isect.entry.t == nears.x) isect.entry.N = make_vec3f(rayDir.x > 0.0f ? -1.0f : 1.0f, 0.0f, 0.0f); else if (isect.entry.t == nears.y) isect.entry.N = make_vec3f(0.0f, rayDir.y > 0.0f ? -1.0f : 1.0f, 0.0f); else isect.entry.N = make_vec3f(0.0f, 0.0f, rayDir.z > 0.0f ? -1.0f : 1.0f); isect.exit.t = reduce_min(fars); if (isect.exit.t == fars.x) isect.exit.N = make_vec3f(rayDir.x > 0.0f ? 1.0f : -1.0f, 0.0f, 0.0f); else if (isect.exit.t == fars.y) isect.exit.N = make_vec3f(0.0f, rayDir.y > 0.0f ? 1.0f : -1.0f, 0.0f); else isect.exit.N = make_vec3f(0.0f, 0.0f, rayDir.z > 0.0f ? 1.0f : -1.0f); isect.entry.hit = isect.entry.t < isect.exit.t; isect.exit.hit = isect.entry.hit; return isect; } inline Hit intersectPlane( const vec3f &rayOrg, const vec3f &rayDir, const uniform vec4f &plane) { Hit hit; hit.hit = false; const uniform vec3f normal = make_vec3f(plane); const float DdN = dot(rayDir, normal); hit.hit = DdN != 0.0f; hit.N = normal; hit.t = (plane.w - dot(rayOrg, normal)) * rcpf(DdN); return hit; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/MotionTransform.cpp000066400000000000000000000062721464752671100246760ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "MotionTransform.h" namespace ospray { void MotionTransform::readParams(ISPCDeviceObject &obj) { 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))); } } 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 RenderKit-ospray-85af292/modules/cpu/common/MotionTransform.h000066400000000000000000000010431464752671100243320ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray stuff #include "Group.h" // embree #include "Embree.h" namespace ospray { struct OSPRAY_SDK_INTERFACE MotionTransform { void readParams(ISPCDeviceObject &); void setEmbreeTransform(RTCGeometry) const; affine3f transform{one}; bool motionBlur{false}; bool quaternion{false}; private: Ref> transforms; std::vector quaternions; range1f time{0.0f, 1.0f}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/OSPCommon.ih000066400000000000000000000160341464752671100231620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" #define STRING(x) #x #define TOSTRING(x) STRING(x) #define CODE_LOCATION __FILE__ " (" TOSTRING(__LINE__) ")" #ifdef OSPRAY_TARGET_SYCL #include #define __noinline __attribute__((noinline)) #define in , #define foreach_unique(var_in_set) FOREACH_UNIQUE(var_in_set) #define FOREACH_UNIQUE(var, set) for (const auto &var : {set}) namespace ispc { using uint64 = uint64_t; using uint32 = uint32_t; using uint16 = uint16_t; using uint8 = uint8_t; using int64 = int64_t; using int32 = int32_t; using int16 = int16_t; using int8 = int8_t; } // namespace ispc #define PING \ sycl::ext::oneapi::experimental::printf(CODE_LOCATION ": " __FUNCTION__ "\n") #undef PRINT #undef PRINTV // Skip printing in host code. #define PRINT(x) #define PRINTV(x) // Note: SYCL printf needs the type specifier, unlike ISPC. So, we need // overloaded functions to print based on the type of the parameter. We use a // wrapper macro to extract argument's name as a char string to print both name // and value of the variable. #ifdef __SYCL_DEVICE_ONLY__ // rkcommon has its own macros for the host that we conflict with #undef PRINT #undef PRINTV #define CONSTANT __attribute__((opencl_constant)) void print_(const CONSTANT char *name, const int &x) { sycl::ext::oneapi::experimental::printf("%s = %d\n", name, x); } void print_(const CONSTANT char *name, const float &x) { sycl::ext::oneapi::experimental::printf("%s = %f\n", name, x); } void print_(const CONSTANT char *name, const uint32_t &x) { sycl::ext::oneapi::experimental::printf("%s = %u\n", name, x); } void print_(const CONSTANT char *name, const ispc::vec2i &v) { sycl::ext::oneapi::experimental::printf("%s = (%d, %d)\n", name, v.x, v.y); } void print_(const CONSTANT char *name, const ispc::vec2f &v) { sycl::ext::oneapi::experimental::printf("%s = (%f, %f)\n", name, v.x, v.y); } void print_(const CONSTANT char *name, const ispc::vec3i &v) { sycl::ext::oneapi::experimental::printf( "%s = (%d, %d, %d)\n", name, v.x, v.y, v.z); } void print_(const CONSTANT char *name, const ispc::vec3f &v) { sycl::ext::oneapi::experimental::printf( "%s = (%f, %f, %f)\n", name, v.x, v.y, v.z); } void print_(const CONSTANT char *name, const ispc::vec4i &v) { sycl::ext::oneapi::experimental::printf( "%s = (%d, %d, %d, %d)\n", name, v.x, v.y, v.z, v.w); } void print_(const CONSTANT char *name, const ispc::vec4f &v) { sycl::ext::oneapi::experimental::printf( "%s = (%f, %f, %f, %f)\n", name, v.x, v.y, v.z, v.w); } void print_(const CONSTANT char *name, const CONSTANT char *s) { sycl::ext::oneapi::experimental::printf("%s = %s\n", name, s); } #define PRINT(x) \ { \ static const CONSTANT char var_name[] = #x; \ print_(var_name, x); \ } // SYCL is scalar, PRINTV = PRINT #define PRINTV(x) PRINT(x); #endif #else // ISPC #define PING print(CODE_LOCATION "\n") #define __noinline noinline inline void printv_(const int &x) { print("%\n", x); } inline void printv_(const float &x) { print("%\n", x); } inline void printv_(const uint32 &x) { print("%\n", x); } inline void printv_(const vec2i &v) { print("(%, %)\n", v.x, v.y); } inline void printv_(const vec2f &v) { print("(%, %)\n", v.x, v.y); } inline void printv_(const vec3i &v) { print("(% % %)\n", v.x, v.y, v.z); } inline void printv_(const vec3f &v) { print("(% % %)\n", v.x, v.y, v.z); } inline void printv_(const vec4i &v) { print("(% % % %)\n", v.x, v.y, v.z, v.w); } inline void printv_(const vec4f &v) { print("(% % % %)\n", v.x, v.y, v.z, v.w); } #define PRINTV(x) \ { \ print(#x " = "); \ printv_(x); \ } inline void print_(const int &x) { print("[%] = %\n", count_trailing_zeros(lanemask()), extract(x, count_trailing_zeros(lanemask()))); } inline void print_(const float &x) { print("[%] = %\n", count_trailing_zeros(lanemask()), extract(x, count_trailing_zeros(lanemask()))); } inline void print_(const uint32 &x) { print("[%] = %\n", count_trailing_zeros(lanemask()), extract(x, count_trailing_zeros(lanemask()))); } inline void print_(const vec2i &v) { print("[%] = (%, %)\n", count_trailing_zeros(lanemask()), extract(v.x, count_trailing_zeros(lanemask())), extract(v.y, count_trailing_zeros(lanemask()))); } inline void print_(const vec2f &v) { print("[%] = (%, %)\n", count_trailing_zeros(lanemask()), extract(v.x, count_trailing_zeros(lanemask())), extract(v.y, count_trailing_zeros(lanemask()))); } inline void print_(const vec3i &v) { print("[%] = (%, %, %)\n", count_trailing_zeros(lanemask()), extract(v.x, count_trailing_zeros(lanemask())), extract(v.y, count_trailing_zeros(lanemask())), extract(v.z, count_trailing_zeros(lanemask()))); } inline void print_(const vec3f &v) { print("[%] = (%, %, %)\n", count_trailing_zeros(lanemask()), extract(v.x, count_trailing_zeros(lanemask())), extract(v.y, count_trailing_zeros(lanemask())), extract(v.z, count_trailing_zeros(lanemask()))); } inline void print_(const vec4i &v) { print("[%] = (%, %, %, %)\n", count_trailing_zeros(lanemask()), extract(v.x, count_trailing_zeros(lanemask())), extract(v.y, count_trailing_zeros(lanemask())), extract(v.z, count_trailing_zeros(lanemask())), extract(v.w, count_trailing_zeros(lanemask()))); } inline void print_(const vec4f &v) { print("[%] = (%, %, %, %)\n", count_trailing_zeros(lanemask()), extract(v.x, count_trailing_zeros(lanemask())), extract(v.y, count_trailing_zeros(lanemask())), extract(v.z, count_trailing_zeros(lanemask())), extract(v.w, count_trailing_zeros(lanemask()))); } #define PRINT(x) \ { \ print(#x); \ print_(x); \ } #define PRINT_STR(s) print(#s " = %\n", s); #endif #ifndef OSPRAY_TARGET_SYCL /*! 64-bit malloc. allows for alloc'ing memory larger than 64 bits */ extern "C" void *uniform malloc64(uniform uint64 size); extern "C" void free64(void *uniform ptr); /*! Thread Local Storage functions */ extern "C" void *uniform pushTLS(uniform uint64 size); extern "C" void *uniform reallocTLS(void *uniform ptr, uniform uint64 size); extern "C" void popTLS(void *uniform ptr); #endif RenderKit-ospray-85af292/modules/cpu/common/OSPConfig.h.in000066400000000000000000000003541464752671100233710ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define TILE_SIZE @OSPRAY_TILE_SIZE@ #define MAX_TILE_SIZE @OSPRAY_MAX_STACK_TILE_SIZE@ #define OSPRAY_RENDER_TASK_SIZE @OSPRAY_RENDER_TASK_SIZE@ RenderKit-ospray-85af292/modules/cpu/common/Ray.ih000066400000000000000000000044261464752671100221050ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "rkcommon/math/AffineSpace.ih" #include "rkcommon/math/vec.ih" // embree #include "Embree.h" OSPRAY_BEGIN_ISPC_NAMESPACE // NOTE(jda) - this MUST match Embree's RayHit structure layout! struct Ray { /* ray input data */ vec3f org; /*!< ray origin */ float t0; /*!< start of valid ray interval */ vec3f dir; /*!< ray direction */ float time; //!< Time of this ray for motion blur, in 0..1 float t; /*!< end of valid ray interval, or distance to hit point after 'intersect' */ uint32 mask; //!< Used to mask out objects during traversal uint32 rayID; uint32 flags; /* hit data */ vec3f Ng; /*! geometry normal*/ float u; //!< Barycentric u coordinate of hit float v; //!< Barycentric v coordinate of hit uint32 primID; //!< primitive ID uint32 geomID; //!< geometry ID uint32 instID; //!< instance ID #ifdef RTC_GEOMETRY_INSTANCE_ARRAY uint32 instPrimID; // not used, but need to pad #endif }; // Hit query functions //////////////////////////////////////////////////////// inline bool noHit(const Ray &ray) { return ray.geomID == RTC_INVALID_GEOMETRY_ID; } inline bool hadHit(const Ray &ray) { return !noHit(ray); } // Ray initialization ///////////////////////////////////////////////////////// inline void setRay(Ray &ray, const vec3f &ray_org, const vec3f &ray_dir, const float t0, const float t1, const float time = 0.5f) { ray.org = ray_org; ray.dir = ray_dir; ray.t0 = t0; ray.t = t1; ray.time = time; ray.mask = -1; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.instID = RTC_INVALID_GEOMETRY_ID; } inline void setRay(Ray &ray, const vec3f &ray_org, const vec3f &ray_dir, const float time = 0.5f) { setRay(ray, ray_org, ray_dir, 0.f, inf, time); } inline void setRay(Ray &ray, const float t0, const float t1) { setRay(ray, ray.org, ray.dir, t0, t1, ray.time); } // Ray transformation helpers ///////////////////////////////////////////////// inline void transformRay(Ray &ray, const AffineSpace3f &xfm) { ray.org = xfmPoint(xfm, ray.org); ray.dir = xfmVector(xfm, ray.dir); ray.Ng = xfmVector(transposed(xfm.l), ray.Ng); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/RayCone.ih000066400000000000000000000006141464752671100227050ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once OSPRAY_BEGIN_ISPC_NAMESPACE struct RayCone { float width; // current width (perpendicular to ray, calculated at the // intersection points) float dwdt; // change of width per unit distance, i.e. the slope corresponding // to the spread angle }; OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/RayQueryContext.ih000066400000000000000000000013051464752671100244710ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "FeatureFlags.ih" // embree #include "Embree.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; #endif enum RayQueryContextType { RQCT_DEFAULT, RQCT_CLIPPING, RQCT_UNKNOWN }; struct RayQueryContextDefault { RTCRayQueryContext ectx; RayQueryContextType type; const FeatureFlagsHandler *uniform ffh; }; inline void initRayQueryContextDefault(RayQueryContextDefault *uniform context, const uniform FeatureFlagsHandler &ffh) { rtcInitRayQueryContext(&context->ectx); context->type = RQCT_DEFAULT; context->ffh = &ffh; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/StructShared.h000066400000000000000000000106201464752671100236050ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include "rkcommon/common.h" #include "rkcommon/math/rkmath.h" #include "rkcommon/math/vec.h" #include "DeviceRT.h" namespace ispc { // Shared structure members may use types from rkcommon using namespace rkcommon; using namespace rkcommon::math; // Shared structure members may use ispc specific types using uint8 = uint8_t; using int32 = int32_t; using uint32 = uint32_t; using int64 = int64_t; static_assert(sizeof(bool) == 1, "Sharing structs with ISPC not possible, because different sizes of 'bool'."); } // namespace ispc namespace ospray { /* Usage: derive from AddStructShared We use multiple inheritance with a virtual base class, thus only a single instance of StructSharedPtr is present, which will be initialized first. StructSharedGet adds getSh returning the correctly typed pointer. It is derived from first to handle the memory allocation with the maximum size of the final StructShared. StructSharedGet does not have any data to ensure final classes can be C-style casted to ManagedObject* (this pointer stays the same). */ template inline T *StructSharedCreate(devicert::Device &device) { return new (device.sharedMalloc(sizeof(T))) T; } struct StructSharedPtr { StructSharedPtr() : _device(nullptr), _ptr(nullptr) {} ~StructSharedPtr(); template friend struct StructSharedGet; template friend struct AddStructShared; private: devicert::Device *_device; void *_ptr; }; template struct StructSharedGet { StructSharedGet(devicert::Device &, devicert::Device **, void **); T *getSh() const; }; // Traits ///////////////////////////////////////////////////// template struct make_void { using type = void; }; template using void_t = typename make_void::type; template struct get_base_structshared_or { using type = S; }; template struct get_base_structshared_or> { using type = typename T::StructShared_t; }; template struct get_super_or { using type = S; }; template struct get_super_or> { using type = decltype(S::super); }; // AddStructShared //////////////////////////////////////////// template struct AddStructShared : public StructSharedGet>, public Base, public virtual StructSharedPtr { using StructShared_t = Struct; using StructSharedGet>::getSh; static_assert( std::is_same::type, typename get_super_or::type>::value, "StructShared_t needs to have 'super' member of type Base::StructShared_t"); template AddStructShared(devicert::Device &device, Args &&...args) : StructSharedGet>( device, &_device, &_ptr), Base(std::forward(args)...) {} }; // Inlined definitions //////////////////////////////////////// inline StructSharedPtr::~StructSharedPtr() { _device->free(_ptr); } template StructSharedGet::StructSharedGet( devicert::Device &device, devicert::Device **_device, void **_ptr) { if (!*_ptr) { *_ptr = (void *)StructSharedCreate(device); *_device = &device; } } template T *StructSharedGet::getSh() const { return static_cast(static_cast(this)->_ptr); } // Testing //////////////////////////////////////////////////// namespace test { // clang-format off struct A {}; struct B { char b; }; struct D1 { B super; }; struct D2 { D1 super; char c; }; struct ShouldPass1 : public AddStructShared {}; struct ShouldPass2 : public AddStructShared {}; struct ShouldPass3 : public AddStructShared {}; //struct ShouldFail1 : public AddStructShared {}; //struct ShouldFail2 : public AddStructShared {}; //struct ShouldFail3 : public AddStructShared {}; // clang-format on } // namespace test } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/VolumeIntervals.ih000066400000000000000000000031541464752671100245060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "Instance.ih" #include "OSPCommon.ih" #include "rkcommon/math/AffineSpace.ih" #include "rkcommon/math/box.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct VolumetricModel; // Volume hit structure /////////////////////////////////////////////////////// struct VolumeInterval { VolumetricModel *volumetricModel; Instance *instance; range1f interval; unsigned int primID; unsigned int geomID; unsigned int instID; }; inline void initVolumeInterval(VolumeInterval &hit) { hit.volumetricModel = NULL; hit.interval.lower = inf; hit.interval.upper = -hit.interval.lower; } inline bool hasInterval(const VolumeInterval &vi) { return !isEmpty(vi.interval); } struct VolumeIntervals { unsigned int numVolumeIntervals; uniform unsigned int numAllocated; varying VolumeInterval *uniform intervals; }; #ifndef OSPRAY_TARGET_SYCL inline void allocVolumeIntervals(VolumeIntervals &intervals) { intervals.numVolumeIntervals = 0; intervals.numAllocated = 0; intervals.intervals = (varying VolumeInterval * uniform) pushTLS(0); } inline void freeVolumeIntervals(VolumeIntervals &intervals) { popTLS(intervals.intervals); intervals.intervals = NULL; } #endif struct RayQueryContextVolume { RTCRayQueryContext ectx; varying VolumeIntervals *intervals; }; inline void InitRayQueryContextVolume(RayQueryContextVolume *uniform context, varying VolumeIntervals *uniform intervals) { rtcInitRayQueryContext(&context->ectx); context->intervals = intervals; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/common/World.cpp000066400000000000000000000135631464752671100226250ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "World.h" #include "Instance.h" #include "common/FeatureFlagsEnum.h" #include "lights/Light.h" #include "render/pathtracer/PathTracerData.h" #include "render/scivis/SciVisData.h" namespace ospray { // Embree helper functions /////////////////////////////////////////////////// static void addGeometryInstance(RTCScene &scene, RTCScene instScene, Instance *inst, RTCDevice embreeDevice, unsigned int id) { if (!embreeDevice) throw std::runtime_error("invalid Embree device"); // Create parent scene if not yet created if (!scene) scene = rtcNewScene(embreeDevice); // Create geometry instance auto eInst = rtcNewGeometry(embreeDevice, RTC_GEOMETRY_TYPE_INSTANCE); rtcSetGeometryInstancedScene(eInst, instScene); rtcAttachGeometryByID(scene, eInst, id); inst->setEmbreeGeom(scene, id); rtcReleaseGeometry(eInst); } static void freeAndNullifyEmbreeScene(RTCScene &scene) { if (scene) rtcReleaseScene(scene); scene = nullptr; } // World definitions //////////////////////////////////////////////////////// World::~World() { // Release Embree scenes freeAndNullifyEmbreeScene(getSh()->embreeSceneHandleGeometries); #ifdef OSPRAY_ENABLE_VOLUMES freeAndNullifyEmbreeScene(getSh()->embreeSceneHandleVolumes); #endif #ifndef OSPRAY_TARGET_SYCL freeAndNullifyEmbreeScene(getSh()->embreeSceneHandleClippers); #endif } World::World(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { managedObjectType = OSP_WORLD; } std::string World::toString() const { return "ospray::World"; } void World::commit() { RTCScene &esGeom = getSh()->embreeSceneHandleGeometries; #ifdef OSPRAY_ENABLE_VOLUMES RTCScene &esVol = getSh()->embreeSceneHandleVolumes; #endif #ifndef OSPRAY_TARGET_SYCL RTCScene &esClip = getSh()->embreeSceneHandleClippers; #endif freeAndNullifyEmbreeScene(esGeom); #ifdef OSPRAY_ENABLE_VOLUMES freeAndNullifyEmbreeScene(esVol); #endif #ifndef OSPRAY_TARGET_SYCL freeAndNullifyEmbreeScene(esClip); #endif scivisData = nullptr; pathtracerData = nullptr; instances = getParamDataT("instance"); lights = getParamDataT("light"); auto numInstances = instances ? instances->size() : 0; int sceneFlags = RTC_SCENE_FLAG_NONE; RTCBuildQuality buildQuality = RTC_BUILD_QUALITY_HIGH; if (getParam("dynamicScene", false)) { sceneFlags |= RTC_SCENE_FLAG_DYNAMIC; buildQuality = RTC_BUILD_QUALITY_LOW; } sceneFlags |= (getParam("compactMode", false) ? RTC_SCENE_FLAG_COMPACT : 0); sceneFlags |= (getParam("robustMode", false) ? RTC_SCENE_FLAG_ROBUST : 0); postStatusMsg(OSP_LOG_DEBUG) << "=======================================================\n" << "Committing world, which has " << numInstances << " instances and " << (lights ? lights->size() : 0) << " lights"; instanceArray = nullptr; getSh()->numInvertedClippers = 0; RTCDevice embreeDevice = getISPCDevice().getEmbreeDevice(); if (instances) { for (auto &&inst : *instances) #ifndef OSPRAY_TARGET_SYCL if (inst->group->sceneClippers) getSh()->numInvertedClippers += inst->group->numInvertedClippers; #endif // Create shared buffers for instance pointers instanceArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), sizeof(ispc::Instance *) * numInstances); getSh()->instances = instanceArray->sharedPtr(); // Populate shared buffer with instance pointers, // create Embree instances featureFlags.reset(); unsigned int id = 0; for (auto &&inst : *instances) { getSh()->instances[id] = inst->getSh(); if (inst->group->sceneGeometries) { addGeometryInstance( esGeom, inst->group->sceneGeometries, inst, embreeDevice, id); } #ifdef OSPRAY_ENABLE_VOLUMES if (inst->group->sceneVolumes) { addGeometryInstance( esVol, inst->group->sceneVolumes, inst, embreeDevice, id); } #endif #ifndef OSPRAY_TARGET_SYCL if (inst->group->sceneClippers) { addGeometryInstance( esClip, inst->group->sceneClippers, inst, embreeDevice, id); } #endif // Gather feature flags from all groups const FeatureFlags &gff = inst->group->getFeatureFlags(); if (inst->motionTransform.motionBlur) featureFlags.geometry |= FFG_MOTION_BLUR; featureFlags |= gff; id++; } } // Gather light types if (lights) { for (auto &&light : *lights) { featureFlags |= light->getFeatureFlags(); } } if (esGeom) { rtcSetSceneFlags(esGeom, static_cast(sceneFlags)); rtcSetSceneBuildQuality(esGeom, buildQuality); rtcCommitScene(esGeom); } #ifdef OSPRAY_ENABLE_VOLUMES if (esVol) { rtcSetSceneFlags(esVol, static_cast(sceneFlags)); rtcSetSceneBuildQuality(esVol, buildQuality); rtcCommitScene(esVol); } #endif #ifndef OSPRAY_TARGET_SYCL if (esClip) { rtcSetSceneFlags(esClip, static_cast( sceneFlags | RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS)); rtcSetSceneBuildQuality(esClip, buildQuality); rtcCommitScene(esClip); } #endif } box3f World::getBounds() const { box3f sceneBounds; box4f bounds; // NOTE(jda) - Embree expects box4f, NOT box3f... if (getSh()->embreeSceneHandleGeometries) { rtcGetSceneBounds( getSh()->embreeSceneHandleGeometries, (RTCBounds *)&bounds); sceneBounds.extend(box3f(vec3f(&bounds.lower[0]), vec3f(&bounds.upper[0]))); } #ifdef OSPRAY_ENABLE_VOLUMES if (getSh()->embreeSceneHandleVolumes) { rtcGetSceneBounds(getSh()->embreeSceneHandleVolumes, (RTCBounds *)&bounds); sceneBounds.extend(box3f(vec3f(&bounds.lower[0]), vec3f(&bounds.upper[0]))); } #endif return sceneBounds; } OSPTYPEFOR_DEFINITION(World *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/World.h000066400000000000000000000021151464752671100222610ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray stuff #include "Data.h" #include "FeatureFlagsEnum.h" #include "ISPCDeviceObject.h" // stl #include // ispc shared #include "WorldShared.h" namespace ospray { struct Instance; struct Light; struct PathTracerData; struct SciVisData; struct OSPRAY_SDK_INTERFACE World : public AddStructShared { World(api::ISPCDevice &device); virtual ~World() override; std::string toString() const override; void commit() override; box3f getBounds() const override; const FeatureFlags &getFeatureFlags() const; // Data members // Ref> instances; Ref> lights; BufferSharedUq instanceArray; std::unique_ptr scivisData; std::unique_ptr pathtracerData; private: FeatureFlags featureFlags; }; OSPTYPEFOR_SPECIALIZATION(World *, OSP_WORLD); inline const FeatureFlags &World::getFeatureFlags() const { return featureFlags; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/common/World.ih000066400000000000000000000334061464752671100224410ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray stuff #include "common/Clipping.ih" #include "common/DGEnum.h" #include "common/DifferentialGeometry.ih" #include "common/FeatureFlags.ih" #include "common/Instance.ih" #include "common/Ray.ih" #include "common/RayCone.ih" #include "common/RayQueryContext.ih" #include "common/VolumeIntervals.ih" #include "geometry/GeometryDispatch.ih" #include "volume/Volume.ih" // c++ shared #include "WorldShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; #endif struct Renderer; inline void traceGeometryRay(const World *uniform world, varying Ray &ray, const uniform FeatureFlagsHandler &ffh) { // Skip if no geometries scene if (!world->embreeSceneHandleGeometries) return; const uniform FeatureFlags ff = getFeatureFlags(ffh); uniform RayQueryContextDefault context; initRayQueryContextDefault(&context, ffh); uniform RTCIntersectArguments intersectArgs; rtcInitIntersectArguments(&intersectArgs); intersectArgs.context = &context.ectx; intersectArgs.intersect = (RTCIntersectFunctionN)Geometry_dispatch_intersect; intersectArgs.feature_mask = (uniform RTCFeatureFlags)( (ff.geometry & ~FFG_OSPRAY_MASK) | RTC_FEATURE_FLAG_INSTANCE); rtcIntersectV(world->embreeSceneHandleGeometries, (varying RTCRayHit * uniform) & ray, &intersectArgs); } #ifdef OSPRAY_ENABLE_VOLUMES inline void traceVolumeRay( const World *uniform world, varying Ray &ray, VolumeInterval &interval) { initVolumeInterval(interval); if (!world->embreeSceneHandleVolumes) return; VolumeIntervals intervals; #ifdef OSPRAY_TARGET_SYCL // We don't have access to TLS/dynamic memory on the kernel, so we only // support one interval on the GPU (i.e., no overlapping volumes) intervals.numVolumeIntervals = 0; intervals.numAllocated = 1; intervals.intervals = &interval; #else allocVolumeIntervals(intervals); #endif uniform RayQueryContextVolume context; InitRayQueryContextVolume(&context, &intervals); uniform RTCIntersectArguments intersectArgs; rtcInitIntersectArguments(&intersectArgs); intersectArgs.context = &context.ectx; intersectArgs.intersect = (RTCIntersectFunctionN)Volume_intersect_kernel; intersectArgs.feature_mask = RTC_FEATURE_FLAG_INSTANCE | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS; rtcIntersectV(world->embreeSceneHandleVolumes, (varying RTCRayHit * uniform) & ray, &intersectArgs); // In the SYCL case we write to the interval parameter directly. In the // non-sycl case we need to get the first interval to return to the caller if (intervals.numVolumeIntervals > 0 && hasInterval(intervals.intervals[0])) { interval.instance = *(world->instances + intervals.intervals[0].instID); interval.volumetricModel = interval.instance->group ->volumetricModels[intervals.intervals[0].geomID]; interval.interval = intervals.intervals[0].interval; } #ifndef OSPRAY_TARGET_SYCL freeVolumeIntervals(intervals); #endif } inline void traceVolumeRay( const World *uniform world, varying Ray &ray, VolumeIntervals &intervals) { if (!world->embreeSceneHandleVolumes) return; uniform RayQueryContextVolume context; InitRayQueryContextVolume(&context, &intervals); uniform RTCIntersectArguments intersectArgs; rtcInitIntersectArguments(&intersectArgs); intersectArgs.context = &context.ectx; intersectArgs.intersect = (RTCIntersectFunctionN)Volume_intersect_kernel; intersectArgs.feature_mask = RTC_FEATURE_FLAG_INSTANCE | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS; rtcIntersectV(world->embreeSceneHandleVolumes, (varying RTCRayHit * uniform) & ray, &intersectArgs); if (intervals.numVolumeIntervals > 0) { for (uniform uint32 i = 0; i < intervals.numVolumeIntervals; ++i) { Instance *instance = *(world->instances + intervals.intervals[i].instID); intervals.intervals[i].instance = instance; intervals.intervals[i].volumetricModel = instance->group->volumetricModels[intervals.intervals[i].geomID]; } } } #endif // Intersection context structure used for clipping geometries struct RayQueryContextClipping { uniform RayQueryContextDefault super; const World *uniform world; varying int32 corrClippingDepth; varying uint32 hitsCount; varying ClippingHit hits[CLIPPING_HITS_MAX_COUNT]; }; unmasked void clippingIntersectionFilterV( const RTCFilterFunctionNArguments *uniform args); inline void traceClippingRay(const World *uniform world, varying Ray &ray, varying RayIntervals &rayIntervals, const uniform FeatureFlagsHandler &ffh) { // Clipping disabled on GPU for now #ifdef OSPRAY_TARGET_SYCL (void)world; (void)ffh; rayIntervals.intervals[0] = make_box1f(ray.t0, ray.t); rayIntervals.count = 1; return; #else // A scene with clipping geometries has to exist if (!world->embreeSceneHandleClippers) { rayIntervals.intervals[0] = make_box1f(ray.t0, ray.t); rayIntervals.count = 1; return; } // Create and initialize intersection context RayQueryContextClipping context; rtcInitRayQueryContext(&context.super.ectx); context.super.type = RQCT_CLIPPING; context.super.ffh = &ffh; context.world = world; context.corrClippingDepth = 0; context.hitsCount = 0; // Create and initialize intersection arguments uniform RTCIntersectArguments intersectArgs; rtcInitIntersectArguments(&intersectArgs); intersectArgs.context = &context.super.ectx; intersectArgs.intersect = (RTCIntersectFunctionN)Geometry_dispatch_intersect; intersectArgs.filter = clippingIntersectionFilterV; intersectArgs.flags = RTC_RAY_QUERY_FLAG_INVOKE_ARGUMENT_FILTER; // Intersect all geometry along given ray, // we have to temporarily extend the ray to inf because // even distant intersections affect visibility of close objects float origT = ray.t; ray.t = inf; rtcIntersectV(world->embreeSceneHandleClippers, (varying RTCRayHit * uniform) & ray, &intersectArgs); ray.t = origT; // Set initial clipping depth, // we have to apply correction because ray origin can be inside clipping area const uniform int32 voidClippingDepth = world->numInvertedClippers; int32 clippingDepth = voidClippingDepth - context.corrClippingDepth; // Variables used for intervals construction uint32 intervalId = 0; bool intervalCompleted = true; // Start ray interval if not in clipping area if (clippingDepth == 0) { rayIntervals.intervals[intervalId].lower = ray.t0; intervalCompleted = false; } // Iterate through collected hits and build ray intervals for (uint32 i = 0; i < context.hitsCount; i++) { // Do not build ray intervals that are further than ray.t float t = context.hits[i].t; float absT = abs(t); if (absT > ray.t) break; // Check if coming into or out of clipping area if (t < 0.0f) { clippingDepth--; // out of clipping area } else { clippingDepth++; // into clipping area } // Start interval if previous one is closed and we are not in clipping area if (clippingDepth == 0 && intervalCompleted) { rayIntervals.intervals[intervalId].lower = absT; intervalCompleted = false; } // End interval if current one is not closed and we enter clipping area if (clippingDepth > 0 && !intervalCompleted) { rayIntervals.intervals[intervalId].upper = absT; intervalCompleted = true; intervalId++; } } // Complete ray interval if started if (!intervalCompleted) { rayIntervals.intervals[intervalId].upper = ray.t; intervalId++; } // Save number of ray intervals rayIntervals.count = intervalId; #endif } inline void traceGeometryRayIntervals(const World *uniform world, Ray &ray, RayIntervals &rayIntervals, const uniform FeatureFlagsHandler &ffh) { // Save the ray const float t0 = ray.t0; const float t = ray.t; // Iterate through ray intervals for (uint32 i = 0; i < rayIntervals.count; i++) { // Set ray interval ray.t0 = rayIntervals.intervals[i].lower; ray.t = rayIntervals.intervals[i].upper; // Skip intervals outside of the ray range if (t < ray.t0 || ray.t < t0) { ray.t0 = t0; ray.t = t; continue; } // Clip interval to the ray range ray.t0 = max(ray.t0, t0); ray.t = min(ray.t, t); // Shoot the ray traceGeometryRay(world, ray, ffh); // Exit loop if geometry hit if (hadHit(ray)) { ray.t0 = t0; return; } } // Restore the ray ray.t0 = t0; ray.t = t; } inline void traceRay(const World *uniform world, varying Ray &ray, const uniform FeatureFlagsHandler &ffh) { #ifdef OSPRAY_TARGET_SYCL // Clipping disabled for now traceGeometryRay(world, ray, ffh); #else // Fast path if no clipping geometry if (!world->embreeSceneHandleClippers) { traceGeometryRay(world, ray, ffh); return; } // Trace ray in clipping geometries scene, fill array with ray intervals varying RayIntervals rayIntervals; traceClippingRay(world, ray, rayIntervals, ffh); // Trace ray intervals traceGeometryRayIntervals(world, ray, rayIntervals, ffh); #endif } inline bool isOccludedNoClipping(const World *uniform world, varying Ray &ray, const uniform FeatureFlagsHandler &ffh) { // Skip if no geometries scene if (!world->embreeSceneHandleGeometries) return false; const uniform FeatureFlags ff = getFeatureFlags(ffh); uniform RayQueryContextDefault context; initRayQueryContextDefault(&context, ffh); uniform RTCOccludedArguments occludedArgs; rtcInitOccludedArguments(&occludedArgs); occludedArgs.context = &context.ectx; occludedArgs.occluded = (RTCOccludedFunctionN)Geometry_dispatch_occluded; occludedArgs.feature_mask = (uniform RTCFeatureFlags)( (ff.geometry & ~FFG_OSPRAY_MASK) | RTC_FEATURE_FLAG_INSTANCE); rtcOccludedV(world->embreeSceneHandleGeometries, (varying RTCRay * uniform) & ray, &occludedArgs); return ray.t < ray.t0; } inline bool areIntervalsOccluded(const World *uniform world, varying Ray &ray, varying RayIntervals &rayIntervals, const uniform FeatureFlagsHandler &ffh) { // Iterate through ray intervals for (uint32 i = 0; i < rayIntervals.count; i++) { // Set ray interval ray.t0 = rayIntervals.intervals[i].lower; ray.t = rayIntervals.intervals[i].upper; // Check for occluders if (isOccludedNoClipping(world, ray, ffh)) return true; } // No occluder found return false; } inline bool isOccluded(const World *uniform world, varying Ray &ray, const uniform FeatureFlagsHandler &ffh) { #ifdef OSPRAY_TARGET_SYCL // Clipping disabled for now return isOccludedNoClipping(world, ray, ffh); #else // Fast path if no clipping geometry if (!world->embreeSceneHandleClippers) { return isOccludedNoClipping(world, ray, ffh); } // Allocate array for ray intervals varying RayIntervals rayIntervals; rayIntervals.count = 0; // Trace ray in clipping geometries scene, fill array with ray intervals traceClippingRay(world, ray, rayIntervals, ffh); // Is there any occluder within given ray intervals return areIntervalsOccluded(world, ray, rayIntervals, ffh); #endif } /*! Perform post-intersect computations, i.e. fill the members of DifferentialGeometry. Should only get called for rays that actually hit that given world. Variables are calculated according to 'flags', a bit-combination of DG_PostIntersectFlags. The ray, dg.P, dg.Ng, and dg.Ns are in world-coordinates. Color defaults to vec4f(1.f) if queried but not present in geometry. */ inline void postIntersect(const World *uniform world, const Renderer *uniform renderer, varying DifferentialGeometry &dg, const varying Ray &ray, varying RayCone &rayCone, uniform int64 flags, const uniform FeatureFlagsHandler &ffh) { dg.primID = ray.primID; dg.st = make_vec2f(ray.u, ray.v); dg.material = NULL; dg.renderer = renderer; if (flags & DG_COLOR) dg.color = make_vec4f(1.f); if (flags & DG_TANGENTS) { dg.dPds = make_vec3f(1.f, 0.f, 0.f); dg.dPdt = make_vec3f(0.f, 1.f, 0.f); } dg.P = ray.org + ray.t * ray.dir; dg.epsilon = 0.f; // per default no geometry-type specific epsilon foreach_unique (instID in ray.instID) { if (instID != RTC_INVALID_GEOMETRY_ID) { Instance *uniform instance = *(world->instances + instID); Instance_postIntersect(instance, renderer, dg, ray, flags, false, ffh); } else { dg.Ns = dg.Ng = ray.Ng; } } // merge geometry-type specific epsilon with general epsilon dg.epsilon = max(dg.epsilon, calcEpsilon(dg.P, ray.dir, ray.t)); // some useful combinations; enums unfortunately don't work :-( #define DG_NG_FACEFORWARD (DG_NG | DG_FACEFORWARD) #define DG_NS_FACEFORWARD (DG_NS | DG_FACEFORWARD) #define DG_NG_NORMALIZE (DG_NG | DG_NORMALIZE) #define DG_NS_NORMALIZE (DG_NS | DG_NORMALIZE) vec3f ffnng = normalize(dg.Ng); if ((flags & DG_NG_NORMALIZE) == DG_NG_NORMALIZE) dg.Ng = ffnng; if ((flags & DG_NS_NORMALIZE) == DG_NS_NORMALIZE) dg.Ns = normalize(dg.Ns); const bool flip = dot(ray.dir, dg.Ng) >= 0.f; if (flip) ffnng = neg(ffnng); if ((flags & DG_NG_FACEFORWARD) == DG_NG_FACEFORWARD && flip) dg.Ng = neg(dg.Ng); if ((flags & DG_NS_FACEFORWARD) == DG_NS_FACEFORWARD) { if (dot(dg.Ng, dg.Ns) < 0.f) dg.Ns = neg(dg.Ns); } #undef DG_NG_FACEFORWARD #undef DG_NS_FACEFORWARD #undef DG_NG_NORMALIZE #undef DG_NS_NORMALIZE dg.P = dg.P + dg.epsilon * ffnng; rayCone.width += rayCone.dwdt * ray.t; // propagate to hit const float texArea = length(cross(dg.dPds, dg.dPdt)); const float world2tex = rsqrtf(texArea); const float projConeWidth = rayCone.width / -dot(ray.dir, dg.Ng); dg.pixelFootprint = projConeWidth * world2tex; dg.pixelFootprint *= renderer->mipBiasFactor; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/World.ispc000066400000000000000000000064061464752671100227770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "World.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #ifndef OSPRAY_TARGET_SYCL unmasked void clippingIntersectionFilterV( const RTCFilterFunctionNArguments *uniform args) { // Set execution mask uniform int *uniform valid = args->valid; if (!valid[programIndex]) return; // Get pointer to the intersection context RayQueryContextClipping *uniform context = (RayQueryContextClipping * uniform) args->context; // We skip this intersection to collect all remaining intersections valid[programIndex] = 0; // Skip if array is full if (context->hitsCount >= CLIPPING_HITS_MAX_COUNT) return; // Get ray and hit varying Ray *uniform ray = (varying Ray * uniform) args->ray; varying const RTCHit *uniform hit = (varying const RTCHit *uniform)args->hit; // Prepare clipping normal vec3f Nc; { // The postIntersect function needs the hit part of the Ray structure to be // initialized. Making a ray copy here is quite costly. That is why just // the necessary ray fields are set here. DifferentialGeometry dg; ray->Ng = make_vec3f(hit->Ng_x, hit->Ng_y, hit->Ng_z); ray->u = hit->u; ray->v = hit->v; ray->primID = hit->primID; ray->geomID = hit->geomID; // We need to call postIntersect on clipping geometry foreach_unique (instID in hit->instID[0]) { // Call postIntersect to get shading normal Instance *uniform instance = *(context->world->instances + instID); Instance_postIntersect( instance, NULL, dg, *ray, DG_NG | DG_NS, true, *context->super.ffh); // Use geometry normal for clipping // but use shading normal to check if inversion is needed Nc = (dot(dg.Ns, dg.Ng) > 0.f) ? ray->Ng : neg(ray->Ng); } // Restore IDs initial values ray->primID = RTC_INVALID_GEOMETRY_ID; ray->geomID = RTC_INVALID_GEOMETRY_ID; } // Based on clipping normal vector decide if the ray is // entering clipping geometry (set positive hit value) or exiting clipping // geometry (set negative hit value) const bool exitsClipping = (dot(ray->dir, Nc) > 0.f); ClippingHit cHit; cHit.t = (exitsClipping) ? -ray->t : ray->t; cHit.primID = hit->primID; cHit.geomID = hit->geomID; cHit.instID = hit->instID[0]; // Some geometry types (e.g. curves, subdivisions) // may give more than 2 intersections, we have to filter them out for (uint32 i = 0; i < context->hitsCount; i++) { if ((context->hits[i].primID == cHit.primID) && (context->hits[i].geomID == cHit.geomID) && (context->hits[i].instID == cHit.instID) && floatUlpCompare(context->hits[i].t, cHit.t, 512)) return; } // Now we know that this intersection will be taken into account, // so we can update clipping depth correction value accordingly if (exitsClipping) { context->corrClippingDepth--; } else { context->corrClippingDepth++; } // Insert hit value into sorted array for (uint32 i = 0; i < context->hitsCount; i++) { if (abs(context->hits[i].t) > abs(cHit.t)) { const ClippingHit tmp = context->hits[i]; context->hits[i] = cHit; cHit = tmp; } } context->hits[context->hitsCount] = cHit; context->hitsCount++; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/common/WorldShared.h000066400000000000000000000017401464752671100234130ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/pathtracer/PathTracerDataShared.h" #include "render/scivis/SciVisDataShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Instance; struct World { Instance **instances; int32 numInvertedClippers; RTCScene embreeSceneHandleGeometries; #ifdef OSPRAY_ENABLE_VOLUMES RTCScene embreeSceneHandleVolumes; #endif #ifndef OSPRAY_TARGET_SYCL RTCScene embreeSceneHandleClippers; #endif SciVisData *scivisData; PathTracerData *pathtracerData; #ifdef __cplusplus World() : instances(nullptr), numInvertedClippers(0), embreeSceneHandleGeometries(nullptr), #ifdef OSPRAY_ENABLE_VOLUMES embreeSceneHandleVolumes(nullptr), #endif #ifndef OSPRAY_TARGET_SYCL embreeSceneHandleClippers(nullptr), #endif scivisData(nullptr), pathtracerData(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/def_header.txt000066400000000000000000000000101464752671100223300ustar00rootroot00000000000000EXPORTS RenderKit-ospray-85af292/modules/cpu/fb/000077500000000000000000000000001464752671100201215ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/fb/FrameBuffer.cpp000066400000000000000000000122031464752671100230070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "FrameBuffer.h" #include "FrameOp.h" #include "OSPConfig.h" #include "fb/FrameBufferView.h" #ifndef OSPRAY_TARGET_SYCL #include "ISPCDevice_ispc.h" #endif namespace { // Internal utilities for thread local progress tracking thread_local int threadLastFrameID = -1; thread_local uint32_t threadNumPixelsRendered = 0; extern "C" uint32_t *getThreadNumPixelsRendered() { return &threadNumPixelsRendered; } extern "C" int *getThreadLastFrameID() { return &threadLastFrameID; } }; // namespace namespace ospray { FrameBuffer::FrameBuffer(api::ISPCDevice &device, const vec2i &_size, ColorBufferFormat _colorBufferFormat, const uint32 channels, const FeatureFlagsOther ffo) : AddStructShared(device.getDRTDevice(), device), size(_size), colorBufferFormat(_colorBufferFormat), hasColorBuffer(channels & OSP_FB_COLOR), hasDepthBuffer(channels & OSP_FB_DEPTH), hasVarianceBuffer((channels & OSP_FB_COLOR) && (channels & OSP_FB_VARIANCE) && (channels & OSP_FB_ACCUM)), hasNormalBuffer(channels & OSP_FB_NORMAL), hasAlbedoBuffer(channels & OSP_FB_ALBEDO), hasPrimitiveIDBuffer(channels & OSP_FB_ID_PRIMITIVE), hasObjectIDBuffer(channels & OSP_FB_ID_OBJECT), hasInstanceIDBuffer(channels & OSP_FB_ID_INSTANCE), doAccum(channels & OSP_FB_ACCUM), featureFlags(ffo) { managedObjectType = OSP_FRAMEBUFFER; if (_size.x <= 0 || _size.y <= 0) { throw std::runtime_error( "framebuffer has invalid size. Dimensions must be greater than 0"); } getSh()->size = _size; getSh()->rcpSize = vec2f(1.f) / vec2f(_size); getSh()->channels = channels; getSh()->accumulateVariance = false; getSh()->targetFrames = !doAccum; #if OSPRAY_RENDER_TASK_SIZE == -1 #ifdef OSPRAY_TARGET_SYCL vec2i renderTaskSize(8); #else // Compute render task size based on the simd width to get as "square" as // possible a task size that has simdWidth pixels const int simdWidth = ispc::ISPCDevice_programCount(); vec2i renderTaskSize(simdWidth, 1); while (renderTaskSize.x / 2 > renderTaskSize.y) { renderTaskSize.y *= 2; renderTaskSize.x /= 2; } #endif #else // Note: we could also allow changing this at runtime if we want to add this // to the API vec2i renderTaskSize(OSPRAY_RENDER_TASK_SIZE); #endif getSh()->renderTaskSize = renderTaskSize; } void FrameBuffer::commit() { imageOpData = getParamDataT("imageOperation"); // always query `targetFrames` to clear query status getSh()->targetFrames = max(0, getParam("targetFrames", 0)); if (!doAccum) getSh()->targetFrames = 1; } void FrameBuffer::clear() { getSh()->frameID = -1; // we increment at the start of the frame if (hasVarianceBuffer) { mtGen.seed(mtSeed); // reset the RNG with same seed frameVariance = inf; } } vec2i FrameBuffer::getRenderTaskSize() const { return getSh()->renderTaskSize; } float FrameBuffer::getVariance() const { return frameVariance; } void FrameBuffer::beginFrame() { cancelRender = false; getSh()->frameID = doAccum ? getSh()->frameID + 1 : 0; #ifndef OSPRAY_TARGET_SYCL // TODO: Cancellation isn't supported on the GPU getSh()->cancelRender = 0; // TODO: Maybe better as a kernel to avoid USM thrash to host getSh()->numPixelsRendered = 0; #endif if (hasVarianceBuffer) { // collect half of the samples // To not run into correlation issues with low discrepancy sequences used // in renders, we randomly pick whether the even or the odd frame is // accumulated into the variance buffer. const bool evenFrame = (getSh()->frameID & 1) == 0; if (evenFrame) pickOdd = mtGen() & 1; // coin flip every other frame getSh()->accumulateVariance = evenFrame != pickOdd; } } std::string FrameBuffer::toString() const { return "ospray::FrameBuffer"; } void FrameBuffer::setCompletedEvent(OSPSyncEvent event) { #ifndef OSPRAY_TARGET_SYCL // We won't be running ISPC-side rendering tasks when updating the // progress values here in C++ if (event == OSP_NONE_FINISHED) getSh()->numPixelsRendered = 0; if (event == OSP_FRAME_FINISHED) getSh()->numPixelsRendered = getNumPixels().long_product(); #endif stagesCompleted = event; } OSPSyncEvent FrameBuffer::getLatestCompleteEvent() const { return stagesCompleted; } void FrameBuffer::waitForEvent(OSPSyncEvent event) const { // TODO: condition variable to sleep calling thread instead of spinning? while (stagesCompleted < event) ; } float FrameBuffer::getCurrentProgress() const { #ifdef OSPRAY_TARGET_SYCL // TODO: Continually polling this will cause a lot of USM thrashing return 0.f; #else return static_cast(getSh()->numPixelsRendered) / getNumPixels().long_product(); #endif } void FrameBuffer::cancelFrame() { cancelRender = true; // TODO: Cancellation isn't supported on the GPU #ifndef OSPRAY_TARGET_SYCL getSh()->cancelRender = 1; #endif } bool FrameBuffer::frameCancelled() const { return cancelRender; } uint32 FrameBuffer::getChannelFlags() const { return getSh()->channels; } OSPTYPEFOR_DEFINITION(FrameBuffer *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/FrameBuffer.h000066400000000000000000000124401464752671100224570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "ISPCDeviceObject.h" #include "common/Data.h" #include "common/FeatureFlagsEnum.h" #include "fb/ImageOp.h" #include "ospray/ospray.h" #include "rkcommon/utility/ArrayView.h" // ispc shared #include "FrameBufferShared.h" #include #include namespace ospray { struct Camera; struct FrameBufferView; // abstract frame buffer class struct OSPRAY_SDK_INTERFACE FrameBuffer : public AddStructShared { // app-mappable format of the color buffer. make sure that this // matches the definition on the ISPC side using ColorBufferFormat = OSPFrameBufferFormat; FrameBuffer(api::ISPCDevice &device, const vec2i &size, ColorBufferFormat colorBufferFormat, const uint32 channels, const FeatureFlagsOther ffo); virtual ~FrameBuffer() override = default; virtual void commit() override; virtual const void *mapBuffer(OSPFrameBufferChannel channel) = 0; virtual void unmap(const void *mappedMem) = 0; // clear (the specified channels of) this frame buffer virtual void clear(); // Get number of pixels per render task, in x and y direction vec2i getRenderTaskSize() const; // Return the number of render tasks in the x and y direction // This is the kernel launch dims to render the image virtual vec2i getNumRenderTasks() const = 0; virtual uint32_t getTotalRenderTasks() const = 0; // Get the device-side render task IDs virtual utility::ArrayView getRenderTaskIDs( const float errorThreshold, const uint32_t spp) = 0; vec2i getNumPixels() const; ColorBufferFormat getColorBufferFormat() const; virtual float getVariance() const; virtual float taskError(const uint32_t taskID) const = 0; virtual void beginFrame(); // Invoke post-processing by calling all FrameOps virtual devicert::AsyncEvent postProcess() = 0; // common function to help printf-debugging, every derived class should // override this virtual std::string toString() const override; void setCompletedEvent(OSPSyncEvent event); OSPSyncEvent getLatestCompleteEvent() const; void waitForEvent(OSPSyncEvent event) const; virtual float getCurrentProgress() const; virtual void cancelFrame(); bool frameCancelled() const; bool hasColorBuf() const; bool hasVarianceBuf() const; bool hasNormalBuf() const; bool hasAlbedoBuf() const; bool hasPrimitiveIDBuf() const; bool hasObjectIDBuf() const; bool hasInstanceIDBuf() const; bool doAccumulation() const; uint32 getChannelFlags() const; int32_t getFrameID() const; void setFrameID(int32_t id); FeatureFlags getFeatureFlags() const; #ifdef OSPRAY_TARGET_SYCL sycl::nd_range<3> getDispatchRange(const size_t numTasks) const; #endif protected: const vec2i size; ColorBufferFormat colorBufferFormat; // Frame buffer optional buffers bool hasColorBuffer; bool hasDepthBuffer; bool hasVarianceBuffer; bool hasNormalBuffer; bool hasAlbedoBuffer; bool hasPrimitiveIDBuffer; bool hasObjectIDBuffer; bool hasInstanceIDBuffer; // indicates whether the app requested this frame buffer to do accumulation bool doAccum; float frameVariance{inf}; std::atomic cancelRender{false}; std::atomic stagesCompleted{OSP_FRAME_FINISHED}; Ref> imageOpData; FeatureFlagsOther featureFlags{FFO_NONE}; int32_t minimumAdaptiveFrames(const uint32_t spp) const; bool accumulationFinished() const; private: // for consistent reproducibility of variance accumulation constexpr static uint32_t mtSeed = 43; std::mt19937 mtGen{mtSeed}; bool pickOdd{false}; }; OSPTYPEFOR_SPECIALIZATION(FrameBuffer *, OSP_FRAMEBUFFER); inline vec2i FrameBuffer::getNumPixels() const { return size; } inline FrameBuffer::ColorBufferFormat FrameBuffer::getColorBufferFormat() const { return colorBufferFormat; } inline bool FrameBuffer::hasColorBuf() const { return hasColorBuffer; } inline bool FrameBuffer::hasVarianceBuf() const { return hasVarianceBuffer; } inline bool FrameBuffer::hasNormalBuf() const { return hasNormalBuffer; } inline bool FrameBuffer::hasAlbedoBuf() const { return hasAlbedoBuffer; } inline bool FrameBuffer::hasPrimitiveIDBuf() const { return hasPrimitiveIDBuffer; } inline bool FrameBuffer::hasObjectIDBuf() const { return hasObjectIDBuffer; } inline bool FrameBuffer::hasInstanceIDBuf() const { return hasInstanceIDBuffer; } inline bool FrameBuffer::doAccumulation() const { return doAccum; } inline int32_t FrameBuffer::getFrameID() const { return getSh()->frameID; } inline void FrameBuffer::setFrameID(int32_t id) { getSh()->frameID = id; } inline FeatureFlags FrameBuffer::getFeatureFlags() const { FeatureFlags ff; ff.other = featureFlags; return ff; } #ifdef OSPRAY_TARGET_SYCL inline sycl::nd_range<3> FrameBuffer::getDispatchRange( const size_t numTasks) const { const vec2i ts = getRenderTaskSize(); return sycl::nd_range<3>({numTasks, ts.y, ts.x}, {1, ts.y, ts.x}); } #endif inline int32_t FrameBuffer::minimumAdaptiveFrames(const uint32_t spp) const { return std::max(2u, 16 / spp); } inline bool FrameBuffer::accumulationFinished() const { return getSh()->targetFrames && getFrameID() >= getSh()->targetFrames; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/FrameBuffer.ih000066400000000000000000000032361464752671100226330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "OSPConfig.h" #include "rkcommon/math/vec.ih" // c++ shared #include "FrameBufferShared.h" #ifndef OSPRAY_TARGET_SYCL extern "C" uint32 *uniform getThreadNumPixelsRendered(); extern "C" int *uniform getThreadLastFrameID(); #endif // factor = rcp(accumID + 1), i.e. 1.0, 0.5, ... // but rcp is not always accurate: rcp(1) can be < 1.0 // thus to be on the safe side we avoid the lerp for the first frame (to not // mix-in stale data) and compare with a value in (0.5, 1.0], the magic 0.8 #define FRAMEBUFFER_ACCUMULATE_VALUE(value, new_value, factor) \ value = (factor > 0.8f) ? new_value : lerp(factor, value, new_value) OSPRAY_BEGIN_ISPC_NAMESPACE #ifndef OSPRAY_TARGET_SYCL inline void FrameBuffer_updateProgress( FrameBuffer *uniform self, const uniform uint32 numPixelsRendered) { uint32 *uniform pixelsRendered = getThreadNumPixelsRendered(); // Reset the pixels rendered counter for each new frame int *uniform lastFrameID = getThreadLastFrameID(); if (self->frameID != *lastFrameID) { *pixelsRendered = 0; *lastFrameID = self->frameID; } // Update the pixels rendered count and report back to the atomic if we've // reached the reporting threshold *pixelsRendered += numPixelsRendered; // Report rendering results at the same frequency they would have been // reported (each tile) when using the old nested parallel fors over tiles // then pixels. if (*pixelsRendered >= TILE_SIZE * TILE_SIZE) { atomic_add_global(&self->numPixelsRendered, *pixelsRendered); *pixelsRendered = 0; } } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/FrameBufferDispatch.ih000066400000000000000000000015161464752671100243120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "common/OSPCommon.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct FrameBuffer; struct RenderTaskDesc; struct ScreenSample; SYCL_EXTERNAL uniform RenderTaskDesc FrameBuffer_dispatch_getRenderTaskDesc( FrameBuffer *uniform fb, const uniform uint32 taskID, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL void FrameBuffer_dispatch_accumulateSample( FrameBuffer *uniform fb, const varying ScreenSample &screenSample, uniform RenderTaskDesc &taskDesc, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL void FrameBuffer_dispatch_completeTask(FrameBuffer *uniform fb, const uniform RenderTaskDesc &taskDesc, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/FrameBufferDispatch.ispc000066400000000000000000000044341464752671100246520ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #include "fb/FrameBufferDispatch.ih" #include "fb/LocalFB.ih" #include "fb/RenderTaskDesc.ih" #include "fb/SparseFB.ih" #include "render/ScreenSample.ih" // c++ shared #include "fb/FrameBufferShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL uniform RenderTaskDesc FrameBuffer_dispatch_getRenderTaskDesc( FrameBuffer *uniform fb, const uniform uint32 taskID, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((fb->type == FRAMEBUFFER_TYPE_LOCAL) && (ffo & FFO_FB_LOCAL)) { return LocalFB_getRenderTaskDesc(fb, taskID); } else if ((fb->type == FRAMEBUFFER_TYPE_SPARSE) && (ffo & FFO_FB_SPARSE)) { return SparseFB_getRenderTaskDesc(fb, taskID); } else { #ifndef OSPRAY_TARGET_SYCL return fb->getRenderTaskDesc(fb, taskID); #endif } // TODO: Should be an error here uniform RenderTaskDesc rt; rt.region.lower = make_vec2i(0, 0); rt.region.upper = rt.region.lower; return rt; } SYCL_EXTERNAL void FrameBuffer_dispatch_accumulateSample( FrameBuffer *uniform fb, const varying ScreenSample &screenSample, uniform RenderTaskDesc &taskDesc, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((fb->type == FRAMEBUFFER_TYPE_LOCAL) && (ffo & FFO_FB_LOCAL)) { LocalFB_accumulateSample(fb, screenSample, taskDesc); } else if ((fb->type == FRAMEBUFFER_TYPE_SPARSE) && (ffo & FFO_FB_SPARSE)) { SparseFB_accumulateSample(fb, screenSample, taskDesc); } else { #ifndef OSPRAY_TARGET_SYCL fb->accumulateSample(fb, screenSample, taskDesc); #endif } } SYCL_EXTERNAL void FrameBuffer_dispatch_completeTask(FrameBuffer *uniform fb, const uniform RenderTaskDesc &taskDesc, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((fb->type == FRAMEBUFFER_TYPE_LOCAL) && (ffo & FFO_FB_LOCAL)) { LocalFB_completeTask(fb, taskDesc); } else if ((fb->type == FRAMEBUFFER_TYPE_SPARSE) && (ffo & FFO_FB_SPARSE)) { SparseFB_completeTask(fb, taskDesc); } else { #ifndef OSPRAY_TARGET_SYCL fb->completeTask(fb, taskDesc); #endif } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/FrameBufferShared.h000066400000000000000000000064661464752671100236210ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *FrameBuffer_accumulateSampleFct; typedef void *FrameBuffer_getRenderTaskDescFct; typedef void *FrameBuffer_completeTaskFct; #else struct FrameBuffer; struct ScreenSample; struct RenderTaskDesc; typedef void (*FrameBuffer_accumulateSampleFct)(FrameBuffer *uniform fb, const varying ScreenSample &sample, uniform RenderTaskDesc &taskDesc); typedef uniform RenderTaskDesc (*FrameBuffer_getRenderTaskDescFct)( FrameBuffer *uniform fb, const uniform uint32 taskID); typedef void (*FrameBuffer_completeTaskFct)( FrameBuffer *uniform fb, const uniform RenderTaskDesc &taskDesc); #endif enum FrameBufferType { FRAMEBUFFER_TYPE_LOCAL, FRAMEBUFFER_TYPE_SPARSE, FRAMEBUFFER_TYPE_UNKNOWN, }; /* The ISPC-side FrameBuffer allows tasks to write directly to the framebuffer * memory from ISPC. Given the set of task IDs to be rendered, a renderer must: * * 1. Get the RenderTaskDesc by calling getRenderTaskDesc and render the region * of pixels specified in the task description. * * 2. Write the result of rendering each pixel to the framebuffer by calling * accumulateSample * * 3. Update task-level values (accum ID and error) by calling completeTask */ struct FrameBuffer { FrameBufferType type; /* Get the task description for a given render task ID. The task description * stores the region that should be rendered for the task and its accumID */ FrameBuffer_getRenderTaskDescFct getRenderTaskDesc; /* Accumulate samples taken for this render task into the framebuffer. * Task error will also be computed and accumulated on the render task, * to handle cases where there are more pixels in a task than the SIMD width. */ FrameBuffer_accumulateSampleFct accumulateSample; /* Perform final task updates for the given task, updating its accum ID (if * accumulation buffering is enabled) and its error if variance termination is * enabled */ FrameBuffer_completeTaskFct completeTask; // The size of the framebuffer, in pixels vec2i size; // 1/size (precomputed) vec2f rcpSize; // The default size of each each render task, in pixels vec2i renderTaskSize; // Rendered frame index int32 frameID; int32 targetFrames; // The channels stored in the framebuffer uint32 channels; // If the frame has been cancelled or not. Note: we don't share bools between // ISPC and C++ as the true value representation may differ (as it does with // gcc) uint32 cancelRender; // The number of pixels rendered this frame, for tracking rendering progress // Not used on GPU to avoid USM thrashing uint32 numPixelsRendered; // Variance accumulation bool accumulateVariance; // do frame accumulation in this frame #ifdef __cplusplus FrameBuffer() : type(FRAMEBUFFER_TYPE_UNKNOWN), getRenderTaskDesc(nullptr), accumulateSample(nullptr), completeTask(nullptr), size(0), rcpSize(0.f), renderTaskSize(4), frameID(-1), targetFrames(0), channels(0), cancelRender(0), numPixelsRendered(0), accumulateVariance(false) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/fb/FrameBufferView.ih000066400000000000000000000003441464752671100234630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus #include "fb/FrameBufferViewDef.h" #ifdef __cplusplus } #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/fb/FrameOp.cpp000066400000000000000000000010551464752671100221570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "FrameOp.h" namespace ospray { LiveFrameOp::LiveFrameOp(devicert::Device &device, FrameBufferView &fbView) : AddStructShared(device), device(device) { // We need `FrameBufferView` to be in `ospray` namespace for external modules // to reach it, and we need it to be in `ispc` namespace for ISPC automatic // headers generator, copying between those two requires a cast *getSh() = *reinterpret_cast(&fbView); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/FrameOp.h000066400000000000000000000012741464752671100216270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/StructShared.h" #include "fb/ImageOp.h" // ispc shared #include "fb/FrameBufferView.ih" namespace ospray { struct OSPRAY_SDK_INTERFACE FrameOp : public FrameOpInterface { FrameOp(devicert::Device &device) : device(device) {} ~FrameOp() override = default; protected: devicert::Device &device; }; struct OSPRAY_SDK_INTERFACE LiveFrameOp : public AddStructShared { LiveFrameOp(devicert::Device &device, FrameBufferView &fbView); ~LiveFrameOp() override = default; protected: devicert::Device &device; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/LocalFB.cpp000066400000000000000000000400751464752671100220750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "LocalFB.h" #include "FrameOp.h" #include "SparseFB.h" #include "fb/FrameBufferView.h" #include "frame_ops/ColorConversion.h" #include "frame_ops/Variance.h" #include "render/util.h" #include "rkcommon/common.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/utility/ArrayView.h" #ifndef OSPRAY_TARGET_SYCL #include "fb/LocalFB_ispc.h" #else namespace ispc { SYCL_EXTERNAL void LocalFrameBuffer_writeColorTile( void *_fb, const void *_tile); SYCL_EXTERNAL void LocalFrameBuffer_writeDepthTile(void *_fb, const void *uniform _tile); SYCL_EXTERNAL void LocalFrameBuffer_writeAuxTile(void *_fb, const void *_tile, void *aux, const void *_ax, const void *_ay, const void *_az); SYCL_EXTERNAL void LocalFrameBuffer_writeIDTile(void *uniform _fb, const void *uniform _tile, uniform uint32 *uniform dst, const void *uniform src); } // namespace ispc #endif #include #include #include #include namespace ospray { LocalFrameBuffer::LocalFrameBuffer(api::ISPCDevice &device, const vec2i &_size, ColorBufferFormat _colorBufferFormat, const uint32 channels) : AddStructShared(device.getDRTDevice(), device, _size, _colorBufferFormat, channels, FFO_FB_LOCAL), device(device), numRenderTasks(divRoundUp(size, getRenderTaskSize())) { const size_t numPixels = _size.long_product(); if (hasColorBuffer) colorBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); if (hasDepthBuffer) depthBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); // If variance is going to be used we need to construct helper buffer and // FrameOp to do the calculations if (hasVarianceBuffer) { varianceBuffer = devicert::make_buffer_device_unique( device.getDRTDevice(), numPixels); // Create and initialize FrameBufferView structure which define domain for // VarianceFrameOp. Since the VarianceFrameOp calculates per-RenderTask // error, the viewDims member is RenderTasks dimensions rather then // FrameBuffer dimensions. Perhaps FrameBufferView should be renamed to // FrameOpDomain or similar in future. FrameBufferView fbv(getNumPixels(), colorBuffer->devicePtr()); fbv.viewDims = getNumRenderTasks(); varianceFrameOp = rkcommon::make_unique( device.getDRTDevice(), fbv, varianceBuffer->devicePtr()); } if (hasNormalBuffer) normalBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); if (hasAlbedoBuffer) albedoBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); if (hasPrimitiveIDBuffer) primitiveIDBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); if (hasObjectIDBuffer) objectIDBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); if (hasInstanceIDBuffer) instanceIDBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), numPixels); // Create color conversion FrameOp if needed if ((hasColorBuffer) && (getColorBufferFormat() != OSP_FB_RGBA32F)) { FrameBufferView fbv(getNumPixels(), colorBuffer->devicePtr()); colorConversionFrameOp = rkcommon::make_unique( device.getDRTDevice(), fbv, getColorBufferFormat()); } // TODO: Better way to pass the task IDs that doesn't require just storing // them all? Maybe as blocks/tiles similar to when we just had tiles? Will // make task ID lookup more expensive for sparse case though renderTaskIDs = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), getTotalRenderTasks()); std::iota(renderTaskIDs->begin(), renderTaskIDs->end(), 0); if (hasVarianceBuffer) activeTaskIDs = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), getTotalRenderTasks()); // TODO: Could use TBB parallel sort here if it's exposed through the // rkcommon tasking system #ifndef OSPRAY_TARGET_SYCL // We use a 1x1 task size in SYCL and this sorting may not pay off for the // cost it adds std::sort(renderTaskIDs->begin(), renderTaskIDs->end(), [&](const uint32_t &a, const uint32_t &b) { const vec2i p_a = getTaskStartPos(a); const vec2i p_b = getTaskStartPos(b); return interleaveZOrder(p_a.x, p_a.y) < interleaveZOrder(p_b.x, p_b.y); }); #endif { // Upload the task IDs to the device renderTaskIDs->copyToDevice(); } #ifndef OSPRAY_TARGET_SYCL getSh()->super.accumulateSample = reinterpret_cast( ispc::LocalFrameBuffer_accumulateSample_addr()); getSh()->super.getRenderTaskDesc = reinterpret_cast( ispc::LocalFrameBuffer_getRenderTaskDesc_addr()); getSh()->super.completeTask = reinterpret_cast( ispc::LocalFrameBuffer_completeTask_addr()); #endif getSh()->colorBuffer = colorBuffer ? colorBuffer->devicePtr() : nullptr; getSh()->varianceBuffer = varianceBuffer ? varianceBuffer->devicePtr() : nullptr; getSh()->depthBuffer = depthBuffer ? depthBuffer->devicePtr() : nullptr; getSh()->normalBuffer = normalBuffer ? normalBuffer->devicePtr() : nullptr; getSh()->albedoBuffer = albedoBuffer ? albedoBuffer->devicePtr() : nullptr; getSh()->numRenderTasks = numRenderTasks; getSh()->primitiveIDBuffer = primitiveIDBuffer ? primitiveIDBuffer->devicePtr() : nullptr; getSh()->objectIDBuffer = objectIDBuffer ? objectIDBuffer->devicePtr() : nullptr; getSh()->instanceIDBuffer = instanceIDBuffer ? instanceIDBuffer->devicePtr() : nullptr; } // Need this destructor to be in the cpp where we have full definition of // LiveVarianceFrameOp and LiveColorConversionFrameOp LocalFrameBuffer::~LocalFrameBuffer() {} void LocalFrameBuffer::commit() { FrameBuffer::commit(); // No frame operations if there is no color buffer if (!hasColorBuffer) return; FrameBufferView fbv(getNumPixels(), colorBuffer ? colorBuffer->devicePtr() : nullptr, depthBuffer ? depthBuffer->devicePtr() : nullptr, normalBuffer ? normalBuffer->devicePtr() : nullptr, albedoBuffer ? albedoBuffer->devicePtr() : nullptr); // Initialize user defined image operations ppColorBuffer.reset(); frameOps.clear(); if (imageOpData) { // Create buffer for post-processing output ppColorBuffer = devicert::make_buffer_device_shadowed_unique( device.getDRTDevice(), getNumPixels().long_product()); fbv.colorBufferOutput = ppColorBuffer->devicePtr(); // Build FrameOps chain by iterating through all image operations set on // commit for (auto &&obj : *imageOpData) { // Populate frame operations FrameOpInterface *fopi = dynamic_cast(obj); if (fopi) { // Create live FrameOp object frameOps.push_back(fopi->attach(fbv)); // Connect previous FrameOp output with the next FrameOp input fbv.colorBufferInput = fbv.colorBufferOutput; } } } // Create color conversion FrameOp if needed colorConversionFrameOp.reset(); if (getColorBufferFormat() != OSP_FB_RGBA32F) { colorConversionFrameOp = rkcommon::make_unique( device.getDRTDevice(), fbv, getColorBufferFormat()); } } vec2i LocalFrameBuffer::getNumRenderTasks() const { return numRenderTasks; } uint32_t LocalFrameBuffer::getTotalRenderTasks() const { return numRenderTasks.long_product(); } utility::ArrayView LocalFrameBuffer::getRenderTaskIDs( const float errorThreshold_, const uint32_t spp) { if (accumulationFinished()) return utility::ArrayView(); errorThreshold = errorThreshold_; // remember if (errorThreshold > 0.0f && varianceFrameOp && (getFrameID() >= minimumAdaptiveFrames(spp))) { // Select render tasks that needs to be processed auto last = std::copy_if(renderTaskIDs->begin(), renderTaskIDs->end(), activeTaskIDs->begin(), [=](uint32_t i) { return varianceFrameOp->getError(i) > errorThreshold; }); activeTaskIDs->copyToDevice(); const size_t numActive = last - activeTaskIDs->begin(); return utility::ArrayView(activeTaskIDs->devicePtr(), numActive); } else return utility::ArrayView( renderTaskIDs->devicePtr(), renderTaskIDs->size()); } float LocalFrameBuffer::getVariance() const { // Return maximum error over all tasks if variance has been calculated in a // FrameOp if (varianceFrameOp && varianceFrameOp->validError()) return varianceFrameOp->getAvgError(errorThreshold); // Return set value otherwise return FrameBuffer::getVariance(); } std::string LocalFrameBuffer::toString() const { return "ospray::LocalFrameBuffer"; } void LocalFrameBuffer::clear() { FrameBuffer::clear(); if (hasVarianceBuffer && varianceFrameOp) varianceFrameOp->restart(); } void LocalFrameBuffer::writeTiles(const utility::ArrayView &tiles) { // TODO: The parallel dispatch part of this should be moved into ISPC as an // ISPC launch that calls the individual (currently) exported functions that // we call below in this loop #ifndef OSPRAY_TARGET_SYCL tasking::parallel_for(tiles.size(), [&](const size_t i) { const Tile *tile = &tiles[i]; if (hasColorBuffer) { ispc::LocalFrameBuffer_writeColorTile(getSh(), tile); } if (hasDepthBuffer) { ispc::LocalFrameBuffer_writeDepthTile(getSh(), tile); } if (hasAlbedoBuffer) { ispc::LocalFrameBuffer_writeAuxTile(getSh(), tile, (ispc::vec3f *)albedoBuffer->data(), tile->ar, tile->ag, tile->ab); } if (hasPrimitiveIDBuffer) { ispc::LocalFrameBuffer_writeIDTile( getSh(), tile, getSh()->primitiveIDBuffer, tile->pid); } if (hasObjectIDBuffer) { ispc::LocalFrameBuffer_writeIDTile( getSh(), tile, getSh()->objectIDBuffer, tile->gid); } if (hasInstanceIDBuffer) { ispc::LocalFrameBuffer_writeIDTile( getSh(), tile, getSh()->instanceIDBuffer, tile->iid); } if (hasNormalBuffer) { ispc::LocalFrameBuffer_writeAuxTile(getSh(), tile, (ispc::vec3f *)normalBuffer->data(), tile->nx, tile->ny, tile->nz); } }); #else auto *fbSh = getSh(); const size_t numTasks = tiles.size(); const Tile *tilesPtr = tiles.data(); const int colorFormat = getColorBufferFormat(); vec3f *albedoBufferPtr = fbSh->super.channels & OSP_FB_ALBEDO ? albedoBuffer->devicePtr() : nullptr; vec3f *normalBufferPtr = fbSh->super.channels & OSP_FB_NORMAL ? normalBuffer->devicePtr() : nullptr; sycl::queue *queue = static_cast(device.getDRTDevice().getSyclQueuePtr()); queue ->submit([&](sycl::handler &cgh) { const sycl::nd_range<1> dispatchRange = device.computeDispatchRange(numTasks, 16); cgh.parallel_for(dispatchRange, [=](sycl::nd_item<1> taskIndex) { if (taskIndex.get_global_id(0) < numTasks) { const Tile *tile = &tilesPtr[taskIndex.get_global_id(0)]; if (fbSh->super.channels & OSP_FB_COLOR) { ispc::LocalFrameBuffer_writeColorTile(fbSh, tile); } if (fbSh->super.channels & OSP_FB_DEPTH) { ispc::LocalFrameBuffer_writeDepthTile(fbSh, tile); } if (fbSh->super.channels & OSP_FB_ALBEDO) { ispc::LocalFrameBuffer_writeAuxTile( fbSh, tile, albedoBufferPtr, tile->ar, tile->ag, tile->ab); } if (fbSh->super.channels & OSP_FB_ID_PRIMITIVE) { ispc::LocalFrameBuffer_writeIDTile( fbSh, tile, fbSh->primitiveIDBuffer, tile->pid); } if (fbSh->super.channels & OSP_FB_ID_OBJECT) { ispc::LocalFrameBuffer_writeIDTile( fbSh, tile, fbSh->objectIDBuffer, tile->gid); } if (fbSh->super.channels & OSP_FB_ID_INSTANCE) { ispc::LocalFrameBuffer_writeIDTile( fbSh, tile, fbSh->instanceIDBuffer, tile->iid); } if (fbSh->super.channels & OSP_FB_NORMAL) { ispc::LocalFrameBuffer_writeAuxTile( fbSh, tile, normalBufferPtr, tile->nx, tile->ny, tile->nz); } } }); }) .wait_and_throw(); #endif } void LocalFrameBuffer::writeTiles(SparseFrameBuffer *sparseFb) { // Write tiles operates on device memory writeTiles(sparseFb->getTilesDevice()); assert(getRenderTaskSize() == sparseFb->getRenderTaskSize()); const vec2i renderTaskSize = getRenderTaskSize(); if (!hasVarianceBuffer) { return; } // Task error is not calculated by varianceFrameOp but is being written // directly from SparseFB, the varianceFrameOp needs to be removed to not // interfere with frameVariance calculation varianceFrameOp.reset(); // Now we do need the tile memory on the host to read the region information frameVariance = 0.f; const auto tileIDs = sparseFb->getTileIDs(); uint32_t renderTaskID = 0; for (size_t i = 0; i < tileIDs.size(); ++i) { const box2i tileRegion = sparseFb->getTileRegion(tileIDs[i]); const box2i taskRegion( tileRegion.lower / renderTaskSize, tileRegion.upper / renderTaskSize); for (int y = taskRegion.lower.y; y < taskRegion.upper.y; ++y) { for (int x = taskRegion.lower.x; x < taskRegion.upper.x; ++x, ++renderTaskID) { frameVariance = max(frameVariance, sparseFb->taskError(renderTaskID)); } } } } vec2i LocalFrameBuffer::getTaskStartPos(const uint32_t taskID) const { const vec2i numRenderTasks = getNumRenderTasks(); vec2i taskStart(taskID % numRenderTasks.x, taskID / numRenderTasks.x); return taskStart * getRenderTaskSize(); } devicert::AsyncEvent LocalFrameBuffer::postProcess() { // Calculate per-task variance if any samples accumulated into variance // buffer, skip it if frameVariance overridden in writeTiles() devicert::AsyncEvent event; const bool oddFrame = (getSh()->super.frameID & 1) == 1; if (varianceFrameOp && oddFrame && (frameVariance == float(inf))) event = varianceFrameOp->process(); // Execute user-defined post-processing kernels for (auto &p : frameOps) event = p->process(); // Run final color conversion if needed if (colorConversionFrameOp) event = colorConversionFrameOp->process(); // Return asynchronous event return event; } namespace { template const void *copyToHost(T &buffer) { buffer.copyToHost().wait(); return static_cast(buffer.hostPtr()); } } // namespace const void *LocalFrameBuffer::mapBuffer(OSPFrameBufferChannel channel) { const void *buf = nullptr; if (channel == OSP_FB_COLOR) { if (colorConversionFrameOp) buf = copyToHost(colorConversionFrameOp->getConvertedBuffer()); else if (ppColorBuffer) buf = copyToHost(*ppColorBuffer); else if (colorBuffer) buf = copyToHost(*colorBuffer); } else if ((channel == OSP_FB_DEPTH) && (depthBuffer)) { buf = copyToHost(*depthBuffer); } else if ((channel == OSP_FB_NORMAL) && (normalBuffer)) { buf = copyToHost(*normalBuffer); } else if ((channel == OSP_FB_ALBEDO) && (albedoBuffer)) { buf = copyToHost(*albedoBuffer); } else if ((channel == OSP_FB_ID_PRIMITIVE) && (primitiveIDBuffer)) { buf = copyToHost(*primitiveIDBuffer); } else if ((channel == OSP_FB_ID_OBJECT) && (objectIDBuffer)) { buf = copyToHost(*objectIDBuffer); } else if ((channel == OSP_FB_ID_INSTANCE) && (instanceIDBuffer)) { buf = copyToHost(*instanceIDBuffer); } if (buf) this->refInc(); return buf; } void LocalFrameBuffer::unmap(const void *mappedMem) { if (mappedMem) this->refDec(); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/LocalFB.h000066400000000000000000000073401464752671100215400ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "fb/FrameBuffer.h" // rkcommon #include "rkcommon/containers/AlignedVector.h" #include "rkcommon/utility/ArrayView.h" // ispc shared #include "LocalFBShared.h" #include "TileShared.h" namespace ospray { struct SparseFrameBuffer; struct LiveVarianceFrameOp; struct LiveColorConversionFrameOp; struct OSPRAY_SDK_INTERFACE LocalFrameBuffer : public AddStructShared { LocalFrameBuffer(api::ISPCDevice &device, const vec2i &size, ColorBufferFormat colorBufferFormat, const uint32 channels); ~LocalFrameBuffer() override; virtual void commit() override; // Return the number of render tasks in the x and y direction // This is the kernel launch dims to render the image virtual vec2i getNumRenderTasks() const override; virtual uint32_t getTotalRenderTasks() const override; virtual utility::ArrayView getRenderTaskIDs( const float errorThreshold, const uint32_t spp) override; virtual float getVariance() const override; // common function to help printf-debugging, every derived class should // override this! virtual std::string toString() const override; devicert::AsyncEvent postProcess() override; const void *mapBuffer(OSPFrameBufferChannel channel) override; void unmap(const void *mappedMem) override; void clear() override; /* Write the tile into this framebuffer's row-major storage. This does not * perform accumulation or buffering, data is taken directly from the tile and * written to the row-major image stored by the LocalFrameBuffer * Safe to call in parallel from multiple threads, as long as each thread is * writing different tiles */ void writeTiles(const utility::ArrayView &tiles); /* Write the tiles of the sparse fb into this framebuffer's row-major storage. * Will also copy error data from the sparseFb the full framebuffer task error * buffer, if variance buffer is enabled. * Safe to call in parallel from multiple threads, as long as each thread is * writing different tiles */ void writeTiles(SparseFrameBuffer *sparseFb); // NOTE: All per-pixel data is only allocated if the corresponding channel // flag was passed on construction // one RGBA per pixel BufferDeviceShadowedUq colorBuffer; // one RGBA per pixel, post-processing output BufferDeviceShadowedUq ppColorBuffer; // one RGBA per pixel, does not accumulate all samples, for variance // estimation BufferDeviceUq varianceBuffer; // one float per pixel BufferDeviceShadowedUq depthBuffer; // accumulated world-space normal per pixel BufferDeviceShadowedUq normalBuffer; // accumulated, one RGB per pixel BufferDeviceShadowedUq albedoBuffer; // primitive ID, object ID, and instance ID BufferDeviceShadowedUq primitiveIDBuffer; BufferDeviceShadowedUq objectIDBuffer; BufferDeviceShadowedUq instanceIDBuffer; protected: vec2i getTaskStartPos(const uint32_t taskID) const; //// Data //// api::ISPCDevice &device; vec2i numRenderTasks; BufferDeviceShadowedUq renderTaskIDs; BufferDeviceShadowedUq activeTaskIDs; // Array of frame operations std::vector> frameOps; // Variance frame operation std::unique_ptr varianceFrameOp; // Color conversion frame operation std::unique_ptr colorConversionFrameOp; private: float errorThreshold; // remember // Not used, to be removed after mpi module refactor float taskError(const uint32_t) const override { return 0.f; } }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/LocalFB.ih000066400000000000000000000011571464752671100217110ustar00rootroot00000000000000// Copyright 2009-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "fb/FrameBuffer.ih" #include "fb/Tile.ih" // c++ shared #include "LocalFBShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void LocalFB_accumulateSample(FrameBuffer *uniform _fb, const varying ScreenSample &screenSample, uniform RenderTaskDesc &taskDesc); SYCL_EXTERNAL uniform RenderTaskDesc LocalFB_getRenderTaskDesc( FrameBuffer *uniform _fb, const uniform uint32 taskID); SYCL_EXTERNAL void LocalFB_completeTask( FrameBuffer *uniform _fb, const uniform RenderTaskDesc &taskDesc); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/LocalFB.ispc000066400000000000000000000167521464752671100222560ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "FrameBuffer.ih" #include "RenderTaskDesc.ih" #include "Tile.ih" #include "render/ScreenSample.ih" // c++ shared #include "LocalFBShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void LocalFB_accumulateSample(FrameBuffer *uniform _fb, const varying ScreenSample &screenSample, uniform RenderTaskDesc &) { LocalFB *uniform fb = (LocalFB * uniform) _fb; const int pixelID = screenSample.sampleID.x + fb->super.size.x * screenSample.sampleID.y; // Calculate accumulation scale const uniform int accumID = fb->super.frameID; const uniform float accScale = rcpf(accumID + 1); // Accumulate color const vec4f colorSample = make_vec4f(screenSample.rgb, screenSample.alpha); if (fb->colorBuffer) FRAMEBUFFER_ACCUMULATE_VALUE( fb->colorBuffer[pixelID], colorSample, accScale); // Accumulate color in variance buffer if (fb->super.accumulateVariance) { const uniform float accVarScale = rcpf(accumID / 2 + 1); FRAMEBUFFER_ACCUMULATE_VALUE( fb->varianceBuffer[pixelID], colorSample, accVarScale); } // Accumulate depth buffer if (fb->depthBuffer) { float depth = screenSample.z; if (accumID > 0) depth = min(fb->depthBuffer[pixelID], screenSample.z); fb->depthBuffer[pixelID] = depth; } // Accumulate normal buffer if (fb->normalBuffer) FRAMEBUFFER_ACCUMULATE_VALUE( fb->normalBuffer[pixelID], screenSample.normal, accScale); // Accumulate albedo buffer if (fb->albedoBuffer) FRAMEBUFFER_ACCUMULATE_VALUE( fb->albedoBuffer[pixelID], screenSample.albedo, accScale); if (fb->primitiveIDBuffer) { if (accumID == 0) fb->primitiveIDBuffer[pixelID] = screenSample.primID; } if (fb->objectIDBuffer) { if (accumID == 0) fb->objectIDBuffer[pixelID] = screenSample.geomID; } if (fb->instanceIDBuffer) { if (accumID == 0) fb->instanceIDBuffer[pixelID] = screenSample.instID; } #ifndef OSPRAY_TARGET_SYCL FrameBuffer_updateProgress(&fb->super, popcnt(lanemask())); #endif } SYCL_EXTERNAL uniform RenderTaskDesc LocalFB_getRenderTaskDesc( FrameBuffer *uniform _fb, const uniform uint32 taskID) { LocalFB *uniform fb = (LocalFB * uniform) _fb; uniform RenderTaskDesc desc; desc.taskID = taskID; desc.error = 0.f; uniform vec2i renderTaskSize = fb->super.renderTaskSize; uniform vec2i taskStart = make_vec2i(taskID % fb->numRenderTasks.x, taskID / fb->numRenderTasks.x); desc.region.lower = taskStart * renderTaskSize; desc.region.upper = min(desc.region.lower + renderTaskSize, fb->super.size); return desc; } SYCL_EXTERNAL void LocalFB_completeTask( FrameBuffer *uniform, const uniform RenderTaskDesc &) { // Do nothing } // TODO: Unify all writeTile functions below into a single one export SYCL_EXTERNAL void LocalFrameBuffer_writeColorTile( void *uniform _fb, const void *uniform _tile) { Tile *uniform tile = (Tile * uniform) _tile; uniform LocalFB *uniform fb = (uniform LocalFB * uniform) _fb; uniform vec4f *uniform color = (uniform vec4f * uniform) fb->colorBuffer; color += (uniform uint64)tile->region.lower.y * fb->super.size.x; VaryingTile *uniform varyTile = (VaryingTile * uniform) tile; for (uniform uint32 iiy = tile->region.lower.y; iiy < (uniform uint32)tile->region.upper.y; iiy++) { uniform uint32 chunkID = (iiy - tile->region.lower.y) * (TILE_SIZE / programCount); for (uint32 iix = tile->region.lower.x + programIndex; iix < (uniform uint32)tile->region.upper.x; iix += programCount, chunkID++) { color[iix] = make_vec4f(varyTile->r[chunkID], varyTile->g[chunkID], varyTile->b[chunkID], varyTile->a[chunkID]); } color += fb->super.size.x; } } // Write the input tile into the row-major framebuffer's depth buffer export SYCL_EXTERNAL void LocalFrameBuffer_writeDepthTile( void *uniform _fb, const void *uniform _tile) { uniform LocalFB *uniform fb = (uniform LocalFB * uniform) _fb; const Tile *uniform tile = (const Tile *uniform)_tile; VaryingTile *uniform varyTile = (VaryingTile * uniform) tile; uniform float *uniform depth = (uniform float *uniform)fb->depthBuffer; depth += (uniform uint64)tile->region.lower.y * fb->super.size.x; for (uniform uint32 iiy = tile->region.lower.y; iiy < (uniform uint32)tile->region.upper.y; iiy++) { uniform uint32 chunkID = (iiy - tile->region.lower.y) * (TILE_SIZE / programCount); for (uint32 iix = tile->region.lower.x + programIndex; iix < (uniform uint32)tile->region.upper.x; iix += programCount, chunkID++) { depth[iix] = varyTile->z[chunkID]; } depth += fb->super.size.x; } } // "accumulate" first frame only and write into buffer export SYCL_EXTERNAL void LocalFrameBuffer_writeIDTile(void *uniform _fb, const void *uniform _tile, uniform uint32 *uniform dst, const void *uniform src) { uniform LocalFB *uniform fb = (uniform LocalFB * uniform) _fb; const Tile *uniform tile = (const Tile *uniform)_tile; uniform uint32 *uniform buffer = dst; //(uniform uint32 *uniform)fb->primitiveIDBuffer; buffer += (uniform uint64)tile->region.lower.y * fb->super.size.x; const void *uniform upid = src; //(const void* uniform)tile->pid; const varying int32 *uniform pid = (const varying int32 *uniform)upid; for (uniform uint32 iiy = tile->region.lower.y; iiy < (uniform uint32)tile->region.upper.y; iiy++) { uniform uint32 chunkID = (iiy - tile->region.lower.y) * (TILE_SIZE / programCount); for (uint32 iix = tile->region.lower.x + programIndex; iix < (uniform uint32)tile->region.upper.x; iix += programCount, chunkID++) { if (tile->accumID == 0) { varying uint32 val = -1; unmasked { val = pid[chunkID]; } buffer[iix] = val; } } buffer += fb->super.size.x; } } // Write a Tile's auxiliary buffer into the framebuffer's row major storage export SYCL_EXTERNAL void LocalFrameBuffer_writeAuxTile(void *uniform _fb, const void *uniform _tile, void *uniform _aux, const void *uniform _ax, const void *uniform _ay, const void *uniform _az) { uniform LocalFB *uniform fb = (uniform LocalFB * uniform) _fb; const Tile *uniform tile = (const Tile *uniform)_tile; uniform vec3f *uniform aux = (uniform vec3f * uniform) _aux; const varying float *uniform ax = (const varying float *uniform)_ax; const varying float *uniform ay = (const varying float *uniform)_ay; const varying float *uniform az = (const varying float *uniform)_az; aux += (uniform uint64)tile->region.lower.y * fb->super.size.x; for (uniform uint32 iiy = tile->region.lower.y; iiy < (uniform uint32)tile->region.upper.y; iiy++) { uniform uint32 chunkID = (iiy - tile->region.lower.y) * (TILE_SIZE / programCount); for (uint32 iix = tile->region.lower.x + programIndex; iix < (uint32)tile->region.upper.x; iix += programCount, chunkID++) { aux[iix] = make_vec3f(ax[chunkID], ay[chunkID], az[chunkID]); } aux += fb->super.size.x; } } export void *uniform LocalFrameBuffer_accumulateSample_addr() { return (void *uniform)LocalFB_accumulateSample; } export void *uniform LocalFrameBuffer_getRenderTaskDesc_addr() { return (void *uniform)LocalFB_getRenderTaskDesc; } export void *uniform LocalFrameBuffer_completeTask_addr() { return (void *uniform)LocalFB_completeTask; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/LocalFBShared.h000066400000000000000000000021471464752671100226670ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "FrameBufferShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // a Local FrameBuffer that stores all pixel values (color, depth, // accum) in a plain 2D array of pixels (one array per component) struct LocalFB { FrameBuffer super; // superclass that we inherit from vec4f *colorBuffer; vec4f *varianceBuffer; // accumulates every other sample, for variance // estimation / stopping float *depthBuffer; vec3f *normalBuffer; vec3f *albedoBuffer; vec2i numRenderTasks; uint32 *primitiveIDBuffer; uint32 *objectIDBuffer; uint32 *instanceIDBuffer; #ifdef __cplusplus LocalFB() : colorBuffer(nullptr), varianceBuffer(nullptr), depthBuffer(nullptr), normalBuffer(nullptr), albedoBuffer(nullptr), numRenderTasks(0), primitiveIDBuffer(nullptr), objectIDBuffer(nullptr), instanceIDBuffer(nullptr) { super.type = FRAMEBUFFER_TYPE_LOCAL; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/fb/RenderTaskDesc.ih000066400000000000000000000004641464752671100233100ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/box.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct RenderTaskDesc { box2i region; // screen region that this corresponds to uint32 taskID; float error; int count; }; OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/SparseFB.cpp000066400000000000000000000313271464752671100223000ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "SparseFB.h" #include "OSPConfig.h" #include "common/DeviceRTImpl.h" #include "fb/ImageOp.h" #include "render/util.h" #include "rkcommon/common.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/ArrayView.h" #ifndef OSPRAY_TARGET_SYCL #include "fb/SparseFB_ispc.h" #endif #include #include namespace ospray { // A global function so we can call it from the tile initialization SYCL kernel box2i getTileRegion(uint32_t tileID, const vec2i fbSize, const vec2i totalTiles) { const vec2i tilePos(tileID % totalTiles.x, tileID / totalTiles.x); return box2i( tilePos * TILE_SIZE, min(tilePos * TILE_SIZE + TILE_SIZE, fbSize)); } SparseFrameBuffer::SparseFrameBuffer(api::ISPCDevice &device, const vec2i &_size, ColorBufferFormat _colorBufferFormat, const uint32 channels, const std::vector &_tileIDs) : AddStructShared(device.getDRTDevice(), device, _size, _colorBufferFormat, channels, FFO_FB_SPARSE), device(device), totalTiles(divRoundUp(size, vec2i(TILE_SIZE))) { if (size.x <= 0 || size.y <= 0) { throw std::runtime_error( "local framebuffer has invalid size. Dimensions must be greater than " "0"); } setTiles(_tileIDs); } SparseFrameBuffer::SparseFrameBuffer(api::ISPCDevice &device, const vec2i &_size, ColorBufferFormat _colorBufferFormat, const uint32 channels) : AddStructShared(device.getDRTDevice(), device, _size, _colorBufferFormat, channels, FFO_FB_SPARSE), device(device), totalTiles(divRoundUp(size, vec2i(TILE_SIZE))) { if (size.x <= 0 || size.y <= 0) { throw std::runtime_error( "local framebuffer has invalid size. Dimensions must be greater than " "0"); } } vec2i SparseFrameBuffer::getNumRenderTasks() const { return numRenderTasks; } uint32_t SparseFrameBuffer::getTotalRenderTasks() const { return numRenderTasks.product(); } utility::ArrayView SparseFrameBuffer::getRenderTaskIDs( const float errorThreshold, const uint32_t) { if (!renderTaskIDs) // XXX || accumulationFinished() as in local rendering, // but this leads to a corrupted FB for MPI return utility::ArrayView(); if (errorThreshold > 0.0f && hasVarianceBuffer) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("buildActiveTaskIDs", "SparseFb")); auto last = std::copy_if(renderTaskIDs->begin(), renderTaskIDs->end(), activeTaskIDs->begin(), [=](uint32_t i) { return taskError(i) > errorThreshold; }); activeTaskIDs->copyToDevice(); const size_t numActive = last - activeTaskIDs->begin(); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); return utility::ArrayView(activeTaskIDs->devicePtr(), numActive); } else { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("returnAllTaskIDs", "SparseFB")); return utility::ArrayView( renderTaskIDs->devicePtr(), renderTaskIDs->size()); } } std::string SparseFrameBuffer::toString() const { return "ospray::SparseFrameBuffer"; } float SparseFrameBuffer::taskError(const uint32_t taskID) const { // If this SparseFB doesn't have any tiles return 0. This should not // typically be called in this case anyways if (!tiles) { return 0.f; } if (!taskErrorBuffer) { throw std::runtime_error( "SparseFrameBuffer::taskError: trying to get task error on FB without variance/error buffers"); } // TODO: Should sync taskError back in endFrame return (*taskErrorBuffer)[taskID]; } void SparseFrameBuffer::setTaskError(const uint32_t taskID, const float error) { // If this SparseFB doesn't have any tiles then do nothing. This should not // typically be called in this case anyways if (!tiles) { return; } if (!taskErrorBuffer) { throw std::runtime_error( "SparseFrameBuffer::setTaskError: trying to set task error on FB without variance/error buffers"); } // TODO: dirty tracking for task error, sync in begin frame (*taskErrorBuffer)[taskID] = error; } void SparseFrameBuffer::beginFrame() { FrameBuffer::beginFrame(); if (tiles) { #ifndef OSPRAY_TARGET_SYCL for (auto &tile : *tiles) { tile.accumID = getFrameID(); } #else const size_t numTasks = tiles->size(); auto *fbSh = getSh(); const int32 frameID = getFrameID(); sycl::queue *queue = static_cast(device.getDRTDevice().getSyclQueuePtr()); queue ->submit([&](sycl::handler &cgh) { const sycl::nd_range<1> dispatchRange = device.computeDispatchRange(numTasks, 16); cgh.parallel_for(dispatchRange, [=](sycl::nd_item<1> taskIndex) { if (taskIndex.get_global_id(0) < numTasks) { fbSh->tiles[taskIndex.get_global_id(0)].accumID = frameID; } }); }) .wait_and_throw(); #endif } tilesDirty = true; } const void *SparseFrameBuffer::mapBuffer(OSPFrameBufferChannel) { return nullptr; } void SparseFrameBuffer::unmap(const void *) {} void SparseFrameBuffer::clear() { FrameBuffer::clear(); // also clear the task error buffer if present if (taskErrorBuffer) { std::fill(taskErrorBuffer->begin(), taskErrorBuffer->end(), inf); } } size_t SparseFrameBuffer::getNumTiles() const { return tiles ? tiles->size() : 0; } const utility::ArrayView SparseFrameBuffer::getTiles() { if (!tiles) { return utility::ArrayView(nullptr, 0); } if (tilesDirty) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("SparseFB::getTiles", "ospray")); tilesDirty = false; tiles->copyToHost().wait(); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } return utility::ArrayView(tiles->hostPtr(), tiles->size()); } const utility::ArrayView SparseFrameBuffer::getTilesDevice() const { if (!tiles) { return utility::ArrayView(nullptr, 0); } return utility::ArrayView(tiles->devicePtr(), tiles->size()); } const utility::ArrayView SparseFrameBuffer::getTileIDs() { if (tileIDs.empty()) { return utility::ArrayView(nullptr, 0); } return utility::ArrayView(tileIDs.data(), tileIDs.size()); } uint32_t SparseFrameBuffer::getTileIndexForTask(uint32_t taskID) const { // Find which tile this task falls into // tileIdx -> index in the SparseFB's list of tiles return taskID / getNumTasksPerTile(); } void SparseFrameBuffer::setTiles(const std::vector &_tileIDs) { RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::beginEvent("SparseFB::setTiles", "ospray"); rkcommon::tracing::setCounter("SparseFB::numTiles", _tileIDs.size()); }); // (Re-)configure the sparse framebuffer based on the tileIDs we're passed tileIDs = _tileIDs; numRenderTasks = vec2i(tileIDs.size() * TILE_SIZE, TILE_SIZE) / getRenderTaskSize(); if (hasVarianceBuffer && !tileIDs.empty()) { taskErrorBuffer = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), numRenderTasks.long_product()); std::fill(taskErrorBuffer->begin(), taskErrorBuffer->end(), inf); } else { taskErrorBuffer = nullptr; } if (!tileIDs.empty()) { tiles = devicert::make_buffer_device_shadowed_unique( getISPCDevice().getDRTDevice(), tileIDs.size()); const vec2f rcpSize = rcp(vec2f(size)); #ifndef OSPRAY_TARGET_SYCL rkcommon::tasking::parallel_for(tiles->size(), [&](size_t i) { Tile &t = (*tiles)[i]; t.fbSize = size; t.rcp_fbSize = rcpSize; t.region = getTileRegion(tileIDs[i]); t.accumID = 0; }); #else // TODO: refactor and simplify this, we don't need so many copies of TileIDs devicert::BufferDeviceShadowedImpl deviceTileIDs( device.getDRTDevice(), tileIDs); deviceTileIDs.copyToDevice(); // In SYCL, populate the tiles on the device. // TODO: Best to unify the codepaths more here and do the ISPC device // tile population in ISPC so it also runs on the "device" const uint32_t *deviceTileIDsPtr = deviceTileIDs.devicePtr(); const size_t numTasks = tiles->size(); const vec2i fbSize = size; const vec2i fbTotalTiles = totalTiles; Tile *tilesDevice = tiles->devicePtr(); sycl::queue *queue = static_cast(device.getDRTDevice().getSyclQueuePtr()); queue ->submit([&](sycl::handler &cgh) { const sycl::nd_range<1> dispatchRange = device.computeDispatchRange(numTasks, 16); cgh.parallel_for(dispatchRange, [=](sycl::nd_item<1> taskIndex) { if (taskIndex.get_global_id(0) < numTasks) { const size_t tid = taskIndex.get_global_id(0); tilesDevice[tid].fbSize = fbSize; tilesDevice[tid].rcp_fbSize = rcpSize; tilesDevice[tid].region = ospray::getTileRegion( deviceTileIDsPtr[tid], fbSize, fbTotalTiles); tilesDevice[tid].accumID = 0; } }); }) .wait_and_throw(); #endif tilesDirty = true; } else { tiles = nullptr; } const size_t numPixels = tiles ? tileIDs.size() * TILE_SIZE * TILE_SIZE : 0; if (hasVarianceBuffer && !tileIDs.empty()) { varianceBuffer = devicert::make_buffer_device_unique( getISPCDevice().getDRTDevice(), numPixels); } else { varianceBuffer = nullptr; } // TODO: Should find a better way for allowing sparse task id sets // here we have this array b/c the tasks will be filtered down based on // variance termination if (!tileIDs.empty()) { renderTaskIDs = devicert::make_buffer_device_shadowed_unique( getISPCDevice().getDRTDevice(), getTotalRenderTasks()); std::iota(renderTaskIDs->begin(), renderTaskIDs->end(), 0); } else { renderTaskIDs = nullptr; } if (hasVarianceBuffer && !tileIDs.empty()) { activeTaskIDs = devicert::make_buffer_device_shadowed_unique( getISPCDevice().getDRTDevice(), getTotalRenderTasks()); } else { activeTaskIDs = nullptr; } const uint32_t nTasksPerTile = getNumTasksPerTile(); // Sort each tile's tasks in Z order // TODO: is this worth doing in the dynamicLB case? We make // a new sparseFb for each tile set we receive, it seems like // this won't be worth it. if (tiles) { #ifndef OSPRAY_TARGET_SYCL // We use a 1x1 task size in SYCL and this sorting may not pay off for the // cost it adds rkcommon::tasking::parallel_for(tiles->size(), [&](const size_t i) { std::sort(renderTaskIDs->begin() + i * nTasksPerTile, renderTaskIDs->begin() + (i + 1) * nTasksPerTile, [&](const uint32_t &a, const uint32_t &b) { const vec2i p_a = getTaskPosInTile(a); const vec2i p_b = getTaskPosInTile(b); return interleaveZOrder(p_a.x, p_a.y) < interleaveZOrder(p_b.x, p_b.y); }); }); #endif // Upload the task IDs to the device renderTaskIDs->copyToDevice(); } #ifndef OSPRAY_TARGET_SYCL getSh()->super.accumulateSample = reinterpret_cast( ispc::SparseFrameBuffer_accumulateSample_addr()); getSh()->super.getRenderTaskDesc = reinterpret_cast( ispc::SparseFrameBuffer_getRenderTaskDesc_addr()); getSh()->super.completeTask = reinterpret_cast( ispc::SparseFrameBuffer_completeTask_addr()); #endif getSh()->numRenderTasks = numRenderTasks; getSh()->totalTiles = totalTiles; getSh()->tiles = tiles ? tiles->devicePtr() : nullptr; getSh()->numTiles = tiles ? tiles->size() : 0; getSh()->varianceBuffer = varianceBuffer ? varianceBuffer->devicePtr() : nullptr; getSh()->taskRegionError = taskErrorBuffer ? taskErrorBuffer->data() : nullptr; RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } box2i SparseFrameBuffer::getTileRegion(uint32_t tileID) const { return ospray::getTileRegion(tileID, size, totalTiles); } vec2i SparseFrameBuffer::getTaskPosInTile(const uint32_t taskID) const { // Find where this task is supposed to render within this tile const vec2i tasksPerTile = vec2i(TILE_SIZE) / getRenderTaskSize(); const uint32 taskTileID = taskID % (tasksPerTile.x * tasksPerTile.y); vec2i taskStart(taskTileID % tasksPerTile.x, taskTileID / tasksPerTile.x); return taskStart * getRenderTaskSize(); } uint32_t SparseFrameBuffer::getNumTasksPerTile() const { const vec2i tileDims(TILE_SIZE); const vec2i tasksPerTile = tileDims / getRenderTaskSize(); return tasksPerTile.long_product(); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/SparseFB.h000066400000000000000000000112371464752671100217430ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDevice.h" #include "fb/FrameBuffer.h" #include "fb/LocalFB.h" #include "rkcommon/containers/AlignedVector.h" #include "rkcommon/utility/ArrayView.h" // ispc shared #include "TileShared.h" #include "fb/SparseFBShared.h" namespace ospray { /* The sparse framebuffer stores a subset of tiles of a larger framebuffer * to allow rendering tasks to directly write to this allocated tile memory, * rather than requiring on the fly allocation of tiles. The sparse framebuffer * is used as a component of a "parent" framebuffer that is responsible for * distributing the full image among different sparse framebuffers and * collecting the tiles from them into a complete image in some way. * * The sparse framebuffer doesn't store the entire image data and thus doesn't * support frame/tile operations or mapping. */ struct OSPRAY_SDK_INTERFACE SparseFrameBuffer : public AddStructShared { // Create a sparse framebuffer holding the tiles specified in tileIDs SparseFrameBuffer(api::ISPCDevice &device, const vec2i &size, ColorBufferFormat colorBufferFormat, const uint32 channels, const std::vector &tileIDs); // Create a sparse framebuffer that stores no image tiles. Tiles can be added // to the empty sparse framebuffer by calling setTiles SparseFrameBuffer(api::ISPCDevice &device, const vec2i &size, ColorBufferFormat colorBufferFormat, const uint32 channels); // Return the number of render tasks in the x and y direction // This is the kernel launch dims to render the image virtual vec2i getNumRenderTasks() const override; virtual uint32_t getTotalRenderTasks() const override; virtual utility::ArrayView getRenderTaskIDs( const float errorThreshold = 0.f, const uint32_t spp = 1) override; //! \brief common function to help printf-debugging /*! \detailed Every derived class should override this! */ virtual std::string toString() const override; float taskError(const uint32_t taskID) const override; /* Set the error for a given task, used by the parent framebuffer managing the * sparse framebuffers to sync error computed over the entire image */ void setTaskError(const uint32_t taskID, const float error); void beginFrame() override; devicert::AsyncEvent postProcess() override { // Do not run post-processing on sparse frame buffer return devicert::AsyncEvent(); } // Mapping sparse framebuffers is not supported, will return null const void *mapBuffer(OSPFrameBufferChannel channel) override; void unmap(const void *mappedMem) override; void clear() override; size_t getNumTiles() const; const utility::ArrayView getTiles(); // Get a view of the device memory of the tiles const utility::ArrayView getTilesDevice() const; const utility::ArrayView getTileIDs(); // Get the index of the tile in the tile ID and Tiles lists that this task // falls into uint32_t getTileIndexForTask(uint32_t taskID) const; /* Change the tiles stored in this SparseFrameBuffer, re-using the existing * storage. New tiles will be allocated if the size of the tileIDs passed * exceeds those currently stored in the SparseFrameBuffer */ void setTiles(const std::vector &tileIDs); // Return the image region for the tile box2i getTileRegion(uint32_t tileID) const; //// Data //// protected: // Get the position of a task in its tile vec2i getTaskPosInTile(const uint32_t taskID) const; uint32_t getNumTasksPerTile() const; api::ISPCDevice &device; // The tiles in this framebuffer BufferDeviceShadowedUq tiles; // Track if we need to read back tiles to the host bool tilesDirty = false; // Variance data for the image, stored in tiled order with one RGBA value per // pixel, accumulates every other sample, for variance estimation BufferDeviceUq varianceBuffer; // Does this need to be USM at all? std::vector tileIDs; // Total number of tiles that the framebuffer is divided into, including those // not owned by this sparsefb vec2i totalTiles; // Total number of render tasks that the framebuffer is divided into, // including those not owned by this sparsefb vec2i numRenderTasks{0}; // holds error per task for each tile, stored in tiled order. // The SparseFB doesn't do its own error refinement since it doesn't have // access to error data for the entire framebuffer BufferSharedUq taskErrorBuffer; BufferDeviceShadowedUq renderTaskIDs; BufferDeviceShadowedUq activeTaskIDs; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/SparseFB.ih000066400000000000000000000020341464752671100221070ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "fb/Tile.ih" // c++ shared #include "SparseFBShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL uniform RenderTaskDesc SparseFB_getRenderTaskDesc( FrameBuffer *uniform _fb, const uniform uint32 taskID); SYCL_EXTERNAL void SparseFB_accumulateSample(FrameBuffer *uniform _fb, const varying ScreenSample &screenSample, uniform RenderTaskDesc &taskDesc); SYCL_EXTERNAL void SparseFB_completeTask( FrameBuffer *uniform _fb, const uniform RenderTaskDesc &taskDesc); inline uniform uint32 SparseFB_getTileIndexForTask( const SparseFB *uniform fb, const uniform uint32 taskID) { // Find which tile this task falls into const uniform vec2i tileDims = make_vec2i(TILE_SIZE); const uniform vec2i tasksPerTile = tileDims / fb->super.renderTaskSize; const uniform int nTasksPerTile = tasksPerTile.x * tasksPerTile.y; // tileIdx -> index in the SparseFB's list of tiles return taskID / nTasksPerTile; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/SparseFB.ispc000066400000000000000000000156301464752671100224530ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "SparseFB.ih" #include "fb/FrameBuffer.ih" #include "fb/RenderTaskDesc.ih" #include "fb/Tile.ih" #include "ospray/OSPEnums.h" #include "render/Renderer.ih" #include "render/ScreenSample.ih" #include "render/util.ih" OSPRAY_BEGIN_ISPC_NAMESPACE /* Return the position of the screen sample within its tile */ inline vec2i SparseFB_getTilePixelPos(SparseFB *uniform fb, const ScreenSample &screenSample, const uniform uint32 tileIdx) { uniform vec2i tilePos = fb->tiles[tileIdx].region.lower; const vec2i tilePixelPos = make_vec2i(screenSample.sampleID.x, screenSample.sampleID.y) - tilePos; return tilePixelPos; } // Accumulates the screenSample color and alpha into the framebuffer's // accumulation buffer. // I.e., the color to be written to the final framebuffer for display for // the current frame // // tileIdx is the index of the tile that this task/sample belongs to, as // computed by SparseFB_getTileIndexForTask. sampleTilePos is the position of // the sample within this tile, via SparseFB_getTilePixelPos inline void SparseFB_accumulateTileSample(SparseFB *uniform fb, const ScreenSample &screenSample, const uniform uint32 tileIdx, const vec2i &sampleTilePos, uniform RenderTaskDesc &taskDesc) { // The location of this pixel's data within the tiled accumulation and // variance buffers const uint32 tilePixelIdx = sampleTilePos.x + TILE_SIZE * sampleTilePos.y; const vec4f sampleValue = make_vec4f(screenSample.rgb, screenSample.alpha); uniform Tile *uniform tile = fb->tiles + tileIdx; const uniform int accumID = fb->accumulate ? fb->super.frameID : 0; const uniform float accScale = rcpf(accumID + 1); // Accumulate color vec4f color = make_vec4f(tile->r[tilePixelIdx], tile->g[tilePixelIdx], tile->b[tilePixelIdx], tile->a[tilePixelIdx]); FRAMEBUFFER_ACCUMULATE_VALUE(color, sampleValue, accScale); tile->r[tilePixelIdx] = color.x; tile->g[tilePixelIdx] = color.y; tile->b[tilePixelIdx] = color.z; tile->a[tilePixelIdx] = color.w; // Accumulate depth float depth = screenSample.z; if (accumID > 0) depth = min(tile->z[tilePixelIdx], screenSample.z); tile->z[tilePixelIdx] = depth; // Accumulate normal vec3f normal = make_vec3f( tile->nx[tilePixelIdx], tile->ny[tilePixelIdx], tile->nz[tilePixelIdx]); FRAMEBUFFER_ACCUMULATE_VALUE(normal, screenSample.normal, accScale); tile->nx[tilePixelIdx] = normal.x; tile->ny[tilePixelIdx] = normal.y; tile->nz[tilePixelIdx] = normal.z; // Accumulate albedo vec3f albedo = make_vec3f( tile->ar[tilePixelIdx], tile->ag[tilePixelIdx], tile->ab[tilePixelIdx]); FRAMEBUFFER_ACCUMULATE_VALUE(albedo, screenSample.albedo, accScale); tile->ar[tilePixelIdx] = albedo.x; tile->ag[tilePixelIdx] = albedo.y; tile->ab[tilePixelIdx] = albedo.z; tile->pid[tilePixelIdx] = screenSample.primID; tile->gid[tilePixelIdx] = screenSample.geomID; tile->iid[tilePixelIdx] = screenSample.instID; uniform vec4f *uniform variance = fb->varianceBuffer; if (fb->super.accumulateVariance) { const uniform float accVarScale = rcpf(accumID / 2 + 1); const uint32 varianceAccumIndex = tileIdx * TILE_SIZE * TILE_SIZE + sampleTilePos.x + TILE_SIZE * sampleTilePos.y; FRAMEBUFFER_ACCUMULATE_VALUE( variance[varianceAccumIndex], sampleValue, accVarScale); // Calculate error float err = 0.f; int cnt = 0; const float den2 = reduce_add(make_vec3f(color)) + (1.f - color.w); // invert alpha (bright alpha is more important) if (den2 > 0.f) { const vec4f diff = absf(color - variance[varianceAccumIndex]); err = reduce_add(diff) * rsqrtf(den2); cnt = 1; } // We max over the task because we may have more pixels in the task than // the SIMD width taskDesc.error += reduce_add(err); taskDesc.count += reduce_add(cnt); } } SYCL_EXTERNAL void SparseFB_accumulateSample(FrameBuffer *uniform _fb, const varying ScreenSample &screenSample, uniform RenderTaskDesc &taskDesc) { SparseFB *uniform fb = (SparseFB * uniform) _fb; // tileIdx -> index in the SparseFB's list of tiles const uniform uint32 tileIdx = SparseFB_getTileIndexForTask(fb, taskDesc.taskID); const vec2i sampleTilePos = SparseFB_getTilePixelPos(fb, screenSample, tileIdx); SparseFB_accumulateTileSample( fb, screenSample, tileIdx, sampleTilePos, taskDesc); #ifndef OSPRAY_TARGET_SYCL FrameBuffer_updateProgress(&fb->super, popcnt(lanemask())); #endif } SYCL_EXTERNAL uniform RenderTaskDesc SparseFB_getRenderTaskDesc( FrameBuffer *uniform _fb, const uniform uint32 taskID) { SparseFB *uniform fb = (SparseFB * uniform) _fb; // Map to the tile and then the set of pixels within that tile. uniform RenderTaskDesc desc; desc.taskID = taskID; desc.error = 0.f; desc.count = 0; const uniform uint32 tileIdx = SparseFB_getTileIndexForTask(fb, taskID); // Find where this task is supposed to render within this tile const uniform vec2i tileDims = make_vec2i(TILE_SIZE); const uniform vec2i tasksPerTile = tileDims / fb->super.renderTaskSize; const uniform uint32 taskTileID = taskID % (tasksPerTile.x * tasksPerTile.y); uniform vec2i taskStart = make_vec2i(taskTileID % tasksPerTile.x, taskTileID / tasksPerTile.x); desc.region.lower = taskStart * fb->super.renderTaskSize; desc.region.upper = desc.region.lower + fb->super.renderTaskSize; // Offset the task's region by the tile location const uniform vec2i tilePos = fb->tiles[tileIdx].region.lower; desc.region.lower = desc.region.lower + tilePos; desc.region.upper = min(desc.region.upper + tilePos, fb->super.size); // TODO: In the end, shouldn't generate these out of bounds tasks for the // padded framebuffer region? For now just mark them as having no error // In the past the tiled load balancer would also generate these though, with // how we padded out to the tile dims if (isEmpty(desc.region) && fb->taskRegionError) { fb->taskRegionError[taskID] = 0.f; } return desc; } SYCL_EXTERNAL void SparseFB_completeTask( FrameBuffer *uniform _fb, const uniform RenderTaskDesc &taskDesc) { // Write error for the task SparseFB *uniform fb = (SparseFB * uniform) _fb; if (fb->super.accumulateVariance) { uniform float err = taskDesc.error; if (taskDesc.count) err *= rcp((uniform float)taskDesc.count); // avg // scale to be backwards compatible with the old default tile size of 64x64 fb->taskRegionError[taskDesc.taskID] = err * 64.f; } } #ifndef OSPRAY_TARGET_SYCL export void *uniform SparseFrameBuffer_accumulateSample_addr() { return (void *uniform)SparseFB_accumulateSample; } export void *uniform SparseFrameBuffer_getRenderTaskDesc_addr() { return (void *uniform)SparseFB_getRenderTaskDesc; } export void *uniform SparseFrameBuffer_completeTask_addr() { return (void *uniform)SparseFB_completeTask; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/SparseFBShared.h000066400000000000000000000023601464752671100230670ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "FrameBufferShared.h" #include "TileShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // a SparseFrameBuffer stores a subset of the full framebuffer as Tiles struct SparseFB { // superclass that we inherit from FrameBuffer super; // Number of tasks being used to render the image in x & y vec2i numRenderTasks; // The total number of tiles that the framebuffer is divided into vec2i totalTiles; uint32 numTiles; // Image data for the tiles in this SparseFrameBuffer Tile *tiles; // accumulates every other sample, for variance estimation / stopping vec4f *varianceBuffer; // holds error per task region, for adaptive accumulation float *taskRegionError; // the dynamic loadbalancer accumulates not in the rendertask, but the owning // rank accumulates the arriving tiles bool accumulate; #ifdef __cplusplus SparseFB() : numRenderTasks(0), totalTiles(0), numTiles(0), tiles(nullptr), varianceBuffer(nullptr), taskRegionError(nullptr), accumulate(false) { super.type = FRAMEBUFFER_TYPE_SPARSE; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/fb/TaskError.cpp000066400000000000000000000070151464752671100225440ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "TaskError.h" #include namespace ospray { TaskError::TaskError(devicert::Device &device, const vec2i &_numTasks) : numTasks(_numTasks) { if (numTasks.long_product() > 0) { taskErrorBuffer = devicert::make_buffer_shared_unique( device, numTasks.long_product()); // maximum number of regions: all regions are of size 3 are split in // half errorRegion.reserve(divRoundUp(taskErrorBuffer->size() * 2, size_t(3))); clear(); } } void TaskError::clear() { if (!taskErrorBuffer) { return; } std::fill(taskErrorBuffer->begin(), taskErrorBuffer->end(), inf); errorRegion.clear(); // initially create one region covering the complete tile/image errorRegion.push_back(box2i(vec2i(0), numTasks)); } float TaskError::operator[](const int id) const { if (!taskErrorBuffer) { return inf; } return (*taskErrorBuffer)[id]; } void TaskError::update(const vec2i &task, const float err) { if (taskErrorBuffer) { (*taskErrorBuffer)[task.y * numTasks.x + task.x] = err; } } float TaskError::refine(const float errorThreshold) { if (!taskErrorBuffer) { return inf; } float maxErr = 0.f; float sumActErr = 0.f; int activeTasks = 0; for (const auto &err : *taskErrorBuffer) { maxErr = std::max(maxErr, err); if (err > errorThreshold) { sumActErr += err; activeTasks++; } } const float error = activeTasks ? sumActErr / activeTasks : maxErr; // process regions first, but don't process newly split regions again int regions = errorThreshold > 0.f ? errorRegion.size() : 0; for (int i = 0; i < regions; i++) { box2i ®ion = errorRegion[i]; float err = 0.f; float maxErr = 0.f; for (int y = region.lower.y; y < region.upper.y; y++) for (int x = region.lower.x; x < region.upper.x; x++) { int idx = y * numTasks.x + x; err += (*taskErrorBuffer)[idx]; maxErr = std::max(maxErr, (*taskErrorBuffer)[idx]); } if (maxErr > errorThreshold) { // set all tasks of this region to >errorThreshold to enforce their // refinement as a group const float minErr = nextafter(errorThreshold, inf); for (int y = region.lower.y; y < region.upper.y; y++) for (int x = region.lower.x; x < region.upper.x; x++) { int idx = y * numTasks.x + x; (*taskErrorBuffer)[idx] = std::max((*taskErrorBuffer)[idx], minErr); } } const vec2i size = region.size(); const int area = reduce_mul(size); err /= area; // == avg if (err <= 4.f * errorThreshold) { // split region? // if would just contain single task after split or wholly done: remove if (area <= 2 || maxErr <= errorThreshold) { regions--; errorRegion[i] = errorRegion[regions]; errorRegion[regions] = errorRegion.back(); errorRegion.pop_back(); i--; continue; } const vec2i split = region.lower + size / 2; // TODO: find split with // equal variance errorRegion.push_back(region); // region ref might become invalid if (size.x > size.y) { errorRegion[i].upper.x = split.x; errorRegion.back().lower.x = split.x; } else { errorRegion[i].upper.y = split.y; errorRegion.back().lower.y = split.y; } } } return error; } float *TaskError::errorBuffer() { return taskErrorBuffer ? taskErrorBuffer->data() : nullptr; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/TaskError.h000066400000000000000000000022341464752671100222070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "common/DeviceRT.h" #include "common/OSPCommon.h" #include "rkcommon/containers/AlignedVector.h" namespace ospray { /* manages error per tile and adaptive regions, for variance estimation Implementation based on Dammertz et al., "A Hierarchical Automatic Stopping Condition for Monte Carlo Global Illumination", WSCG 2010 */ class OSPRAY_SDK_INTERFACE TaskError { public: TaskError(devicert::Device &device, const vec2i &numTasks); // The default constructor will make an empty task error region TaskError() = default; void clear(); float operator[](const int id) const; void update(const vec2i &task, const float error); float refine(const float errorThreshold); // Return the error buffer, or null if there are no tiles that error is // tracked for float *errorBuffer(); protected: vec2i numTasks = vec2i(0); // holds error per task BufferSharedUq taskErrorBuffer; // image regions (in #tasks) that do not yet estimate the error on // per-task basis std::vector errorRegion; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/Tile.ih000066400000000000000000000022001464752671100213320ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/box.ih" // c++ shared #include "TileShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void setRGBA(uniform Tile &tile, const varying uint32 i, const varying vec3f rgb, const varying float alpha = 0.f) { tile.r[i] = rgb.x; tile.g[i] = rgb.y; tile.b[i] = rgb.z; tile.a[i] = alpha; } inline void setRGBAZ(uniform Tile &tile, const varying uint32 i, const varying vec3f rgb, const varying float alpha, const varying float z) { tile.r[i] = rgb.x; tile.g[i] = rgb.y; tile.b[i] = rgb.z; tile.a[i] = alpha; tile.z[i] = z; } inline void setRGBA( uniform Tile &tile, const varying uint32 i, const varying vec4f rgba) { tile.r[i] = rgba.x; tile.g[i] = rgba.y; tile.b[i] = rgba.z; tile.a[i] = rgba.w; } inline void setNormalAlbedo( uniform Tile &tile, const uint32 i, const vec3f normal, const vec3f albedo) { tile.nx[i] = normal.x; tile.ny[i] = normal.y; tile.nz[i] = normal.z; tile.ar[i] = albedo.x; tile.ag[i] = albedo.y; tile.ab[i] = albedo.z; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/TileShared.h000066400000000000000000000105761464752671100223270ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "OSPConfig.h" #ifdef __cplusplus namespace ispc { #endif #ifdef __cplusplus static_assert(TILE_SIZE > 0 && (TILE_SIZE & (TILE_SIZE - 1)) == 0, "OSPRay config error: TILE_SIZE must be a positive power of two."); #endif // Extra defines to hide some differences between ISPC/C++ to unify the // declaration // TODO: remove all uniform/varying modifiers from Tile and VaryingTile #ifdef __cplusplus #ifndef OSPRAY_TARGET_SYCL #define uniform #endif #else #define OSPRAY_SDK_INTERFACE #endif #ifndef OSPRAY_SDK_INTERFACE #define OSPRAY_SDK_INTERFACE #endif //! a tile of pixels used by any tile-based renderer /*! pixels in the tile are in a row-major TILE_SIZE x TILE_SIZE pattern. the 'region' specifies which part of the screen this tile belongs to: tile.lower is the lower-left coordinate of this tile (and a multiple of TILE_SIZE); the 'upper' value may be smaller than the upper-right edge of the "full" tile. note that a tile contains "all" of the values a renderer might want to use. not all renderers nor all frame buffers will use all those values; it's up to the renderer and frame buffer to agree on which fields will be set. Similarly, the frame buffer may actually use uchars, but the tile will always store floats. */ struct OSPRAY_SDK_INTERFACE Tile { uniform range2i region; uniform vec2i fbSize; uniform vec2f rcp_fbSize; uniform int32 generation; uniform int32 children; uniform int32 sortOrder; uniform int32 accumID; uniform float pad[4]; // padding to match the varying tile layout uniform float r[TILE_SIZE * TILE_SIZE]; // red uniform float g[TILE_SIZE * TILE_SIZE]; // green uniform float b[TILE_SIZE * TILE_SIZE]; // blue uniform float a[TILE_SIZE * TILE_SIZE]; // alpha uniform float z[TILE_SIZE * TILE_SIZE]; // depth uniform float nx[TILE_SIZE * TILE_SIZE]; // normal x uniform float ny[TILE_SIZE * TILE_SIZE]; // normal y uniform float nz[TILE_SIZE * TILE_SIZE]; // normal z uniform float ar[TILE_SIZE * TILE_SIZE]; // albedo red uniform float ag[TILE_SIZE * TILE_SIZE]; // albedo green uniform float ab[TILE_SIZE * TILE_SIZE]; // albedo blue uniform uint32 pid[TILE_SIZE * TILE_SIZE]; // primID uniform uint32 gid[TILE_SIZE * TILE_SIZE]; // objID uniform uint32 iid[TILE_SIZE * TILE_SIZE]; // instanceID #ifdef __cplusplus Tile() : region(empty), fbSize(0), rcp_fbSize(0.f), generation(0), children(0), sortOrder(0), accumID(0) {} Tile(const vec2i &tile, const vec2i &fbsize, const int32 accumId) : fbSize(fbsize), accumID(accumId) { rcp_fbSize.x = rcp(float(fbSize.x)); rcp_fbSize.y = rcp(float(fbSize.y)); region.lower = tile * TILE_SIZE; region.upper = min(region.lower + TILE_SIZE, fbsize); } #endif }; #if !defined(__cplusplus) || defined(OSPRAY_TARGET_SYCL) struct VaryingTile { uniform range2i region; // 4 ints uniform vec2i fbSize; // 2 ints uniform vec2f rcp_fbSize; // 2 floats uniform int32 generation; uniform int32 children; uniform int32 sortOrder; uniform int32 accumID; uniform float pad[4]; // explicit padding to match on SSE, this padding is // implicitly added on AVX and AVX512 to align the // vectors though. We need it here to match on SSE varying float r[TILE_SIZE * TILE_SIZE / programCount]; varying float g[TILE_SIZE * TILE_SIZE / programCount]; varying float b[TILE_SIZE * TILE_SIZE / programCount]; varying float a[TILE_SIZE * TILE_SIZE / programCount]; varying float z[TILE_SIZE * TILE_SIZE / programCount]; varying float nx[TILE_SIZE * TILE_SIZE / programCount]; varying float ny[TILE_SIZE * TILE_SIZE / programCount]; varying float nz[TILE_SIZE * TILE_SIZE / programCount]; varying float ar[TILE_SIZE * TILE_SIZE / programCount]; varying float ag[TILE_SIZE * TILE_SIZE / programCount]; varying float ab[TILE_SIZE * TILE_SIZE / programCount]; varying uint32 pid[TILE_SIZE * TILE_SIZE / programCount]; // primID varying uint32 gid[TILE_SIZE * TILE_SIZE / programCount]; // objID varying uint32 iid[TILE_SIZE * TILE_SIZE / programCount]; // instanceID }; #endif #ifdef __cplusplus #ifndef OSPRAY_TARGET_SYCL #undef uniform #endif #else #undef OSPRAY_SDK_INTERFACE #endif #ifdef __cplusplus } namespace ospray { using Tile = ispc::Tile; } #endif RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/000077500000000000000000000000001464752671100220745ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Blur.cpp000066400000000000000000000032341464752671100235060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Blur.h" #include "fb/FrameBufferView.h" DECLARE_FRAMEOP_KERNEL_LAUNCHER(BlurHorizontal_kernelLauncher); DECLARE_FRAMEOP_KERNEL_LAUNCHER(BlurVertical_kernelLauncher); namespace ospray { BlurFrameOp::BlurFrameOp(devicert::Device &device) : FrameOp(device) {} std::unique_ptr BlurFrameOp::attach( FrameBufferView &fbView) { return rkcommon::make_unique(device, fbView); } std::string BlurFrameOp::toString() const { return "ospray::BlurFrameOp"; } LiveBlurFrameOp::LiveBlurFrameOp( devicert::Device &device, FrameBufferView &fbView) : AddStructShared(device, device, fbView), scratch(device, fbView.viewDims.long_product()) { // Set pointer to scratch buffer getSh()->scratchBuffer = scratch.devicePtr(); // Calculate blur weights const float variance = 9.f; for (uint32_t i = 0; i <= BLUR_RADIUS; i++) { getSh()->weights[i] = 1.f / std::sqrt(2.f * M_PI * variance) * std::exp(-float(i * i) / (2.f * variance)); } float weightSum = 0.f; for (int32_t i = -BLUR_RADIUS; i <= BLUR_RADIUS; i++) weightSum += getSh()->weights[abs(i)]; for (uint32_t i = 0; i <= BLUR_RADIUS; i++) getSh()->weights[i] /= weightSum; } devicert::AsyncEvent LiveBlurFrameOp::process() { // Horizontal copying pass const vec2ui &itemDims = getSh()->super.viewDims; device.launchFrameOpKernel( itemDims, ispc::BlurHorizontal_kernelLauncher, &getSh()->super); // Vertical in-place pass return device.launchFrameOpKernel( itemDims, ispc::BlurVertical_kernelLauncher, &getSh()->super); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Blur.h000066400000000000000000000013751464752671100231570ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "fb/FrameOp.h" // ispc shared #include "BlurShared.h" namespace ospray { // The blur frame op is a test which applies a Gaussian blur to the frame struct OSPRAY_SDK_INTERFACE BlurFrameOp : public FrameOp { BlurFrameOp(devicert::Device &device); std::unique_ptr attach( FrameBufferView &fbView) override; std::string toString() const override; }; struct OSPRAY_SDK_INTERFACE LiveBlurFrameOp : public AddStructShared { LiveBlurFrameOp(devicert::Device &device, FrameBufferView &fbView); devicert::AsyncEvent process() override; private: devicert::BufferDevice scratch; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Blur.ispc000066400000000000000000000031061464752671100236600ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DeviceRT.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "BlurShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void BlurHorizontal_kernel( const vec2ui itemIndex, const FrameBufferView *uniform fbvSelf) { const LiveBlur *uniform self = (const LiveBlur *uniform)fbvSelf; uniform const vec2ui &itemDims = fbvSelf->viewDims; const vec4f *uniform inputBuffer = fbvSelf->colorBufferInput; vec4f v = make_vec4f(0.f); for (int32 i = -BLUR_RADIUS; i <= BLUR_RADIUS; i++) { const uint32 i0 = itemIndex.x + i; const uint32 absi = abs(i); if (i0 < itemDims.x) { v = v + inputBuffer[itemIndex.y * itemDims.x + i0] * self->weights[absi]; } } self->scratchBuffer[itemIndex.y * itemDims.x + itemIndex.x] = v; } inline void BlurVertical_kernel( const vec2ui itemIndex, const FrameBufferView *uniform fbvSelf) { const LiveBlur *uniform self = (const LiveBlur *uniform)fbvSelf; uniform const vec2ui &itemDims = fbvSelf->viewDims; const vec4f *uniform inputBuffer = self->scratchBuffer; vec4f v = make_vec4f(0.f); for (int32 i = -BLUR_RADIUS; i <= BLUR_RADIUS; i++) { const uint32 i0 = itemIndex.y + i; const uint32 absi = abs(i); if (i0 < itemDims.y) { v = v + inputBuffer[i0 * itemDims.x + itemIndex.x] * self->weights[absi]; } } fbvSelf->colorBufferOutput[itemIndex.y * itemDims.x + itemIndex.x] = v; } DEFINE_FRAMEOP_KERNEL_LAUNCHER(BlurHorizontal_kernel); DEFINE_FRAMEOP_KERNEL_LAUNCHER(BlurVertical_kernel); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/BlurShared.h000066400000000000000000000005021464752671100242750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "fb/FrameBufferView.ih" #ifdef __cplusplus namespace ispc { #endif #define BLUR_RADIUS 4 struct LiveBlur { FrameBufferView super; vec4f *scratchBuffer; float weights[BLUR_RADIUS + 1]; }; #ifdef __cplusplus } #endif RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ColorConversion.cpp000066400000000000000000000015471464752671100257330ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ColorConversion.h" #include "fb/FrameBufferView.h" DECLARE_FRAMEOP_KERNEL_LAUNCHER(ColorConversion_kernelLauncher); namespace ospray { LiveColorConversionFrameOp::LiveColorConversionFrameOp(devicert::Device &device, FrameBufferView &fbView, OSPFrameBufferFormat targetColorFormat) : AddStructShared(device, device, fbView), convBuffer( device, fbView.viewDims.long_product() * sizeOf(targetColorFormat)) { getSh()->targetColorFormat = targetColorFormat; getSh()->convBuffer = convBuffer.devicePtr(); } devicert::AsyncEvent LiveColorConversionFrameOp::process() { const vec2ui &itemDims = getSh()->super.viewDims; return device.launchFrameOpKernel( itemDims, ispc::ColorConversion_kernelLauncher, &getSh()->super); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ColorConversion.h000066400000000000000000000013031464752671100253660ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "common/DeviceRTImpl.h" #include "fb/FrameOp.h" // ispc shared #include "ColorConversionShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE LiveColorConversionFrameOp : public AddStructShared { LiveColorConversionFrameOp(devicert::Device &device, FrameBufferView &fbView, OSPFrameBufferFormat targetColorFormat); devicert::AsyncEvent process() override; devicert::BufferDeviceShadowed &getConvertedBuffer() { return convBuffer; } private: devicert::BufferDeviceShadowedImpl convBuffer; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ColorConversion.ispc000066400000000000000000000020231464752671100260750ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DeviceRT.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "ColorConversionShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void ColorConversion_kernel( const vec2ui itemIndex, const FrameBufferView *uniform fbvSelf) { const LiveColorConversion *uniform self = (const LiveColorConversion *uniform)fbvSelf; const uint32 i = itemIndex.y * fbvSelf->viewDims.x + itemIndex.x; vec4f v = fbvSelf->colorBufferInput[i]; switch (self->targetColorFormat) { case OSP_FB_RGBA8: { uint32 *uniform typedCB = (uint32 * uniform) self->convBuffer; typedCB[i] = cvt_uint32(v); } break; case OSP_FB_SRGBA: { uint32 *uniform typedCB = (uint32 * uniform) self->convBuffer; typedCB[i] = linear_to_srgba8(v); } break; case OSP_FB_RGBA32F: { // Should never get here } break; default: // Should never get here break; } } DEFINE_FRAMEOP_KERNEL_LAUNCHER(ColorConversion_kernel); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ColorConversionShared.h000066400000000000000000000006171464752671100265240ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "fb/FrameBufferView.ih" #include "ospray/OSPEnums.h" #ifdef __cplusplus namespace ispc { #endif struct LiveColorConversion { FrameBufferView super; // Target color format OSPFrameBufferFormat targetColorFormat; // Converted color buffer void *convBuffer; }; #ifdef __cplusplus } #endif RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Debug.cpp000066400000000000000000000015361464752671100236330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Debug.h" #include "fb/FrameBufferView.h" DECLARE_FRAMEOP_KERNEL_LAUNCHER(Debug_kernelLauncher); namespace ospray { DebugFrameOp::DebugFrameOp(devicert::Device &device) : FrameOp(device) {} std::unique_ptr DebugFrameOp::attach( FrameBufferView &fbView) { return rkcommon::make_unique(device, fbView); } std::string DebugFrameOp::toString() const { return "ospray::DebugFrameOp"; } LiveDebugFrameOp::LiveDebugFrameOp( devicert::Device &device, FrameBufferView &fbView) : LiveFrameOp(device, fbView) {} devicert::AsyncEvent LiveDebugFrameOp::process() { const vec2ui &itemDims = getSh()->viewDims; return device.launchFrameOpKernel( itemDims, ispc::Debug_kernelLauncher, getSh()); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Debug.h000066400000000000000000000011011464752671100232640ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "fb/FrameOp.h" namespace ospray { struct OSPRAY_SDK_INTERFACE DebugFrameOp : public FrameOp { DebugFrameOp(devicert::Device &device); std::unique_ptr attach( FrameBufferView &fbView) override; std::string toString() const override; }; struct OSPRAY_SDK_INTERFACE LiveDebugFrameOp : public LiveFrameOp { LiveDebugFrameOp(devicert::Device &device, FrameBufferView &fbView); devicert::AsyncEvent process() override; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Debug.ispc000066400000000000000000000010271464752671100240020ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DeviceRT.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "fb/FrameBufferView.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline void Debug_kernel( const vec2ui itemIndex, const FrameBufferView *uniform self) { const uint32 i = itemIndex.y * self->viewDims.x + itemIndex.x; vec4f v = self->colorBufferInput[i]; v.x = 1.f; self->colorBufferOutput[i] = v; } DEFINE_FRAMEOP_KERNEL_LAUNCHER(Debug_kernel); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ToneMapper.cpp000066400000000000000000000051011464752671100246470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ToneMapper.h" #include "fb/FrameBufferView.h" DECLARE_FRAMEOP_KERNEL_LAUNCHER(ToneMapper_kernelLauncher); namespace ospray { ToneMapperFrameOp::ToneMapperFrameOp(devicert::Device &device) : FrameOp(device) {} void ToneMapperFrameOp::commit() { FrameOp::commit(); exposure = getParam("exposure", 1.f); // Default parameters fitted to the ACES 1.0 grayscale curve // (RRT.a1.0.3 + ODT.Academy.Rec709_100nits_dim.a1.0.3) // We included exposure adjustment to match 18% middle gray // (ODT(RRT(0.18)) = 0.18) const float aces_contrast = 1.6773f; const float aces_shoulder = 0.9714f; const float aces_midIn = 0.18f; const float aces_midOut = 0.18f; const float aces_hdrMax = 11.0785f; a = max(getParam("contrast", aces_contrast), 0.0001f); d = clamp(getParam("shoulder", aces_shoulder), 0.0001f, 1.f); float m = clamp(getParam("midIn", aces_midIn), 0.0001f, 1.f); float n = clamp(getParam("midOut", aces_midOut), 0.0001f, 1.f); float w = max(getParam("hdrMax", aces_hdrMax), 1.f); acesColor = getParam("acesColor", true); // Solve b and c b = -((powf(m, -a * d) * (-powf(m, a) + (n * (powf(m, a * d) * n * powf(w, a) - powf(m, a) * powf(w, a * d))) / (powf(m, a * d) * n - n * powf(w, a * d)))) / n); // avoid discontinuous curve by clamping to 0 c = max((powf(m, a * d) * n * powf(w, a) - powf(m, a) * powf(w, a * d)) / (powf(m, a * d) * n - n * powf(w, a * d)), 0.f); } std::unique_ptr ToneMapperFrameOp::attach( FrameBufferView &fbView) { return rkcommon::make_unique( device, fbView, exposure, a, b, c, d, acesColor); } std::string ToneMapperFrameOp::toString() const { return "ospray::ToneMapperFrameOp"; } LiveToneMapperFrameOp::LiveToneMapperFrameOp(devicert::Device &device, FrameBufferView &fbView, float exposure, float a, float b, float c, float d, bool acesColor) : AddStructShared(device, device, fbView) { // Pass tone mapping parameters getSh()->exposure = exposure; getSh()->a = a; getSh()->b = b; getSh()->c = c; getSh()->d = d; getSh()->acesColor = acesColor; } devicert::AsyncEvent LiveToneMapperFrameOp::process() { const vec2ui &itemDims = getSh()->super.viewDims; return device.launchFrameOpKernel( itemDims, ispc::ToneMapper_kernelLauncher, &getSh()->super); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ToneMapper.h000066400000000000000000000020601464752671100243150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "fb/FrameOp.h" // ispc shared #include "ToneMapperShared.h" namespace ospray { /*! \brief Generic tone mapping operator approximating ACES by default. */ struct OSPRAY_SDK_INTERFACE ToneMapperFrameOp : public FrameOp { ToneMapperFrameOp(devicert::Device &device); void commit() override; std::unique_ptr attach( FrameBufferView &fbView) override; std::string toString() const override; private: // Params for the tone mapping curve float a{1.6773f}, b{1.11743f}, c{0.244676f}, d{0.9714f}; bool acesColor{true}; float exposure{1.f}; }; struct OSPRAY_SDK_INTERFACE LiveToneMapperFrameOp : public AddStructShared { LiveToneMapperFrameOp(devicert::Device &device, FrameBufferView &fbView, float exposure, float a, float b, float c, float d, bool acesColor); // Execute FrameOp kernel devicert::AsyncEvent process() override; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ToneMapper.ispc000066400000000000000000000031401464752671100250240ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DeviceRT.ih" #include "rkcommon/math/LinearSpace.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "ToneMapperShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void ToneMapper_kernel( const vec2ui itemIndex, const FrameBufferView *uniform fbvSelf) { // ACES input transform matrix = RRT_SAT_MAT * XYZ_2_AP1_MAT * D65_2_D60_CAT * // REC709_2_XYZ_PRI_MAT const uniform LinearSpace3f acesInputMat = { {0.5972782409f, 0.0760130499f, 0.0284085382f}, {0.3545713181f, 0.9083220973f, 0.1338243154f}, {0.0482176639f, 0.0156579968f, 0.8375684636f}}; // ACES output transform matrix = XYZ_2_REC709_PRI_MAT * D60_2_D65_CAT * // AP1_2_XYZ_MAT * ODT_SAT_MAT const uniform LinearSpace3f acesOutputMat = { {1.6047539945f, -0.1020831870f, -0.0032670420f}, {-0.5310794927f, 1.1081322801f, -0.0727552477f}, {-0.0736720338f, -0.0060518756f, 1.0760219533f}}; const LiveToneMapper *uniform self = (const LiveToneMapper *uniform)fbvSelf; uniform const vec2ui &itemDims = fbvSelf->viewDims; const uint32 i = itemIndex.y * itemDims.x + itemIndex.x; vec4f col = fbvSelf->colorBufferInput[i]; vec3f x = make_vec3f(col) * self->exposure; if (self->acesColor) x = acesInputMat * x; x = pow(x, self->a) / (pow(x, self->a * self->d) * self->b + self->c); if (self->acesColor) x = acesOutputMat * x; x = clamp(x, make_vec3f(0.f), make_vec3f(1.f)); fbvSelf->colorBufferOutput[i] = make_vec4f(x, col.w); } DEFINE_FRAMEOP_KERNEL_LAUNCHER(ToneMapper_kernel); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/ToneMapperShared.h000066400000000000000000000010141464752671100254420ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "fb/FrameBufferView.ih" #ifdef __cplusplus namespace ispc { #endif // Based on the generic filmic tone mapping operator from // [Lottes, 2016, "Advanced Techniques and Optimization of HDR Color Pipelines"] struct LiveToneMapper { FrameBufferView super; // linear exposure adjustment float exposure; // coefficients float a, b, c, d; // ACES color transform flag bool acesColor; }; #ifdef __cplusplus } #endif RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Variance.cpp000066400000000000000000000025201464752671100243270ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Variance.h" #include "fb/FrameBufferView.h" DECLARE_FRAMEOP_KERNEL_LAUNCHER(Variance_kernelLauncher); namespace ospray { LiveVarianceFrameOp::LiveVarianceFrameOp(devicert::Device &device, FrameBufferView &fbView, const vec4f *varianceBuffer) : AddStructShared(device, device, fbView), taskVariance(device, fbView.viewDims.product()) { // Prepare kernel constant variables getSh()->rtSize = divRoundUp(fbView.fbDims, fbView.viewDims); getSh()->varianceBuffer = varianceBuffer; getSh()->taskVarianceBuffer = taskVariance.data(); } devicert::AsyncEvent LiveVarianceFrameOp::process() { // Run kernel const vec2ui &itemDims = getSh()->super.viewDims; firstRun = false; return device.launchFrameOpKernel( itemDims, ispc::Variance_kernelLauncher, &getSh()->super); } float LiveVarianceFrameOp::getAvgError(const float errorThreshold) const { float maxErr = 0.f; float sumActErr = 0.f; int activeTasks = 0; std::for_each( taskVariance.cbegin(), taskVariance.cend(), [&](const float &err) { maxErr = std::max(maxErr, err); if (err >= errorThreshold) { sumActErr += err; activeTasks++; } }); return activeTasks ? sumActErr / activeTasks : maxErr; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Variance.h000066400000000000000000000017451464752671100240040ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "fb/FrameOp.h" // ispc shared #include "VarianceShared.h" namespace ospray { // The variance frame op calculates per-RenderTask variance struct OSPRAY_SDK_INTERFACE LiveVarianceFrameOp : public AddStructShared { LiveVarianceFrameOp(devicert::Device &device, FrameBufferView &fbView, const vec4f *varianceBuffer); devicert::AsyncEvent process() override; void restart(); bool validError() const; float getError(const uint32_t id) const; float getAvgError(const float errorThreshold) const; private: devicert::BufferShared taskVariance; bool firstRun{true}; }; inline void LiveVarianceFrameOp::restart() { firstRun = true; } inline bool LiveVarianceFrameOp::validError() const { return firstRun == false; } inline float LiveVarianceFrameOp::getError(const uint32_t id) const { return taskVariance[id]; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/Variance.ispc000066400000000000000000000036271464752671100245140ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DeviceRT.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "VarianceShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void Variance_kernel( const vec2ui itemIndex, const FrameBufferView *uniform fbvSelf) { uniform const vec2ui &rtDims = fbvSelf->viewDims; uniform const vec2ui &fbDims = fbvSelf->fbDims; const vec4f *uniform colorBuffer = fbvSelf->colorBufferInput; const LiveVariance *uniform self = (const LiveVariance *uniform)fbvSelf; uniform const vec2ui rtSize = self->rtSize; const vec4f *uniform varianceBuffer = self->varianceBuffer; const vec2ui rtLower = itemIndex * rtSize; // Iterate over all pixels within single render task and calculate maximum // variance over collected samples float v = 0.f; int cnt = 0; for (uniform uint32 rtY = 0; rtY < rtSize.y; rtY++) { // Skip if out of range const uint32 fbY = rtLower.y + rtY; if (fbY >= fbDims.y) continue; for (uniform uint32 rtX = 0; rtX < rtSize.x; rtX++) { // Skip if out of range const uint32 fbX = rtLower.x + rtX; if (fbX >= fbDims.x) continue; const uint32 linearId = fbY * fbDims.x + fbX; const vec4f color = colorBuffer[linearId]; const vec4f variance = varianceBuffer[linearId]; const float den2 = reduce_add(make_vec3f(color)) + (1.f - color.w); // invert alpha (bright alpha is more important) if (den2 > 0.f) { cnt++; const vec4f diff = absf(color - variance); v += reduce_add(diff) * rsqrtf(den2); } } } if (cnt) v *= rcp((float)cnt); // avg const uint32 lId = itemIndex.y * rtDims.x + itemIndex.x; // scale to be backwards compatible with the old default tile size of 64x64 self->taskVarianceBuffer[lId] = v * 64.f; } DEFINE_FRAMEOP_KERNEL_LAUNCHER(Variance_kernel); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/fb/frame_ops/VarianceShared.h000066400000000000000000000005031464752671100251220ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "fb/FrameBufferView.ih" #ifdef __cplusplus namespace ispc { #endif struct LiveVariance { FrameBufferView super; vec2ui rtSize; const vec4f *varianceBuffer; float *taskVarianceBuffer; }; #ifdef __cplusplus } #endif RenderKit-ospray-85af292/modules/cpu/fb/registration.cpp000066400000000000000000000011731464752671100233410ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // We don't want an instance of ObjectFactory static table in this library // so we have to include it with import define so the table will be imported // from 'ospray' library #define OBJECTFACTORY_IMPORT #include "common/ObjectFactory.h" #include "frame_ops/Blur.h" #include "frame_ops/Debug.h" #include "frame_ops/ToneMapper.h" namespace ospray { void registerAllImageOps() { ImageOp::registerType("blur"); ImageOp::registerType("debug"); ImageOp::registerType("tonemapper"); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/fb/registration.h000066400000000000000000000002231464752671100230010ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllImageOps(); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/000077500000000000000000000000001464752671100213655ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/geometry/Boxes.cpp000066400000000000000000000020041464752671100231450ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Boxes.h" #include "common/Data.h" #ifndef OSPRAY_TARGET_SYCL // ispc-generated files #include "geometry/Boxes_ispc.h" #else namespace ispc { void Boxes_bounds(const RTCBoundsFunctionArguments *uniform args); } #endif namespace ospray { Boxes::Boxes(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_BOX) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.postIntersect = reinterpret_cast( ispc::Boxes_postIntersect_addr()); #endif } std::string Boxes::toString() const { return "ospray::Boxes"; } void Boxes::commit() { boxData = getParamDataT("box", true); createEmbreeUserGeometry((RTCBoundsFunction)&ispc::Boxes_bounds); getSh()->boxes = *ispc(boxData); getSh()->super.numPrimitives = numPrimitives(); postCreationInfo(); } size_t Boxes::numPrimitives() const { return boxData ? boxData->size() : 0; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Boxes.h000066400000000000000000000010371464752671100226170ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" // ispc shared #include "BoxesShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Boxes : public AddStructShared { Boxes(api::ISPCDevice &device); virtual ~Boxes() override = default; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; protected: Ref> boxData; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Boxes.ih000066400000000000000000000007351464752671100227740ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void Boxes_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); SYCL_EXTERNAL unmasked void Boxes_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/Boxes.ispc000066400000000000000000000037541464752671100233360ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "common/Data.ih" #include "common/DifferentialGeometry.ih" #include "common/FilterIntersect.ih" #include "common/Intersect.ih" #include "common/Ray.ih" #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "BoxesShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE export void Boxes_bounds(const RTCBoundsFunctionArguments *uniform args) { Boxes *uniform self = (Boxes * uniform) args->geometryUserPtr; uniform int primID = args->primID; box3fa *uniform out = (box3fa * uniform) args->bounds_o; *out = make_box3fa(get_box3f(self->boxes, primID)); } SYCL_EXTERNAL unmasked void Boxes_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest) { // make sure to set the mask if (!args->valid[programIndex]) { return; } args->valid[programIndex] = 0; Boxes *uniform self = (Boxes * uniform) args->geometryUserPtr; varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; uniform int primID = args->primID; uniform box3f box = get_box3f(self->boxes, primID); const Intersections isect = intersectBox(ray->org, ray->dir, box); // call intersection filtering callback and setup hit if accepted if (filterIntersectionBoth(args, isect, isOcclusionTest)) { args->valid[programIndex] = -1; } } export void Boxes_intersect( const struct RTCIntersectFunctionNArguments *uniform args) { Boxes_intersect_kernel(args, false); } export void Boxes_occluded( const struct RTCOccludedFunctionNArguments *uniform args) { Boxes_intersect_kernel((RTCIntersectFunctionNArguments * uniform) args, true); } SYCL_EXTERNAL void Boxes_postIntersect(const Geometry *uniform, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64) { dg.Ng = dg.Ns = ray.Ng; } export void *uniform Boxes_postIntersect_addr() { return (void *uniform)Boxes_postIntersect; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/BoxesShared.h000066400000000000000000000005661464752671100237540ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Boxes { Geometry super; Data1D boxes; #ifdef __cplusplus Boxes() { super.type = GEOMETRY_TYPE_BOXES; } #endif }; #ifdef __cplusplus } // namespace ispc #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/Curves.cpp000066400000000000000000000156701464752671100233510ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Curves.h" #include "common/DGEnum.h" #ifndef OSPRAY_TARGET_SYCL // ispc-generated files #include "geometry/Curves_ispc.h" #endif // std #include namespace ospray { static std::map, std::pair> curveMap = { {{OSP_ROUND, OSP_LINEAR}, {RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE, FFG_ROUND_LINEAR_CURVE}}, {{OSP_FLAT, OSP_LINEAR}, {RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE, FFG_FLAT_LINEAR_CURVE}}, {{OSP_RIBBON, OSP_LINEAR}, {(RTCGeometryType)-1, FFG_NONE}}, {{OSP_DISJOINT, OSP_LINEAR}, {RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE, FFG_CONE_LINEAR_CURVE}}, {{OSP_ROUND, OSP_BEZIER}, {RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE, FFG_ROUND_BEZIER_CURVE}}, {{OSP_FLAT, OSP_BEZIER}, {RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE, FFG_FLAT_BEZIER_CURVE}}, {{OSP_RIBBON, OSP_BEZIER}, {RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE, FFG_NORMAL_ORIENTED_BEZIER_CURVE}}, {{OSP_DISJOINT, OSP_BEZIER}, {(RTCGeometryType)-1, FFG_NONE}}, {{OSP_ROUND, OSP_BSPLINE}, {RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE, FFG_ROUND_BSPLINE_CURVE}}, {{OSP_FLAT, OSP_BSPLINE}, {RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE, FFG_FLAT_BSPLINE_CURVE}}, {{OSP_RIBBON, OSP_BSPLINE}, {RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE, FFG_NORMAL_ORIENTED_BSPLINE_CURVE}}, {{OSP_DISJOINT, OSP_BSPLINE}, {(RTCGeometryType)-1, FFG_NONE}}, {{OSP_ROUND, OSP_HERMITE}, {RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE, FFG_ROUND_HERMITE_CURVE}}, {{OSP_FLAT, OSP_HERMITE}, {RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE, FFG_FLAT_HERMITE_CURVE}}, {{OSP_RIBBON, OSP_HERMITE}, {RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE, FFG_NORMAL_ORIENTED_HERMITE_CURVE}}, {{OSP_DISJOINT, OSP_HERMITE}, {(RTCGeometryType)-1, FFG_NONE}}, {{OSP_ROUND, OSP_CATMULL_ROM}, {RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE, FFG_ROUND_CATMULL_ROM_CURVE}}, {{OSP_FLAT, OSP_CATMULL_ROM}, {RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE, FFG_FLAT_CATMULL_ROM_CURVE}}, {{OSP_RIBBON, OSP_CATMULL_ROM}, {RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE, FFG_NORMAL_ORIENTED_CATMULL_ROM_CURVE}}, {{OSP_DISJOINT, OSP_CATMULL_ROM}, {(RTCGeometryType)-1, FFG_NONE}}}; // Curves definitions /////////////////////////////////////////////////////// Curves::Curves(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_NONE) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.postIntersect = reinterpret_cast( ispc::Curves_postIntersect_addr()); #endif // TODO implement area sampling of OldCurves for geometry lights } std::string Curves::toString() const { return "ospray::Curves"; } void Curves::commit() { indexData = getParamDataT("index", true); normalData = nullptr; tangentData = nullptr; texcoordData = getParamDataT("vertex.texcoord"); Ref> vertexNoRadiusData = getParamDataT("vertex.position"); if (vertexNoRadiusData) { // round, linear curves with constant radius float radius = getParam("radius", 0.01f); curveType = (OSPCurveType)getParam("type", OSP_ROUND); curveBasis = (OSPCurveBasis)getParam("basis", OSP_LINEAR); if (curveMap[std::make_pair(curveType, curveBasis)].first != RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE) throw std::runtime_error( "constant-radius curves need to be of type OSP_ROUND and have " "basis OSP_LINEAR"); // To maintain OSPRay 2.x compatibility and keep support for // the global 'radius' parameter, a vec4f vertex buffer copy // has to be created. It specifies radius on per-vertex basis and // is required by Embree. TODO: Refactor for OSPRay 3.x DataT *dataT = (DataT *)new Data( getISPCDevice(), OSP_VEC4F, vertexNoRadiusData->numItems); for (size_t i = 0; i < dataT->size(); i++) { const vec3f &v = (*vertexNoRadiusData)[i]; (*dataT)[i] = vec4f(v.x, v.y, v.z, radius); } vertexData = dataT; dataT->refDec(); } else { // embree curves vertexData = getParamDataT("vertex.position_radius", true); curveType = (OSPCurveType)getParam("type", OSP_UNKNOWN_CURVE_TYPE); if (curveType == OSP_UNKNOWN_CURVE_TYPE) throw std::runtime_error("curves geometry has invalid 'type'"); curveBasis = (OSPCurveBasis)getParam("basis", OSP_UNKNOWN_CURVE_BASIS); if (curveBasis == OSP_UNKNOWN_CURVE_BASIS) throw std::runtime_error("curves geometry has invalid 'basis'"); if (curveType == OSP_RIBBON) normalData = getParamDataT("vertex.normal", true); if (curveBasis == OSP_HERMITE) tangentData = getParamDataT("vertex.tangent", true); } colorData = getParamDataT("vertex.color"); auto curveEnums = curveMap[std::make_pair(curveType, curveBasis)]; embreeCurveType = curveEnums.first; if (embreeCurveType == (RTCGeometryType)-1) throw std::runtime_error("unsupported combination of 'type' and 'basis'"); createEmbreeGeometry(); getSh()->geom = embreeGeometry; getSh()->flagMask = -1; getSh()->super.numPrimitives = numPrimitives(); getSh()->curveType = curveType; getSh()->curveBasis = curveBasis; getSh()->index = *ispc(indexData); if (!colorData) { getSh()->flagMask &= ispc::int64(~DG_COLOR); } else { getSh()->color = *ispc(colorData); } if (!texcoordData) { getSh()->flagMask &= ispc::int64(~DG_TEXCOORD); } else { getSh()->texcoord = *ispc(texcoordData); } postCreationInfo(vertexData->size()); featureFlagsGeometry = curveEnums.second; } size_t Curves::numPrimitives() const { return indexData->size(); } void Curves::createEmbreeGeometry() { Geometry::createEmbreeGeometry(embreeCurveType); Ref> vertex4f(&vertexData->as()); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX, vertex4f); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_INDEX, indexData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_NORMAL, normalData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_TANGENT, tangentData); if (colorData) { rtcSetGeometryVertexAttributeCount(embreeGeometry, 1); setEmbreeGeometryBuffer( embreeGeometry, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, colorData); } if (texcoordData) { rtcSetGeometryVertexAttributeCount(embreeGeometry, 2); setEmbreeGeometryBuffer( embreeGeometry, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, texcoordData, 1); } rtcCommitGeometry(embreeGeometry); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Curves.h000066400000000000000000000017141464752671100230100ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" #include "common/Data.h" // ispc shared #include "CurvesShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Curves : public AddStructShared { Curves(api::ISPCDevice &device); virtual ~Curves() override = default; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; protected: Ref> vertexData; Ref> indexData; Ref> normalData; Ref> tangentData; Ref> colorData; Ref> texcoordData; RTCGeometryType embreeCurveType{(RTCGeometryType)-1}; OSPCurveType curveType{OSP_UNKNOWN_CURVE_TYPE}; OSPCurveBasis curveBasis{OSP_UNKNOWN_CURVE_BASIS}; private: void createEmbreeGeometry(); }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Curves.ih000066400000000000000000000005641464752671100231630ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void Curves_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/Curves.ispc000066400000000000000000000053211464752671100235150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Geometry.ih" #include "common/Data.ih" #include "common/FeatureFlags.ih" // c++ shared #include "CurvesShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; #endif template inline T interpolate(const Curves *uniform self, const uniform Data1D &buffer, const varying Ray &ray, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); const uint32 index = get(self->index, ray.primID); const float t = ray.u; const T v0 = get(buffer, index + 0); const T v1 = get(buffer, index + 1); if (((self->curveBasis == OSP_LINEAR) && (ffg & FFG_LINEAR_CURVE)) || ((self->curveBasis == OSP_HERMITE) && (ffg & FFG_HERMITE_CURVE))) { return lerp(t, v0, v1); } if ((ffg & FFG_BEZIER_CURVE) || (ffg & FFG_BSPLINE_CURVE) || (ffg & FFG_CATMULL_ROM_CURVE)) { const T v2 = get(buffer, index + 2); const T v3 = get(buffer, index + 3); const float s = 1.0f - ray.u; const float s2 = s * s; const float t2 = t * t; const float s2t = s2 * t; const float t2s = t2 * s; const float s3 = s2 * s; const float t3 = t2 * t; float b0 = 0.0f, b1 = 0.0f, b2 = 0.0f, b3 = 0.0f; float c = 0.0f; if ((self->curveBasis == OSP_BEZIER) && (ffg & FFG_BEZIER_CURVE)) { b0 = s3; b1 = 3.0f * s2t; b2 = 3.0f * t2s; b3 = t3; c = 1.0f; } if ((self->curveBasis == OSP_BSPLINE) && (ffg & FFG_BSPLINE_CURVE)) { b0 = s3; b1 = (4.0f * s3 + t3) + (12.0f * s2t + 6.0f * t2s); b2 = (4.0f * t3 + s3) + (12.0f * t2s + 6.0f * s2t); b3 = t3; c = 1.0f / 6.0f; } if ((self->curveBasis == OSP_CATMULL_ROM) && (ffg & FFG_CATMULL_ROM_CURVE)) { b0 = -s2t; b1 = 2.0f + t2 * (3.0f * t - 5.0f); b2 = 2.0f + s2 * (3.0f * s - 5.0f); b3 = -t2s; c = 0.5f; } return c * (b0 * v0 + b1 * v1 + b2 * v2 + b3 * v3); } T result = {0}; return result; } SYCL_EXTERNAL void Curves_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh) { const Curves *uniform self = (const Curves *uniform)_self; dg.Ng = dg.Ns = ray.Ng; flags &= self->flagMask; if (flags & DG_COLOR) { dg.color = interpolate(self, self->color, ray, ffh); } if (flags & DG_TEXCOORD) { dg.st = interpolate(self, self->texcoord, ray, ffh); } } export void *uniform Curves_postIntersect_addr() { return (void *uniform)Curves_postIntersect; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/CurvesShared.h000066400000000000000000000012461464752671100241370ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #include "ospray/OSPEnums.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Curves { Geometry super; // inherited geometry fields RTCGeometry geom; int64 flagMask; OSPCurveType curveType; OSPCurveBasis curveBasis; Data1D index; Data1D color; Data1D texcoord; #ifdef __cplusplus Curves() : geom(nullptr), flagMask(-1), curveType(OSP_UNKNOWN_CURVE_TYPE), curveBasis(OSP_UNKNOWN_CURVE_BASIS) { super.type = GEOMETRY_TYPE_CURVES; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/GeometricModel.cpp000066400000000000000000000071231464752671100247730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "GeometricModel.h" #include "render/Material.h" namespace ospray { GeometricModel::GeometricModel(api::ISPCDevice &device, Geometry *_geometry) : AddStructShared(device.getDRTDevice(), device), geomAPI(_geometry) { managedObjectType = OSP_GEOMETRIC_MODEL; } std::string GeometricModel::toString() const { return "ospray::GeometricModel"; } void GeometricModel::commit() { geom = getParamObject("geometry", geomAPI.ptr); if (!geom) throw std::runtime_error(toString() + " received NULL 'geometry'"); materialData = getParamDataT("material", false, true); materialArray = nullptr; materialIDArray = nullptr; getSh()->material = nullptr; getSh()->materialID = nullptr; getSh()->numMaterials = 0; featureFlagsOther = FFO_NONE; if (materialData) { for (auto &&mat : materialData->as()) featureFlagsOther |= mat->getFeatureFlags().other; materialArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), createArrayOfSh(materialData->as())); getSh()->material = materialArray->sharedPtr(); getSh()->numMaterials = materialArray->size(); } else { materialData = getParamDataT("material", false, true); if (materialData) { materialIDArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), materialData->as().data(), materialData->size()); getSh()->materialID = materialIDArray->sharedPtr(); getSh()->numMaterials = materialIDArray->size(); } } colorData = getParamDataT("color", false, true); indexData = getParamDataT("index"); size_t maxItems = geom->numPrimitives(); if (indexData && indexData->size() < maxItems) { postStatusMsg(OSP_LOG_INFO) << toString() << " not enough 'index' elements for 'geometry', clamping"; } if (indexData) maxItems = 256; // conservative, should actually go over the index if (materialData && materialData->size() > 1 && materialData->size() < maxItems) { postStatusMsg(OSP_LOG_INFO) << toString() << " potentially not enough 'material' elements for " "'geometry', clamping"; } if (colorData && colorData->size() > 1 && colorData->size() < maxItems) { postStatusMsg(OSP_LOG_INFO) << toString() << " potentially not enough 'color' elements for 'geometry', clamping"; } getSh()->geom = geom->getSh(); getSh()->color = *ispc(colorData); getSh()->index = *ispc(indexData); getSh()->invertedNormals = getParam("invertNormals", false); getSh()->userID = getParam("id", RTC_INVALID_GEOMETRY_ID); } bool GeometricModel::hasEmissiveMaterials( Ref> rendererMaterials) const { // No materials used - nothing to check if (!materialData) return false; // Check geometry model materials bool hasEmissive = false; if (materialArray) { for (auto &&mat : materialData->as()) if (mat->isEmissive()) { hasEmissive = true; break; } } // Check renderer materials referenced from geometry model else if (materialIDArray) { for (auto matIdx : materialData->as()) if ((matIdx < rendererMaterials->size()) && ((*rendererMaterials)[matIdx]->isEmissive())) { hasEmissive = true; break; } } // Done return hasEmissive; } OSPTYPEFOR_DEFINITION(GeometricModel *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/GeometricModel.h000066400000000000000000000032301464752671100244330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" #include "common/Data.h" // ispc shared #include "GeometricModelShared.h" namespace ispc { struct Material; } namespace ospray { struct Material; struct OSPRAY_SDK_INTERFACE GeometricModel : public AddStructShared { GeometricModel(api::ISPCDevice &device, Geometry *geometry); ~GeometricModel() override = default; std::string toString() const override; void commit() override; Geometry &geometry(); RTCGeometry embreeGeometryHandle() const; bool invertedNormals() const; bool hasEmissiveMaterials( Ref> rendererMaterials) const; FeatureFlags getFeatureFlags() const; private: Ref geom; const Ref geomAPI; Ref materialData; Ref> colorData; Ref> indexData; BufferSharedUq materialArray; BufferSharedUq materialIDArray; FeatureFlagsOther featureFlagsOther{FFO_NONE}; }; OSPTYPEFOR_SPECIALIZATION(GeometricModel *, OSP_GEOMETRIC_MODEL); // Inlined members ////////////////////////////////////////////////////////// inline Geometry &GeometricModel::geometry() { return *geom; } inline RTCGeometry GeometricModel::embreeGeometryHandle() const { return geom->getEmbreeGeometry(); } inline bool GeometricModel::invertedNormals() const { return getSh()->invertedNormals; } inline FeatureFlags GeometricModel::getFeatureFlags() const { FeatureFlags ff = geom->getFeatureFlags(); ff.other |= featureFlagsOther; return ff; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/GeometricModel.ih000066400000000000000000000037561464752671100246210ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.ih" #include "GeometryDispatch.ih" #include "common/Data.ih" #include "common/FeatureFlagsEnum.h" #include "render/Renderer.ih" #include "rkcommon/math/AffineSpace.ih" // c++ shared #include "GeometricModelShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; #endif inline Material *GeometricModel_getMaterial(const GeometricModel *uniform self, const Renderer *uniform renderer, const int32 primID) { if ((!self->material) && (!self->materialID)) return NULL; uint32 idx = primID; if (valid(self->index)) { idx = get_uint8(self->index, min(idx, self->index.numItems - 1)); } uniform uint32 lastMaterial = self->numMaterials - 1; Material **uniform mats = (Material * *uniform) self->material; if (!mats) { idx = self->materialID[min(idx, lastMaterial)]; mats = renderer->material; lastMaterial = renderer->numMaterials - 1; } if (mats) return mats[min(idx, lastMaterial)]; return NULL; } inline void GeometricModel_postIntersect(const GeometricModel *uniform self, const Renderer *uniform renderer, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh) { Geometry *uniform geom = self->geom; Geometry_dispatch_postIntersect(geom, dg, ray, flags, ffh); dg.areaPDF = self->areaPDF; dg.objID = (self->userID == RTC_INVALID_GEOMETRY_ID) ? ray.geomID : self->userID; if (flags & DG_COLOR && valid(self->color)) { uint32 idx = ray.primID; if (valid(self->index)) { idx = get_uint8(self->index, min(idx, self->index.numItems - 1)); } dg.color = get_vec4f(self->color, min(idx, self->color.numItems - 1)); } if (renderer) { dg.material = GeometricModel_getMaterial(self, renderer, ray.primID); } if (flags & DG_NS && self->invertedNormals) dg.Ns = neg(dg.Ns); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/GeometricModel.ispc000066400000000000000000000033711464752671100251500ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "GeometricModel.ih" #include "math/Distribution1D.ih" #include "render/Material.ih" #include "render/MaterialDispatch.ih" // c++ shared #include "common/InstanceShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE export uniform int GeometricModel_gatherEmissivePrimIDs(void *uniform _model, void *uniform _renderer, void *uniform _instance, int *uniform primIDs, float *uniform distribution, uniform float &pdf) { GeometricModel *uniform model = (GeometricModel * uniform) _model; const Renderer *uniform renderer = (Renderer * uniform) _renderer; const Geometry *uniform geo = model->geom; const Instance *uniform instance = (Instance * uniform) _instance; // create the list of emissive primitive IDs uniform int32 numEmissivePrims = 0; #ifdef OSPRAY_TARGET_SYCL // SYCL execution in a thread is scalar for (int primID = 0; primID < geo->numPrimitives; ++primID) { #else foreach (primID = 0 ... geo->numPrimitives) { #endif Material *mat = (Material *)GeometricModel_getMaterial(model, renderer, primID); if (mat->isEmissive) { int offset = exclusive_scan_add(1); primIDs[numEmissivePrims + offset] = primID; numEmissivePrims += reduce_add(1); } } // create the sampling distribution // TODO: use emissive power instead of just area // TODO: motion blur can introduce scale, which means areas cannot // accurately be precomputed // Note: Can stay as a ptr call if not moved to GPU geo->getAreas(geo, primIDs, numEmissivePrims, instance->xfm, distribution); pdf = model->areaPDF = 1.f / Distribution1D_create(numEmissivePrims, distribution); return numEmissivePrims; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/GeometricModelShared.h000066400000000000000000000013371464752671100255700ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Material; struct GeometricModel { Geometry *geom; Data1D color; Data1D index; // per-primitive property mapping Material **material; uint32 *materialID; uint32 numMaterials; bool invertedNormals; float areaPDF; unsigned int userID; #ifdef __cplusplus GeometricModel() : geom(nullptr), material(nullptr), materialID(nullptr), numMaterials(0), invertedNormals(false), areaPDF(0.f), userID(RTC_INVALID_GEOMETRY_ID) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/Geometry.cpp000066400000000000000000000032121464752671100236620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Geometry.h" #include "common/Data.h" #ifndef OSPRAY_TARGET_SYCL #include "geometry/GeometryDispatch_ispc.h" #endif namespace ospray { // Geometry definitions /////////////////////////////////////////////////////// Geometry::Geometry(api::ISPCDevice &device, const FeatureFlagsGeometry ffg) : AddStructShared(device.getDRTDevice(), device), featureFlagsGeometry(ffg) { managedObjectType = OSP_GEOMETRY; } Geometry::~Geometry() { if (embreeGeometry) rtcReleaseGeometry(embreeGeometry); } std::string Geometry::toString() const { return "ospray::Geometry"; } void Geometry::postCreationInfo(size_t numVerts) const { std::stringstream ss; ss << toString() << " created: #primitives=" << numPrimitives(); if (numVerts > 0) ss << ", #vertices=" << numVerts; postStatusMsg(OSP_LOG_INFO) << ss.str(); } void Geometry::createEmbreeGeometry(RTCGeometryType type) { if (embreeGeometry) rtcReleaseGeometry(embreeGeometry); if (!getISPCDevice().getEmbreeDevice()) { throw std::runtime_error("invalid Embree device"); } embreeGeometry = rtcNewGeometry(getISPCDevice().getEmbreeDevice(), type); } void Geometry::createEmbreeUserGeometry(RTCBoundsFunction boundsFn) { createEmbreeGeometry(RTC_GEOMETRY_TYPE_USER); // Setup Embree user-defined geometry rtcSetGeometryUserData(embreeGeometry, getSh()); rtcSetGeometryUserPrimitiveCount(embreeGeometry, numPrimitives()); rtcSetGeometryBoundsFunction(embreeGeometry, boundsFn, getSh()); rtcCommitGeometry(embreeGeometry); } OSPTYPEFOR_DEFINITION(Geometry *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Geometry.h000066400000000000000000000116331464752671100233350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/Data.h" #include "common/FeatureFlagsEnum.h" #include "common/ObjectFactory.h" // embree #include "common/Embree.h" // ispc shared #include "GeometryShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Geometry : public AddStructShared, public ObjectFactory { Geometry(api::ISPCDevice &device, const FeatureFlagsGeometry ffg); virtual ~Geometry() override; virtual std::string toString() const override; virtual size_t numPrimitives() const = 0; void postCreationInfo(size_t numVerts = 0) const; RTCGeometry getEmbreeGeometry() const; bool supportAreaLighting() const; virtual FeatureFlags getFeatureFlags() const; protected: RTCGeometry embreeGeometry{nullptr}; FeatureFlagsGeometry featureFlagsGeometry; void createEmbreeGeometry(RTCGeometryType type); // NOTE: We now pass intersection functions through Embree RTCIntersectionArgs // context parameter so that they can be inlined in SYCL void createEmbreeUserGeometry(RTCBoundsFunction boundsFn); }; OSPTYPEFOR_SPECIALIZATION(Geometry *, OSP_GEOMETRY); inline RTCGeometry Geometry::getEmbreeGeometry() const { return embreeGeometry; } inline bool Geometry::supportAreaLighting() const { return (getSh()->sampleArea != nullptr) && (getSh()->getAreas != nullptr); } inline FeatureFlags Geometry::getFeatureFlags() const { FeatureFlags ff; ff.geometry = featureFlagsGeometry; return ff; } // convenience wrappers to set Embree buffer ////////////////////////////////// template struct RTCFormatFor { static constexpr RTCFormat value = RTC_FORMAT_UNDEFINED; }; #define RTCFORMATFOR_SPECIALIZATION(type, rtc_format) \ template <> \ struct RTCFormatFor \ { \ static constexpr RTCFormat value = rtc_format; \ }; RTCFORMATFOR_SPECIALIZATION(char, RTC_FORMAT_CHAR); RTCFORMATFOR_SPECIALIZATION(unsigned char, RTC_FORMAT_UCHAR); RTCFORMATFOR_SPECIALIZATION(short, RTC_FORMAT_SHORT); RTCFORMATFOR_SPECIALIZATION(unsigned short, RTC_FORMAT_USHORT); RTCFORMATFOR_SPECIALIZATION(int32_t, RTC_FORMAT_INT); RTCFORMATFOR_SPECIALIZATION(vec2i, RTC_FORMAT_INT2); RTCFORMATFOR_SPECIALIZATION(vec3i, RTC_FORMAT_INT3); RTCFORMATFOR_SPECIALIZATION(vec4i, RTC_FORMAT_INT4); RTCFORMATFOR_SPECIALIZATION(uint32_t, RTC_FORMAT_UINT); RTCFORMATFOR_SPECIALIZATION(vec2ui, RTC_FORMAT_UINT2); RTCFORMATFOR_SPECIALIZATION(vec3ui, RTC_FORMAT_UINT3); RTCFORMATFOR_SPECIALIZATION(vec4ui, RTC_FORMAT_UINT4); RTCFORMATFOR_SPECIALIZATION(int64_t, RTC_FORMAT_LLONG); RTCFORMATFOR_SPECIALIZATION(vec2l, RTC_FORMAT_LLONG2); RTCFORMATFOR_SPECIALIZATION(vec3l, RTC_FORMAT_LLONG3); RTCFORMATFOR_SPECIALIZATION(vec4l, RTC_FORMAT_LLONG4); RTCFORMATFOR_SPECIALIZATION(uint64_t, RTC_FORMAT_ULLONG); RTCFORMATFOR_SPECIALIZATION(vec2ul, RTC_FORMAT_ULLONG2); RTCFORMATFOR_SPECIALIZATION(vec3ul, RTC_FORMAT_ULLONG3); RTCFORMATFOR_SPECIALIZATION(vec4ul, RTC_FORMAT_ULLONG4); RTCFORMATFOR_SPECIALIZATION(float, RTC_FORMAT_FLOAT); RTCFORMATFOR_SPECIALIZATION(vec2f, RTC_FORMAT_FLOAT2); RTCFORMATFOR_SPECIALIZATION(vec3f, RTC_FORMAT_FLOAT3); RTCFORMATFOR_SPECIALIZATION(vec4f, RTC_FORMAT_FLOAT4); RTCFORMATFOR_SPECIALIZATION(linear2f, RTC_FORMAT_FLOAT2X2_COLUMN_MAJOR); RTCFORMATFOR_SPECIALIZATION(linear3f, RTC_FORMAT_FLOAT3X3_COLUMN_MAJOR); RTCFORMATFOR_SPECIALIZATION(affine2f, RTC_FORMAT_FLOAT2X3_COLUMN_MAJOR); RTCFORMATFOR_SPECIALIZATION(affine3f, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR); #undef RTCFORMATFOR_SPECIALIZATION // ... via Ref, NoOp when data is invalid template void setEmbreeGeometryBuffer(RTCGeometry geom, enum RTCBufferType type, Ref> &dataRef, unsigned int slot = 0) { if (!dataRef) return; rtcSetSharedGeometryBuffer(geom, type, slot, RTCFormatFor::value, dataRef->data(), 0, dataRef->stride(), dataRef->size()); } // ... via *ospData, NoOp when data is invalid template void setEmbreeGeometryBuffer(RTCGeometry geom, enum RTCBufferType type, const DataT *dataPtr, unsigned int slot = 0) { if (!dataPtr) return; rtcSetSharedGeometryBuffer(geom, type, slot, RTCFormatFor::value, dataPtr->data(), 0, dataPtr->stride(), dataPtr->size()); } // ... via an std::vector template void setEmbreeGeometryBuffer(RTCGeometry geom, enum RTCBufferType type, std::vector &data, unsigned int slot = 0) { rtcSetSharedGeometryBuffer(geom, type, slot, RTCFormatFor::value, data.data(), 0, sizeof(T), data.size()); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Geometry.ih000066400000000000000000000003661464752671100235070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../common/DifferentialGeometry.ih" #include "../common/Ray.ih" #include "rkcommon/math/AffineSpace.ih" // c++ shared #include "GeometryShared.h" RenderKit-ospray-85af292/modules/cpu/geometry/GeometryDispatch.ih000066400000000000000000000035011464752671100251610ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Geometries are supposed to fill certain members of DifferentialGeometry: // calculate Ng, Ns, st, color, and materialID if the respective bit DG_NG, // DG_NS, DG_TEXCOORD, DG_COLOR, and DG_MATERIALID, in flags is set. // Important with instancing: P and ray are in world-coordinates, whereas Ng // and Ns are in object-coordinates and transformed to world-space by // Instance_postIntersect. // World::postIntersect already set the hit point P, color, geometry, and // material before, and handles normalization/faceforwarding // (DG_NORMALIZE/DG_FACEFORWARD) after Geometry_postIntersectFct is called. // Thus the material pointer only needs to be set if different to // geometry->material, or the color when different to vec4f(1.0f). SYCL_EXTERNAL void Geometry_dispatch_postIntersect(const Geometry *uniform self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh); // sample the given primitive uniformly wrt. area SYCL_EXTERNAL SampleAreaRes Geometry_dispatch_sampleArea( const Geometry *const uniform, const int32 primID, const uniform affine3f &xfm, // instance transformation (obj2world) const uniform affine3f &rcp_xfm, // inverse transformation (world2obj) const vec2f &s, // random numbers to generate the sample const float time, // for deformation motion blur const uniform FeatureFlagsHandler &ffh); RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Geometry_dispatch_intersect( RTCIntersectFunctionNArguments *uniform args); RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Geometry_dispatch_occluded( RTCOccludedFunctionNArguments *uniform args); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/GeometryDispatch.ispc000066400000000000000000000120251464752671100255200ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DifferentialGeometry.ih" #include "common/FeatureFlagsEnum.h" #include "common/Ray.ih" #include "common/RayQueryContext.ih" #include "geometry/Boxes.ih" #include "geometry/Curves.ih" #include "geometry/GeometryDispatch.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "geometry/Isosurfaces.ih" #endif #include "geometry/Mesh.ih" #include "geometry/Planes.ih" #include "geometry/Spheres.ih" #include "geometry/Subdivision.ih" // c++ shared #include "geometry/GeometryShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void Geometry_dispatch_postIntersect(const Geometry *uniform self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); if ((self->type == GEOMETRY_TYPE_QUAD_MESH) && (ffg & FFG_QUAD)) { QuadMesh_postIntersect(self, dg, ray, flags); } else if ((self->type == GEOMETRY_TYPE_TRIANGLE_MESH) && (ffg & FFG_TRIANGLE)) { TriangleMesh_postIntersect(self, dg, ray, flags); } else if ((self->type == GEOMETRY_TYPE_BOXES) && (ffg & FFG_BOX)) { Boxes_postIntersect(self, dg, ray, flags); } else if ((self->type == GEOMETRY_TYPE_SPHERES) && (ffg & FFG_SPHERES)) { Spheres_postIntersect(self, dg, ray, flags); } else if ((self->type == GEOMETRY_TYPE_PLANES) && (ffg & FFG_PLANE)) { Planes_postIntersect(self, dg, ray, flags); } else if ((self->type == GEOMETRY_TYPE_CURVES) && (ffg & FFG_CURVES)) { Curves_postIntersect(self, dg, ray, flags, ffh); #ifdef OSPRAY_ENABLE_VOLUMES } else if ((self->type == GEOMETRY_TYPE_ISOSURFACES) && (ffg & FFG_ISOSURFACE)) { Isosurfaces_postIntersect(self, dg, ray, flags, ffh); #endif #ifndef OSPRAY_TARGET_SYCL } else if ((self->type == GEOMETRY_TYPE_SUBDIVISION) && (ffg & FFG_SUBDIVISION)) { Subdivision_postIntersect(self, dg, ray, flags); } else { self->postIntersect(self, dg, ray, flags); } #else } else { } #endif } SYCL_EXTERNAL SampleAreaRes Geometry_dispatch_sampleArea( const Geometry *const uniform self, const int32 primID, const uniform affine3f &xfm, const uniform affine3f &rcp_xfm, const vec2f &s, const float time, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); if (((self->type == GEOMETRY_TYPE_QUAD_MESH) && (ffg & FFG_QUAD)) || ((self->type == GEOMETRY_TYPE_TRIANGLE_MESH) && (ffg & FFG_TRIANGLE))) { return Mesh_sampleArea(self, primID, xfm, rcp_xfm, s, time); } else if ((self->type == GEOMETRY_TYPE_SPHERES) && (ffg & FFG_SPHERE)) { return Spheres_sampleArea(self, primID, xfm, rcp_xfm, s, time); } else { #ifdef OSPRAY_TARGET_SYCL SampleAreaRes res; res.pos = make_vec3f(0.f); res.normal = make_vec3f(0.f); res.st = make_vec2f(0.f); return res; #else return self->sampleArea(self, primID, xfm, rcp_xfm, s, time); #endif } } RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Geometry_dispatch_intersect( RTCIntersectFunctionNArguments *uniform args) { RayQueryContextDefault *uniform ctx = (RayQueryContextDefault * uniform) args->context; const uniform FeatureFlagsHandler &ffh = *ctx->ffh; const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); Geometry *uniform geom = (Geometry * uniform) args->geometryUserPtr; if ((geom->type == GEOMETRY_TYPE_BOXES) && (ffg & FFG_BOX)) { Boxes_intersect_kernel(args, false); } else if ((geom->type == GEOMETRY_TYPE_PLANES) && (ffg & FFG_PLANE)) { Planes_intersect_kernel(args, false); #ifdef OSPRAY_ENABLE_VOLUMES } else if ((geom->type == GEOMETRY_TYPE_ISOSURFACES) && (ffg & FFG_ISOSURFACE)) { Isosurfaces_intersect_kernel(args, false, ffh); #endif } else { #ifndef OSPRAY_TARGET_SYCL geom->intersect((RTCIntersectFunctionNArguments * uniform) args, false); #endif } } RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Geometry_dispatch_occluded( RTCOccludedFunctionNArguments *uniform args) { RayQueryContextDefault *uniform ctx = (RayQueryContextDefault * uniform) args->context; const uniform FeatureFlagsHandler &ffh = *ctx->ffh; const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); Geometry *uniform geom = (Geometry * uniform) args->geometryUserPtr; if ((geom->type == GEOMETRY_TYPE_BOXES) && (ffg & FFG_BOX)) { Boxes_intersect_kernel( (RTCIntersectFunctionNArguments * uniform) args, true); } else if ((geom->type == GEOMETRY_TYPE_PLANES) && (ffg & FFG_PLANE)) { Planes_intersect_kernel( (RTCIntersectFunctionNArguments * uniform) args, true); #ifdef OSPRAY_ENABLE_VOLUMES } else if ((geom->type == GEOMETRY_TYPE_ISOSURFACES) && (ffg & FFG_ISOSURFACE)) { Isosurfaces_intersect_kernel( (RTCIntersectFunctionNArguments * uniform) args, true, ffh); #endif } else { #ifndef OSPRAY_TARGET_SYCL geom->intersect((RTCIntersectFunctionNArguments * uniform) args, true); #endif } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/GeometryShared.h000066400000000000000000000070361464752671100244660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *Geometry_postIntersectFct; typedef void *Geometry_GetAreasFct; typedef void *Geometry_SampleAreaFct; typedef void *Geometry_IntersectFct; #else struct Geometry; struct DifferentialGeometry; struct Ray; // Geometries are supposed to fill certain members of DifferentialGeometry: // calculate Ng, Ns, st, color, and materialID if the respective bit DG_NG, // DG_NS, DG_TEXCOORD, DG_COLOR, and DG_MATERIALID, in flags is set. // Important with instancing: P and ray are in world-coordinates, whereas Ng // and Ns are in object-coordinates and transformed to world-space by // Instance_postIntersect. // World::postIntersect already set the hit point P, color, geometry, and // material before, and handles normalization/faceforwarding // (DG_NORMALIZE/DG_FACEFORWARD) after Geometry_postIntersectFct is called. // Thus the material pointer only needs to be set if different to // geometry->material, or the color when different to vec4f(1.0f). typedef void (*Geometry_postIntersectFct)(const Geometry *uniform self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); typedef void (*Geometry_GetAreasFct)(const Geometry *const uniform, const int32 *const uniform primIDs, // primitive IDs const uniform int32 numPrims, // number of primitives const uniform affine3f &xfm, // instance transformation (obj2world) float *const uniform areas // array to return area per primitive in world-space ); struct SampleAreaRes // basically a reduced DifferentialGeometry { vec3f pos; // sampled point, in world-space vec3f normal; // geometry normal Ng at the sampled point vec2f st; // texture coordinates float epsilon; // adaptive epsilon, isotropic in world-space }; // sample the given primitive uniformly wrt. area typedef SampleAreaRes (*Geometry_SampleAreaFct)(const Geometry *const uniform, const int32 primID, const uniform affine3f &xfm, // instance transformation (obj2world) const uniform affine3f &rcp_xfm, // inverse transformation (world2obj) const vec2f &s, // random numbers to generate the sample const float time // for deformation motion blur ); typedef void unmasked (*Geometry_IntersectFct)( const struct RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest); #endif enum GeometryType { GEOMETRY_TYPE_TRIANGLE_MESH, GEOMETRY_TYPE_QUAD_MESH, GEOMETRY_TYPE_BOXES, GEOMETRY_TYPE_SPHERES, GEOMETRY_TYPE_PLANES, GEOMETRY_TYPE_CURVES, #ifdef OSPRAY_ENABLE_VOLUMES GEOMETRY_TYPE_ISOSURFACES, #endif GEOMETRY_TYPE_SUBDIVISION, GEOMETRY_TYPE_UNKNOWN, }; struct Geometry { GeometryType type; // 'virtual' post-intersect function that fills in a // DifferentialGeometry struct, see above prototype for details Geometry_postIntersectFct postIntersect; Geometry_GetAreasFct getAreas; Geometry_SampleAreaFct sampleArea; // TODO: Maybe behind a define? Custom user geometry w/ fcn ptr callbacks will // only be on the CPU for now for perf limitations #ifndef OSPRAY_TARGET_SYCL Geometry_IntersectFct intersect; #endif // number of primitives this geometry has int32 numPrimitives; #ifdef __cplusplus Geometry() : type(GEOMETRY_TYPE_UNKNOWN), postIntersect(nullptr), getAreas(nullptr), sampleArea(nullptr), numPrimitives(0) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/Isosurfaces.cpp000066400000000000000000000042661464752671100243670ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES // ospray #include "Isosurfaces.h" #include "common/Data.h" // openvkl #include "openvkl/openvkl.h" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.h" #ifndef OSPRAY_TARGET_SYCL // ispc-generated files #include "geometry/Isosurfaces_ispc.h" #else namespace ispc { void Isosurfaces_bounds(const RTCBoundsFunctionArguments *uniform args); } #endif namespace ospray { Isosurfaces::Isosurfaces(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_ISOSURFACE) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.postIntersect = ispc::Isosurfaces_postIntersect_addr(); #endif } Isosurfaces::~Isosurfaces() { if (vklHitContext) { vklRelease(vklHitContext); } } std::string Isosurfaces::toString() const { return "ospray::Isosurfaces"; } void Isosurfaces::commit() { isovaluesData = getParamDataT("isovalue", true, true); volume = getParamObject("volume"); if (!volume) throw std::runtime_error(toString() + "must have 'volume'"); if (!isovaluesData->compact()) { // get rid of stride auto data = new Data( getISPCDevice(), OSP_FLOAT, vec3ui(isovaluesData->size(), 1, 1)); data->copy(*isovaluesData, vec3ui(0)); isovaluesData = &(data->as()); data->refDec(); } if (vklHitContext) { vklRelease(vklHitContext); } vklHitContext = vklNewHitIteratorContext(volume->vklSampler); if (isovaluesData->size() > 0) { VKLData valuesData = vklNewData(getISPCDevice().getVklDevice(), isovaluesData->size(), VKL_FLOAT, isovaluesData->data()); vklSetData(vklHitContext, "values", valuesData); vklRelease(valuesData); } vklCommit(vklHitContext); createEmbreeUserGeometry((RTCBoundsFunction)&ispc::Isosurfaces_bounds); getSh()->isovalues = isovaluesData->data(); getSh()->volume = volume->getSh(); getSh()->super.numPrimitives = numPrimitives(); getSh()->vklHitContext = vklHitContext; postCreationInfo(); } size_t Isosurfaces::numPrimitives() const { return isovaluesData->size(); } } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/geometry/Isosurfaces.h000066400000000000000000000017061464752671100240300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "Geometry.h" #include "volume/Volume.h" // ispc shared #include "IsosurfacesShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Isosurfaces : public AddStructShared { Isosurfaces(api::ISPCDevice &device); virtual ~Isosurfaces() override; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; FeatureFlags getFeatureFlags() const override; protected: Ref> isovaluesData; Ref volume; VKLHitIteratorContext vklHitContext = VKLHitIteratorContext(); }; inline FeatureFlags Isosurfaces::getFeatureFlags() const { FeatureFlags ff = Geometry::getFeatureFlags(); ff |= volume->getFeatureFlags(); return ff; } } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/geometry/Isosurfaces.ih000066400000000000000000000013661464752671100242030ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "common/FeatureFlags.ih" #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL void Isosurfaces_bounds(const RTCBoundsFunctionArguments *uniform args); #endif SYCL_EXTERNAL void Isosurfaces_postIntersect(const Geometry *uniform geometry, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL void unmasked Isosurfaces_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/geometry/Isosurfaces.ispc000066400000000000000000000073111464752671100245350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #ifdef OSPRAY_ENABLE_VOLUMES // ospray #include "common/FilterIntersect.ih" #include "common/Ray.ih" #include "common/World.ih" #include "geometry/Geometry.ih" #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" #include "volume/Volume.ih" // c++ shared #include "IsosurfacesShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE int Isosurfaces_primID(const Isosurfaces *uniform self, const float isovalue) { for (uniform int i = 0; i < self->super.numPrimitives; ++i) { if (isovalue == self->isovalues[i]) { return i; } } return -1; } export void Isosurfaces_bounds(const RTCBoundsFunctionArguments *uniform args) { uniform Isosurfaces *uniform self = (uniform Isosurfaces * uniform) args->geometryUserPtr; box3fa *uniform out = (box3fa * uniform) args->bounds_o; *out = make_box3fa(self->volume->boundingBox); } SYCL_EXTERNAL void Isosurfaces_postIntersect(const Geometry *uniform geometry, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags, const uniform FeatureFlagsHandler &ffh) { Isosurfaces *uniform self = (Isosurfaces * uniform) geometry; if (flags & (DG_NS | DG_NG)) dg.Ng = dg.Ns = Volume_getGradient(self->volume, ray.Ng /* actually local hit */, ffh); // convert ray-space epsilon (in ray.u) to object-/world-space using max(dir) // instead of costly length; the error is at most sqrt(3)~1.7, quite // acceptable for eps dg.epsilon = reduce_max(abs(ray.dir)) * ray.u; } SYCL_EXTERNAL void unmasked Isosurfaces_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest, const uniform FeatureFlagsHandler &ffh) { // make sure to set the mask if (!args->valid[programIndex]) { return; } const uniform FeatureFlags ff = getFeatureFlags(ffh); args->valid[programIndex] = 0; Isosurfaces *uniform self = (Isosurfaces * uniform) args->geometryUserPtr; // this assumes that the args->rayhit is actually a pointer to a varying ray! varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; VKLHitIterator iterator; vkl_range1f tRange; tRange.lower = ray->t0; tRange.upper = ray->t; float time = 0.f; // do not use alloca: it prevents inlining and thus optimization // wrt. "template arg" isOcclusionTest, alloca also not supported on GPU uniform uint8 hitIteratorBuffer[VKL_MAX_HIT_ITERATOR_SIZE]; iterator = vklInitHitIteratorV(&self->vklHitContext, (varying vkl_vec3f *)&ray->org, (varying vkl_vec3f *)&ray->dir, &tRange, #ifndef OSPRAY_TARGET_SYCL & #endif time, hitIteratorBuffer #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ); VKLHit hit; bool gotHit = vklIterateHitV(iterator, &hit #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ); if (!gotHit) return; Hit hitFilter; hitFilter.hit = true; hitFilter.t = hit.t; // Transport hit point in *volume local coords* to postIntersect hitFilter.N = ray->org + ray->dir * hit.t; // Transport epsilon to postIntersect hitFilter.u = hit.epsilon; bool accept = filterIntersectionSingle(args, hitFilter, isOcclusionTest, false); if (!accept) return; args->valid[programIndex] = -1; if (isOcclusionTest) { ray->t = neg_inf; } else { ray->instID = args->context->instID[0]; ray->geomID = args->geomID; ray->primID = Isosurfaces_primID(self, hit.sample); ray->t = hitFilter.t; ray->u = hitFilter.u; ray->Ng = hitFilter.N; } } export void *uniform Isosurfaces_postIntersect_addr() { return (void *uniform)Isosurfaces_postIntersect; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/geometry/IsosurfacesShared.h000066400000000000000000000011371464752671100251550ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Isosurfaces { Geometry super; // inherited geometry fields float *isovalues; Volume *volume; VKLHitIteratorContext vklHitContext; #ifdef __cplusplus Isosurfaces() : isovalues(nullptr), volume(nullptr), vklHitContext(VKLHitIteratorContext()) { super.type = ispc::GEOMETRY_TYPE_ISOSURFACES; } }; } // namespace ispc #else }; #endif // __cplusplus #endif RenderKit-ospray-85af292/modules/cpu/geometry/Mesh.cpp000066400000000000000000000163061464752671100227730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Mesh.h" #include "common/DGEnum.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "geometry/Mesh_ispc.h" #else namespace ispc { void *QuadMesh_postIntersect_addr(); void *TriangleMesh_postIntersect_addr(); void *Mesh_sampleArea_addr(); void *Mesh_getAreas_addr(); } // namespace ispc #endif // std #include namespace ospray { Mesh::Mesh(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_NONE) { getSh()->super.getAreas = reinterpret_cast(ispc::Mesh_getAreas_addr()); getSh()->super.sampleArea = reinterpret_cast( ispc::Mesh_sampleArea_addr()); } std::string Mesh::toString() const { return "ospray::Mesh"; } void Mesh::commit() { bool isNormalFaceVarying = true; motionVertexData = getParamDataT *>("motion.vertex.position"); if (motionVertexData) { const auto mKeys = motionVertexData->size(); motionBlur = mKeys > 1; if (!motionVertexAddr || motionVertexAddr->size() < mKeys) // reallocate? motionVertexAddr = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), mKeys); auto mVAddr = motionVertexAddr->begin(); // check types and strides vertexData = (*motionVertexData)[0]; // use 1st key as fallback const int64_t stride = vertexData->ispc.byteStride; const size_t size = vertexData->ispc.numItems; for (size_t i = 0; i < mKeys; i++) { auto &&vtxData = (*motionVertexData)[i]; if (vtxData->type != OSP_VEC3F || vtxData->ispc.numItems != size || vtxData->ispc.byteStride != stride) throw std::runtime_error( "Mesh 'motion.vertex.position' arrays need to be" " of same size and stride and have type vec3f"); mVAddr[i] = vtxData->data(); } motionNormalData = getParamDataT *>("motion.normal"); if (!motionNormalData) { motionNormalData = getParamDataT *>("motion.vertex.normal"); isNormalFaceVarying = false; } if (motionNormalData) { if (motionNormalData->size() < mKeys) throw std::runtime_error( "Mesh 'motion*.normal' array has less keys than" " 'motion.vertex.position'"); if (!motionNormalAddr || motionNormalAddr->size() < mKeys) // reallocate? motionNormalAddr = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), mKeys); auto mNAddr = motionNormalAddr->begin(); // check types and strides normalData = (*motionNormalData)[0]; // use 1st key as fallback const int64_t stride = normalData->ispc.byteStride; for (size_t i = 0; i < mKeys; i++) { auto &&norData = (*motionNormalData)[i]; if (norData->type != OSP_VEC3F || norData->ispc.numItems != size || norData->ispc.byteStride != stride) throw std::runtime_error( "Mesh 'motion*.normal' arrays need to be" " of same size and stride and have type vec3f"); mNAddr[i] = norData->data(); } } else normalData = nullptr; } else { motionBlur = false; vertexData = getParamDataT("vertex.position", true); normalData = getParamDataT("normal"); if (!normalData) { normalData = getParamDataT("vertex.normal"); isNormalFaceVarying = false; } } colorData = getParamObject("color"); bool isColorFaceVarying = true; if (!colorData) { colorData = getParamObject("vertex.color"); isColorFaceVarying = false; } bool isTexcoordFaceVarying = true; texcoordData = getParamDataT("texcoord"); if (!texcoordData) { texcoordData = getParamDataT("vertex.texcoord"); isTexcoordFaceVarying = false; } // get optional vec3i index, if successful, it's a triangle indexData = getParamDataT("index"); // optionally get vec4i index, if successful, it's a quad if (!indexData) indexData = getParamDataT("index"); // If no index data given, make tri or quad soup based on input parameter // Index order is 0,1,2,3,... if (!indexData) { const bool quadSoup = getParam("quadSoup", false); const int elements = quadSoup ? 4 : 3; indexData = new Data(getISPCDevice(), quadSoup ? OSP_VEC4UI : OSP_VEC3UI, vec3l(vertexData->size() / elements, 1, 1)); indexData->refDec(); auto begin = (unsigned int *)indexData->data(); std::iota(begin, begin + indexData->size() * elements, 0); } const bool isTri = indexData->type == OSP_VEC3UI; getSh()->super.type = isTri ? ispc::GEOMETRY_TYPE_TRIANGLE_MESH : ispc::GEOMETRY_TYPE_QUAD_MESH; createEmbreeGeometry( isTri ? RTC_GEOMETRY_TYPE_TRIANGLE : RTC_GEOMETRY_TYPE_QUAD); time = range1f(0.0f, 1.0f); if (motionBlur) { time = getParam("time", range1f(0.0f, 1.0f)); if (time.upper < time.lower) time.upper = time.lower; rtcSetGeometryTimeStepCount(embreeGeometry, motionVertexData->size()); size_t i = 0; for (auto &&vtx : *motionVertexData) setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX, vtx, i++); rtcSetGeometryTimeRange(embreeGeometry, time.lower, time.upper); } else { rtcSetGeometryTimeStepCount(embreeGeometry, 1); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX, vertexData); } rtcSetSharedGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_INDEX, 0, isTri ? RTC_FORMAT_UINT3 : RTC_FORMAT_UINT4, indexData->data(), 0, isTri ? sizeof(vec3ui) : sizeof(vec4ui), indexData->size()); rtcCommitGeometry(embreeGeometry); getSh()->isColorFaceVarying = isColorFaceVarying; getSh()->isTexcoordFaceVarying = isTexcoordFaceVarying; getSh()->isNormalFaceVarying = isNormalFaceVarying; getSh()->index = *ispc(indexData); getSh()->vertex = *ispc(vertexData); getSh()->normal = *ispc(normalData); getSh()->color = *ispc(colorData); getSh()->texcoord = *ispc(texcoordData); getSh()->motionVertex = motionVertexAddr ? (uint8_t **)motionVertexAddr->data() : nullptr; getSh()->motionNormal = motionNormalAddr ? (uint8_t **)motionNormalAddr->data() : nullptr; getSh()->motionKeys = motionBlur ? motionVertexData->size() : 0; getSh()->time = time; getSh()->has_alpha = colorData && colorData->type == OSP_VEC4F; getSh()->is_triangleMesh = isTri; getSh()->super.numPrimitives = numPrimitives(); getSh()->super.postIntersect = isTri ? reinterpret_cast( ispc::TriangleMesh_postIntersect_addr()) : reinterpret_cast( ispc::QuadMesh_postIntersect_addr()); getSh()->flagMask = -1; if (!normalData) getSh()->flagMask &= ispc::int64(~DG_NS); if (!colorData) getSh()->flagMask &= ispc::int64(~DG_COLOR); if (!texcoordData) getSh()->flagMask &= ispc::int64(~DG_TEXCOORD); postCreationInfo(vertexData->size()); featureFlagsGeometry = isTri ? FFG_TRIANGLE : FFG_QUAD; if (motionBlur) featureFlagsGeometry |= FFG_MOTION_BLUR; } size_t Mesh::numPrimitives() const { return indexData->size(); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Mesh.h000066400000000000000000000016761464752671100224440ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" #include "common/Data.h" // ispc shared #include "MeshShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Mesh : public AddStructShared { Mesh(api::ISPCDevice &device); virtual ~Mesh() override = default; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; protected: Ref> vertexData; Ref> normalData; Ref colorData; Ref> texcoordData; Ref indexData; bool motionBlur{false}; Ref *>> motionVertexData; BufferSharedUq motionVertexAddr; Ref *>> motionNormalData; BufferSharedUq motionNormalAddr; range1f time{0.0f, 1.0f}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Mesh.ih000066400000000000000000000013101464752671100225760ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void QuadMesh_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); SYCL_EXTERNAL void TriangleMesh_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); SYCL_EXTERNAL SampleAreaRes Mesh_sampleArea(const Geometry *uniform const _self, const int32 primID, const uniform affine3f &xfm, const uniform affine3f &, const vec2f &s, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/Mesh.ispc000066400000000000000000000351431464752671100231470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Mesh.ih" #include "common/Data.ih" #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" // c++ shared #include "MeshShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; #endif // Create quad_interpolate for vec2f, vec3f, and vec4f types #define __define_quad_interpolate(T) \ static inline T quad_interpolate( \ const vec4f &uv, const T &t0, const T &t1, const T &t2, const T &t3) \ { \ return uv.x * t0 + uv.y * t1 + uv.z * t2 + uv.w * t3; \ } __define_quad_interpolate(vec2f); __define_quad_interpolate(vec3f); __define_quad_interpolate(vec4f); inline float calcEpsilon(const vec3f &a, const vec3f &b, const vec3f &c) { return reduce_max(max(max(abs(a), abs(b)), abs(c))) * ulpEpsilon; } inline float calcEpsilon( const vec3f &a, const vec3f &b, const vec3f &c, const vec3f &d) { return reduce_max(max(max(abs(a), abs(b)), max(abs(c), abs(d)))) * ulpEpsilon; } inline float Mesh_calcKey(const Mesh *uniform self, float time, int &idx) { // should only get hits within time interval, just to be sure... float t = clamp(time, self->time.lower, self->time.upper); t = (t - self->time.lower) * rcp(box_size(self->time)) * (self->motionKeys - 1); idx = clamp((int)t, (int)0, (int)(self->motionKeys - 2)); t = clamp(t - idx); return t; } inline vec3f interpolate_vec3f(const uniform int64 byteStride, const uint8 *a0, const uint8 *a1, const int index, const float t) { vec3f v0, v1; int64 offs = byteStride * index; v0 = *((const vec3f *)(a0 + offs)); v1 = *((const vec3f *)(a1 + offs)); return lerp(t, v0, v1); } SYCL_EXTERNAL void QuadMesh_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags) { Mesh *uniform self = (Mesh * uniform) _self; dg.Ng = dg.Ns = ray.Ng; const vec4ui index = get_vec4ui(self->index, ray.primID); const int iOffset = ray.primID * 4; const vec4ui findex = make_vec4ui( iOffset, iOffset + 1, iOffset + 2, iOffset + 3); // face indices const float u = ray.u; const float v = ray.v; vec4f uv; #define QUAD_BILINEAR #ifdef QUAD_BILINEAR if (index.z == index.w) uv = make_vec4f(1.f - u - v, u, v, 0.f); else uv = make_vec4f((1 - v) * (1 - u), (1 - v) * u, v * u, v * (1 - u)); #else // always as triangles if (u + v < 1.0f) uv = make_vec4f(1.f - u - v, u, 0.f, v); else uv = make_vec4f(0.f, 1.f - v, u + v - 1.f, 1.f - u); #endif flags &= self->flagMask; if (flags & DG_NS) { const vec4ui tindex = self->isNormalFaceVarying ? findex : index; if (self->motionKeys) { int idx; const float t = Mesh_calcKey(self, ray.time, idx); const uniform int64 byteStride = self->normal.byteStride; const uint8 *a0 = self->motionNormal[idx]; const uint8 *a1 = self->motionNormal[idx + 1]; const vec3f a = interpolate_vec3f(byteStride, a0, a1, tindex.x, t); const vec3f b = interpolate_vec3f(byteStride, a0, a1, tindex.y, t); const vec3f c = interpolate_vec3f(byteStride, a0, a1, tindex.z, t); const vec3f d = interpolate_vec3f(byteStride, a0, a1, tindex.w, t); dg.Ns = quad_interpolate(uv, a, b, c, d); } else { const vec3f a = get_vec3f(self->normal, tindex.x); const vec3f b = get_vec3f(self->normal, tindex.y); const vec3f c = get_vec3f(self->normal, tindex.z); const vec3f d = get_vec3f(self->normal, tindex.w); dg.Ns = quad_interpolate(uv, a, b, c, d); } } if (flags & DG_COLOR) { const vec4ui tindex = self->isColorFaceVarying ? findex : index; const vec4f a = get_vec4f(self->color, tindex.x); const vec4f b = get_vec4f(self->color, tindex.y); const vec4f c = get_vec4f(self->color, tindex.z); const vec4f d = get_vec4f(self->color, tindex.w); dg.color = quad_interpolate(uv, a, b, c, d); if (!self->has_alpha) dg.color.w = 1.f; } vec3f va, vb, vc, vd; if (self->motionKeys) { int idx; const float t = Mesh_calcKey(self, ray.time, idx); const uniform int64 byteStride = self->vertex.byteStride; const uint8 *a0 = self->motionVertex[idx]; const uint8 *a1 = self->motionVertex[idx + 1]; va = interpolate_vec3f(byteStride, a0, a1, index.x, t); vb = interpolate_vec3f(byteStride, a0, a1, index.y, t); vc = interpolate_vec3f(byteStride, a0, a1, index.z, t); vd = interpolate_vec3f(byteStride, a0, a1, index.w, t); } else { va = get_vec3f(self->vertex, index.x); vb = get_vec3f(self->vertex, index.y); vc = get_vec3f(self->vertex, index.z); vd = get_vec3f(self->vertex, index.w); } dg.epsilon = calcEpsilon(va, vb, vc, vd); const uniform bool compute_texcoord = flags & DG_TEXCOORD; bool compute_tangents = flags & DG_TANGENTS; if ((compute_texcoord || compute_tangents) && valid(self->texcoord)) { const vec4ui tindex = self->isTexcoordFaceVarying ? findex : index; const vec2f a = get_vec2f(self->texcoord, tindex.x); const vec2f b = get_vec2f(self->texcoord, tindex.y); const vec2f d = get_vec2f(self->texcoord, tindex.w); if (compute_texcoord) { const vec2f c = get_vec2f(self->texcoord, tindex.z); dg.st = quad_interpolate(uv, a, b, c, d); } if (compute_tangents) { const vec2f dst02 = a - d; const vec2f dst12 = b - d; const float det = dst02.x * dst12.y - dst02.y * dst12.x; if (det != 0.f) { const float invDet = rcp(det); const vec3f dp02 = va - vd; const vec3f dp12 = vb - vd; dg.dPds = (dst12.y * dp02 - dst02.y * dp12) * invDet; dg.dPdt = (dst02.x * dp12 - dst12.x * dp02) * invDet; compute_tangents = false; } } } if (compute_tangents) { dg.dPds = vb - va; dg.dPdt = vd - va; } } SYCL_EXTERNAL void TriangleMesh_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags) { Mesh *uniform self = (Mesh * uniform) _self; dg.Ng = dg.Ns = ray.Ng; const vec3ui index = get_vec3ui(self->index, ray.primID); const int iOffset = ray.primID * 3; const vec3ui findex = make_vec3ui(iOffset, iOffset + 1, iOffset + 2); // face indices const vec3f uv = make_vec3f(1.0f - ray.u - ray.v, ray.u, ray.v); flags &= self->flagMask; if (flags & DG_NS) { const vec3ui tindex = self->isNormalFaceVarying ? findex : index; if (self->motionKeys) { int idx; const float t = Mesh_calcKey(self, ray.time, idx); const uniform int64 byteStride = self->normal.byteStride; const uint8 *a0 = self->motionNormal[idx]; const uint8 *a1 = self->motionNormal[idx + 1]; const vec3f a = interpolate_vec3f(byteStride, a0, a1, tindex.x, t); const vec3f b = interpolate_vec3f(byteStride, a0, a1, tindex.y, t); const vec3f c = interpolate_vec3f(byteStride, a0, a1, tindex.z, t); dg.Ns = interpolate(uv, a, b, c); } else { const vec3f a = get_vec3f(self->normal, tindex.x); const vec3f b = get_vec3f(self->normal, tindex.y); const vec3f c = get_vec3f(self->normal, tindex.z); dg.Ns = interpolate(uv, a, b, c); } } if (flags & DG_COLOR) { const vec3ui tindex = self->isColorFaceVarying ? findex : index; const vec4f a = get_vec4f(self->color, tindex.x); const vec4f b = get_vec4f(self->color, tindex.y); const vec4f c = get_vec4f(self->color, tindex.z); dg.color = interpolate(uv, a, b, c); if (!self->has_alpha) dg.color.w = 1.f; } vec3f va, vb, vc; if (self->motionKeys) { int idx; const float t = Mesh_calcKey(self, ray.time, idx); const uniform int64 byteStride = self->vertex.byteStride; const uint8 *a0 = self->motionVertex[idx]; const uint8 *a1 = self->motionVertex[idx + 1]; va = interpolate_vec3f(byteStride, a0, a1, index.x, t); vb = interpolate_vec3f(byteStride, a0, a1, index.y, t); vc = interpolate_vec3f(byteStride, a0, a1, index.z, t); } else { va = get_vec3f(self->vertex, index.x); vb = get_vec3f(self->vertex, index.y); vc = get_vec3f(self->vertex, index.z); } dg.epsilon = calcEpsilon(va, vb, vc); const uniform bool compute_texcoord = flags & DG_TEXCOORD; bool compute_tangents = flags & DG_TANGENTS; if ((compute_texcoord || compute_tangents) && valid(self->texcoord)) { const vec3ui tindex = self->isTexcoordFaceVarying ? findex : index; const vec2f a = get_vec2f(self->texcoord, tindex.x); const vec2f b = get_vec2f(self->texcoord, tindex.y); const vec2f c = get_vec2f(self->texcoord, tindex.z); if (compute_texcoord) dg.st = interpolate(uv, a, b, c); if (compute_tangents) { const vec2f dst02 = a - c; const vec2f dst12 = b - c; const float det = dst02.x * dst12.y - dst02.y * dst12.x; if (det != 0.f) { const float invDet = rcp(det); const vec3f dp02 = va - vc; const vec3f dp12 = vb - vc; dg.dPds = (dst12.y * dp02 - dst02.y * dp12) * invDet; dg.dPdt = (dst02.x * dp12 - dst12.x * dp02) * invDet; compute_tangents = false; } } } if (compute_tangents) { dg.dPds = vb - va; dg.dPdt = vc - va; } } SYCL_EXTERNAL SampleAreaRes Mesh_sampleArea(const Geometry *uniform const _self, const int32 primID, const uniform affine3f &xfm, const uniform affine3f &, const vec2f &s, const float time) { const Mesh *const uniform self = (const Mesh *uniform)_self; SampleAreaRes res; vec4ui index4; bool quad = false; if (self->is_triangleMesh) { const vec3ui index3 = get_vec3ui(self->index, primID); index4 = make_vec4ui(index3.x, index3.y, index3.z, index3.z); } else { index4 = get_vec4ui(self->index, primID); quad = index4.z != index4.w; } const vec4ui index = index4; vec3f a, b, c, d; if (self->motionKeys) { int idx; const float t = Mesh_calcKey(self, time, idx); const uniform int64 byteStride = self->vertex.byteStride; const uint8 *a0 = self->motionVertex[idx]; const uint8 *a1 = self->motionVertex[idx + 1]; a = interpolate_vec3f(byteStride, a0, a1, index.x, t); b = interpolate_vec3f(byteStride, a0, a1, index.y, t); d = interpolate_vec3f(byteStride, a0, a1, index.w, t); if (quad) c = interpolate_vec3f(byteStride, a0, a1, index.z, t); else c = d; } else { a = get_vec3f(self->vertex, index.x); b = get_vec3f(self->vertex, index.y); d = get_vec3f(self->vertex, index.w); if (quad) c = get_vec3f(self->vertex, index.z); else c = d; } res.epsilon = calcEpsilon(a, b, c, d); res.epsilon *= max(abs(xfm.l.vx.x), max(abs(xfm.l.vy.y), abs(xfm.l.vz.z))); const vec3f e1 = xfmVector(xfm, a - d); const vec3f e2 = xfmVector(xfm, b - d); const vec3f m1 = cross(e1, e2); res.normal = m1; vec3f v0 = a; vec3f v1 = b; vec3f v2 = d; vec2f sp = s; bool invertUV = false; if (quad) { // painfully slow: re-calculate areas to decide which triangle to sample const vec3f e3 = xfmVector(xfm, c - d); const vec3f m2 = cross(e2, e3); const float a1 = length(m1); const float a2 = length(m2); const float p1 = a1 * rcp(a1 + a2); if (s.x < p1) { sp.x *= rcp(p1); // reproject } else { // sample second tri sp.x = (s.x - p1) * rcp(1.f - p1); // reproject // same split and parametrization as Embree invertUV = true; v0 = c; v1 = d; v2 = b; res.normal = m2; } } const vec2f uv = uniformSampleTriangleUV(sp); const vec3f localPos = v0 + uv.x * (v1 - v0) + uv.y * (v2 - v0); res.normal = normalize(res.normal); res.pos = xfmPoint(xfm, localPos); res.st = invertUV ? 1.0f - uv : uv; if (valid(self->texcoord)) { const float u = res.st.x; const float v = res.st.y; vec4f uv4; #ifdef QUAD_BILINEAR if (quad) uv4 = make_vec4f((1 - v) * (1 - u), (1 - v) * u, v * u, v * (1 - u)); else uv4 = make_vec4f(1.f - u - v, u, v, 0.f); #else // always as triangles if (invertUV) uv4 = make_vec4f(0.f, 1.f - v, u + v - 1.f, 1.f - u); else uv4 = make_vec4f(1.f - u - v, u, 0.f, v); #endif const int iOffs = primID * (self->is_triangleMesh ? 3 : 4); const vec4ui findex = make_vec4ui(iOffs, iOffs + 1, iOffs + 2, iOffs + 3); const vec4ui tindex = self->isTexcoordFaceVarying ? findex : index; const vec2f a = get_vec2f(self->texcoord, tindex.x); const vec2f b = get_vec2f(self->texcoord, tindex.y); const vec2f c = get_vec2f(self->texcoord, tindex.z); if (self->is_triangleMesh) { res.st = interpolate(make_vec3f(uv4), a, b, c); } else { const vec2f d = get_vec2f(self->texcoord, tindex.w); res.st = quad_interpolate(uv4, a, b, c, d); } } return res; } void Mesh_getAreas(const Geometry *const uniform _self, const int32 *const uniform primIDs, const uniform int32 numPrims, const uniform affine3f &xfm, float *const uniform areas) { const Mesh *const uniform self = (const Mesh *uniform)_self; // TODO vectorize this loop, with for each or ProgramCount & ProgramIndex // XXX for deformation motion blur the areas (i.e. selection probabilities) // are calculated using the first key only uniform vec4ui index; for (uniform int32 i = 0; i < numPrims; i++) { uniform bool quad = false; if (self->is_triangleMesh) { const uniform vec3ui index3 = get_vec3ui(self->index, primIDs[i]); index = make_vec4ui(index3.x, index3.y, index3.z, index3.z); } else { index = get_vec4ui(self->index, primIDs[i]); quad = index.z != index.w; } const uniform vec3f a = get_vec3f(self->vertex, index.x); const uniform vec3f b = get_vec3f(self->vertex, index.y); // use same splitting diagonal as Embree const uniform vec3f d = get_vec3f(self->vertex, index.w); const uniform vec3f e1 = xfmVector(xfm, a - d); const uniform vec3f e2 = xfmVector(xfm, b - d); areas[i] = length(cross(e1, e2)); if (quad) { const uniform vec3f c = get_vec3f(self->vertex, index.z); const uniform vec3f e3 = xfmVector(xfm, c - d); areas[i] += length(cross(e2, e3)); } areas[i] *= 0.5f; } } export void *uniform QuadMesh_postIntersect_addr() { return (void *uniform)QuadMesh_postIntersect; } export void *uniform TriangleMesh_postIntersect_addr() { return (void *uniform)TriangleMesh_postIntersect; } export void *uniform Mesh_sampleArea_addr() { return (void *uniform)Mesh_sampleArea; } export void *uniform Mesh_getAreas_addr() { return (void *uniform)Mesh_getAreas; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/MeshShared.h000066400000000000000000000017471464752671100235720ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Mesh { Geometry super; Data1D index; Data1D vertex; Data1D normal; Data1D color; Data1D texcoord; uint8 **motionVertex; uint8 **motionNormal; uint32 motionKeys; box1f time; int64 flagMask; // which attributes are missing and cannot be interpolated bool has_alpha; // 4th color component is valid bool is_triangleMesh; bool isColorFaceVarying; bool isTexcoordFaceVarying; bool isNormalFaceVarying; #ifdef __cplusplus Mesh() : motionVertex(nullptr), motionNormal(nullptr), motionKeys(0), time(0.f, 1.f), flagMask(-1), has_alpha(false), is_triangleMesh(false), isColorFaceVarying(false), isTexcoordFaceVarying(false), isNormalFaceVarying(false) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/Planes.cpp000066400000000000000000000022011464752671100233060ustar00rootroot00000000000000// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Planes.h" #include "common/Data.h" #ifndef OSPRAY_TARGET_SYCL // ispc-generated files #include "geometry/Planes_ispc.h" #else namespace ispc { void Planes_bounds(const RTCBoundsFunctionArguments *args); } #endif namespace ospray { Planes::Planes(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_PLANE) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.postIntersect = reinterpret_cast( ispc::Planes_postIntersect_addr()); #endif } std::string Planes::toString() const { return "ospray::Planes"; } void Planes::commit() { coeffsData = getParamDataT("plane.coefficients", true); boundsData = getParamDataT("plane.bounds"); createEmbreeUserGeometry((RTCBoundsFunction)&ispc::Planes_bounds); getSh()->coeffs = *ispc(coeffsData); getSh()->bounds = *ispc(boundsData); getSh()->super.numPrimitives = numPrimitives(); postCreationInfo(); } size_t Planes::numPrimitives() const { return coeffsData ? coeffsData->size() : 0; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Planes.h000066400000000000000000000011151464752671100227560ustar00rootroot00000000000000// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" // ispc shared #include "PlanesShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Planes : public AddStructShared { Planes(api::ISPCDevice &device); virtual ~Planes() override = default; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; protected: Ref> coeffsData; Ref> boundsData; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Planes.ih000066400000000000000000000010761464752671100231350ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Only used on the host void Planes_bounds(const RTCBoundsFunctionArguments *uniform args); SYCL_EXTERNAL void Planes_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); SYCL_EXTERNAL unmasked void Planes_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/Planes.ispc000066400000000000000000000104311464752671100234660ustar00rootroot00000000000000// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "common/Data.ih" #include "common/DifferentialGeometry.ih" #include "common/FilterIntersect.ih" #include "common/Intersect.ih" #include "common/Ray.ih" #include "geometry/Geometry.ih" #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "PlanesShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // The plane can't be truly infinite because Embree has a limit on object size #define PLANE_MAX_SIZE 1e18f #define DUMMY_MAX_T 1e38f export void Planes_bounds(const RTCBoundsFunctionArguments *uniform args) { const uniform vec3f lo = make_vec3f(-PLANE_MAX_SIZE, -PLANE_MAX_SIZE, -PLANE_MAX_SIZE); const uniform vec3f hi = make_vec3f(PLANE_MAX_SIZE, PLANE_MAX_SIZE, PLANE_MAX_SIZE); // use maximum size planes if bounding boxes not provided Planes *uniform self = (Planes * uniform) args->geometryUserPtr; box3fa *uniform out = (box3fa * uniform) args->bounds_o; if (valid(self->bounds)) { uniform int primID = args->primID; uniform box3f bbox = get_box3f(self->bounds, primID); *out = make_box3fa(max(bbox.lower, lo), min(bbox.upper, hi)); } else { *out = make_box3fa(lo, hi); } } SYCL_EXTERNAL unmasked void Planes_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest) { // make sure to set the mask if (!args->valid[programIndex]) return; args->valid[programIndex] = 0; // get geometry pointers Planes *uniform self = (Planes * uniform) args->geometryUserPtr; uniform unsigned int primID = args->primID; // this assumes that the args->rayhit is actually a pointer to a varying // ray! varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; // intersect plane with ray uniform vec4f coeffs = get_vec4f(self->coeffs, primID); const Hit hit = intersectPlane(ray->org, ray->dir, coeffs); // do bounding box check if defined if (valid(self->bounds)) { uniform box3f bbox = get_box3f(self->bounds, primID); const Intersections isect = intersectBox(ray->org, ray->dir, bbox); // discard the intersection if our ray misses bbox completely or // the intersection is not within bbox extents, // assumes that (isect.entry.hit == isect.exit.hit) if (!isect.entry.hit || (hit.t < isect.entry.t) || (hit.t > isect.exit.t)) return; } // we are done if first intersection accepted if (filterIntersectionSingle(args, hit, isOcclusionTest, false)) { args->valid[programIndex] = -1; return; } // handle plane parallel to ray, which breaks interval logic for clipping if (!hit.hit) { const uniform vec3f normal = make_vec3f(coeffs); if (coeffs.w > dot(ray->org, normal)) { // within clipping half-space? Hit hitExitDummy; hitExitDummy.hit = true; hitExitDummy.t = DUMMY_MAX_T; hitExitDummy.N = ray->dir; filterIntersectionSingle(args, hitExitDummy, isOcclusionTest, true); } return; } // The second implicit plane is needed just for infinite planes if (valid(self->bounds)) return; // clipping algorithm works on closed surfaces only, // so for infinite planes an implicit second plane is tested here, // it is positioned at the edge of bounding box and its // normal is oriented in opposite direction to mimic a closed surface const uniform vec4f coeffsImplicit = make_vec4f(-coeffs.x, -coeffs.y, -coeffs.z, PLANE_MAX_SIZE); const Hit hitImplicit = intersectPlane(ray->org, ray->dir, coeffsImplicit); // we don't want the second plane to be drawn so this intersection is never // accepted filterIntersectionSingle(args, hitImplicit, isOcclusionTest, true); } export void Planes_intersect( const struct RTCIntersectFunctionNArguments *uniform args) { Planes_intersect_kernel(args, false); } export void Planes_occluded( const struct RTCOccludedFunctionNArguments *uniform args) { Planes_intersect_kernel( (RTCIntersectFunctionNArguments * uniform) args, true); } SYCL_EXTERNAL void Planes_postIntersect(const Geometry *uniform, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64) { dg.Ng = dg.Ns = ray.Ng; } export void *uniform Planes_postIntersect_addr() { return (void *uniform)Planes_postIntersect; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/PlanesShared.h000066400000000000000000000006131464752671100241070ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Planes { Geometry super; Data1D coeffs; Data1D bounds; #ifdef __cplusplus Planes() { super.type = GEOMETRY_TYPE_PLANES; } #endif }; #ifdef __cplusplus } // namespace ispc #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/Spheres.cpp000066400000000000000000000075761464752671100235210ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Spheres.h" #include "common/Data.h" #ifndef OSPRAY_TARGET_SYCL // ispc-generated files #include "geometry/Spheres_ispc.h" #else namespace ispc { void *Spheres_sampleArea_addr(); void *Spheres_getAreas_addr(); } // namespace ispc #endif namespace ospray { static std::map sphereFeatureFlags = { {OSP_SPHERE, FFG_SPHERE}, {OSP_DISC, FFG_DISC_POINT}, {OSP_ORIENTED_DISC, FFG_ORIENTED_DISC_POINT}}; Spheres::Spheres(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_NONE) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.postIntersect = reinterpret_cast( ispc::Spheres_postIntersect_addr()); #endif getSh()->super.getAreas = reinterpret_cast( ispc::Spheres_getAreas_addr()); // We also set the sampleArea function ptr so that // Geometry::supportAreaLighting will be true, but in SYCL we'll never call it // through the function pointer on the device getSh()->super.sampleArea = reinterpret_cast( ispc::Spheres_sampleArea_addr()); } std::string Spheres::toString() const { return "ospray::Spheres"; } void Spheres::commit() { sphereType = (OSPSphereType)getParam("type", OSP_SPHERE); radius = getParam("radius", 0.01f); vertexData = getParamDataT("sphere.position", true); radiusData = getParamDataT("sphere.radius"); texcoordData = getParamDataT("sphere.texcoord"); normalData = nullptr; if (sphereType == OSP_ORIENTED_DISC) { normalData = getParamDataT("sphere.normal", true); } // If the application's data is already interleaved and they just passed us // separate views into the interleaved data to make the sphere.position and // sphere.radius arrays we can detect this and use the interleaved array // directly to avoid copying it. If not, we need to make a new interleaved // data array for Embree if (radiusData && vertexData && reinterpret_cast(vertexData->data()) + sizeof(vec3f) == reinterpret_cast(radiusData->data()) && vertexData->stride() == radiusData->stride()) { auto interleaved = new Data(getISPCDevice(), vertexData->data(), OSP_VEC4F, vertexData->numItems, vec3l(sizeof(vec4f), 0, 0)); sphereData = &interleaved->as(); interleaved->refDec(); } else { // To maintain OSPRay 2.x compatibility we need to create the interleaved // position/radius array that Embree expects from the separate // position/radius (or global radius) that the OSPRay geometry takes auto interleaved = new Data(getISPCDevice(), OSP_VEC4F, vertexData->numItems); sphereData = &interleaved->as(); interleaved->refDec(); // For now default to always create the interleaved buffer since we // don't expose the interleaved data yet for (size_t i = 0; i < vertexData->size(); ++i) { float ptRadius = radius; if (radiusData) { ptRadius = (*radiusData)[i]; } interleaved->as()[i] = vec4f((*vertexData)[i], ptRadius); } } createEmbreeGeometry((RTCGeometryType)sphereType); featureFlagsGeometry = sphereFeatureFlags[sphereType]; setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX, sphereData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_NORMAL, normalData); rtcCommitGeometry(embreeGeometry); getSh()->sphere = *ispc(sphereData); getSh()->texcoord = *ispc(texcoordData); getSh()->super.numPrimitives = numPrimitives(); getSh()->normalData = *ispc(normalData); getSh()->sphereType = sphereType; postCreationInfo(numPrimitives()); } size_t Spheres::numPrimitives() const { return sphereData ? sphereData->size() : 0; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Spheres.h000066400000000000000000000022601464752671100231470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" // ispc shared #include "SpheresShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Spheres : public AddStructShared { Spheres(api::ISPCDevice &device); virtual ~Spheres() override = default; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; protected: float radius{.01f}; // default radius, if no per-sphere radius Ref> vertexData; Ref> radiusData; Ref> texcoordData; // Embree's layout for sphere point uses interleaved position and // radius, each sphere is stored as x, y, z, r. OSPRay 2's format is not // interleaved, so we should deprecate the non-interleaved format. This array // is used to reference the interleaved data for the app or the interleaved // data the geometry creates when using the deprecated parameters Ref> sphereData; Ref> normalData; OSPSphereType sphereType{OSP_UNKNOWN_SPHERE_TYPE}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Spheres.ih000066400000000000000000000010451464752671100233200ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL void Spheres_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); SYCL_EXTERNAL SampleAreaRes Spheres_sampleArea( const Geometry *uniform const _self, const int32 primID, const uniform affine3f &xfm, const uniform affine3f &, const vec2f &s, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/Spheres.ispc000066400000000000000000000070051464752671100236600ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Spheres.ih" #include "common/Data.ih" #include "common/DifferentialGeometry.ih" #include "common/FilterIntersect.ih" #include "common/ISPCMessages.h" #include "common/Intersect.ih" #include "common/Ray.ih" #include "math/sampling.ih" #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "SpheresShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL using namespace ospray; #endif SYCL_EXTERNAL void Spheres_postIntersect(const Geometry *uniform geometry, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags) { Spheres *uniform self = (Spheres * uniform) geometry; dg.Ng = dg.Ns = ray.Ng; const vec4f vertex = get_vec4f(self->sphere, ray.primID); // make epsilon large enough to not get lost when computing // |CO| = |center-ray.org| ~ radius for 2ndary rays dg.epsilon = vertex.w * ulpEpsilon; if ((flags & DG_TEXCOORD) && valid(self->texcoord)) { dg.st = get_vec2f(self->texcoord, ray.primID); } } SYCL_EXTERNAL SampleAreaRes Spheres_sampleArea( const Geometry *uniform const _self, const int32 primID, const uniform affine3f &xfm, const uniform affine3f &rcp_xfm, const vec2f &s, const float) { const Spheres *const uniform self = (const Spheres *uniform)_self; const vec4f vertex = get_vec4f(self->sphere, primID); vec3f localNormal; vec3f localPos; if (self->sphereType == OSP_ORIENTED_DISC) { localNormal = normalize(get_vec3f(self->normalData, primID)); localPos = frame(localNormal) * uniformSampleDisk(vertex.w, s); } else { localNormal = uniformSampleSphere(vertex.w, s); localPos = localNormal; } SampleAreaRes res; res.pos = xfmPoint(xfm, make_vec3f(vertex) + localPos); res.normal = normalize(xfmVector(transposed(rcp_xfm.l), localNormal)); res.st = valid(self->texcoord) ? get_vec2f(self->texcoord, primID) : make_vec2f(0.f); res.epsilon = vertex.w * ulpEpsilon; res.epsilon *= max(abs(xfm.l.vx.x), max(abs(xfm.l.vy.y), abs(xfm.l.vz.z))); return res; } void Spheres_getAreas(const Geometry *const uniform _self, const int32 *const uniform, const uniform int32 numPrims, const uniform affine3f &xfm, float *const uniform areas) { Spheres *uniform self = (Spheres * uniform) _self; // detect (non-uniform) scaling; get length of transformed unit-vectors const uniform vec3f scaling3 = make_vec3f(length(xfm.l.vx), length(xfm.l.vy), length(xfm.l.vz)); #if 0 const uniform float min_scaling = reduce_min(scaling3); const uniform float max_scaling = reduce_max(scaling3); if ((max_scaling - min_scaling) > 1e-4f * min_scaling) { postStatusMsg(ISPC_MSG_SPHERES, OSP_LOG_WARNING); } #endif // use average as approximation to closest uniform scaling const uniform float scale = ((self->sphereType == OSP_SPHERE) ? 4.0f : 1.0f) * (float)pi * sqr(reduce_add(scaling3) / 3.f); // TODO vectorize this loop, with foreach or ProgramCount & ProgramIndex for (uniform int32 i = 0; i < numPrims; i++) { const uniform vec4f vertex = get_vec4f(self->sphere, i); areas[i] = scale * sqr(vertex.w); } } export void *uniform Spheres_postIntersect_addr() { return (void *uniform)Spheres_postIntersect; } export void *uniform Spheres_sampleArea_addr() { return (void *uniform)Spheres_sampleArea; } export void *uniform Spheres_getAreas_addr() { return (void *uniform)Spheres_getAreas; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/SpheresShared.h000066400000000000000000000007351464752671100243030ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Spheres { Geometry super; Data1D sphere; Data1D texcoord; Data1D normalData; float global_radius; OSPSphereType sphereType; #ifdef __cplusplus Spheres() : global_radius(.01f) { super.type = GEOMETRY_TYPE_SPHERES; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/Subdivision.cpp000066400000000000000000000134151464752671100243730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Subdivision.h" #include "common/DGEnum.h" #include #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "geometry/Subdivision_ispc.h" #else void *Subdivision_postIntersect_addr(); #endif namespace ospray { Subdivision::Subdivision(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_SUBDIVISION) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.postIntersect = reinterpret_cast( ispc::Subdivision_postIntersect_addr()); #endif } std::string Subdivision::toString() const { return "ospray::Subdivision"; } void Subdivision::commit() { createEmbreeGeometry(RTC_GEOMETRY_TYPE_SUBDIVISION); vertexData = getParamDataT("vertex.position", true); colorsData = getParamDataT("color"); bool isColorsFaceVarying = true; if (!colorsData) { colorsData = getParamDataT("vertex.color"); isColorsFaceVarying = false; } texcoordData = getParamDataT("texcoord"); bool isTexcoordFaceVarying = true; if (!texcoordData) { texcoordData = getParamDataT("vertex.texcoord"); isTexcoordFaceVarying = false; } level = getParam("level", 5.f); indexData = getParamDataT("index", true); indexLevelData = getParamDataT("index.level"); facesData = getParamDataT("face"); edge_crease_indicesData = getParamDataT("edgeCrease.index"); edge_crease_weightsData = getParamDataT("edgeCrease.weight"); vertex_crease_indicesData = getParamDataT("vertexCrease.index"); vertex_crease_weightsData = getParamDataT("vertexCrease.weight"); mode = (OSPSubdivisionMode)getParam( "mode", OSP_SUBDIVISION_SMOOTH_BOUNDARY); if (!facesData) { if (indexData->size() % 4 != 0) throw std::runtime_error( toString() + ": if no 'face' array is present then a pure quad mesh is assumed " "(the number of indices must be a multiple of 4)"); auto data = new Data( getISPCDevice(), OSP_UINT, vec3ui(indexData->size() / 4, 1, 1)); facesData = &(data->as()); data->refDec(); for (auto &&face : *facesData) face = 4; } setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX, vertexData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_INDEX, indexData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_FACE, facesData); rtcSetGeometrySubdivisionMode(embreeGeometry, 0, (RTCSubdivisionMode)mode); if (edge_crease_indicesData && edge_crease_weightsData) { if (edge_crease_indicesData->size() != edge_crease_weightsData->size()) postStatusMsg(OSP_LOG_DEBUG) << toString() + " ignoring edge creases, because size of arrays " "'edgeCrease.index' and 'edgeCrease.weight' does not match"; else { setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_EDGE_CREASE_INDEX, edge_crease_indicesData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT, edge_crease_weightsData); } } if (vertex_crease_indicesData && vertex_crease_weightsData) { if (vertex_crease_indicesData->size() != vertex_crease_weightsData->size()) { postStatusMsg(OSP_LOG_DEBUG) << toString() + " ignoring vertex creases, because size of " "arrays 'vertexCrease.index' and " "'vertexCrease.weight' does not match"; } else { setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX, vertex_crease_indicesData); setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT, vertex_crease_weightsData); } } if ((colorsData && isColorsFaceVarying) || (texcoordData && isTexcoordFaceVarying)) { if (generatedIndicesSize != indexData->size()) { auto data = new Data(getISPCDevice(), OSP_UINT, vec3ui(indexData->size(), 1, 1)); generatedIndicesData = &(data->as()); data->refDec(); uint32_t *dataptr = static_cast(generatedIndicesData->data()); for (unsigned int i = 0; i < indexData->size(); i++) *(dataptr++) = i; generatedIndicesSize = indexData->size(); } rtcSetGeometryTopologyCount(embreeGeometry, 2); setEmbreeGeometryBuffer( embreeGeometry, RTC_BUFFER_TYPE_INDEX, generatedIndicesData, 1); rtcSetGeometrySubdivisionMode(embreeGeometry, 1, (RTCSubdivisionMode)mode); } if (colorsData) { rtcSetGeometryVertexAttributeCount(embreeGeometry, 1); setEmbreeGeometryBuffer( embreeGeometry, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, colorsData, 0); if (isColorsFaceVarying) rtcSetGeometryVertexAttributeTopology(embreeGeometry, 0, 1); } if (texcoordData) { rtcSetGeometryVertexAttributeCount(embreeGeometry, 2); setEmbreeGeometryBuffer( embreeGeometry, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, texcoordData, 1); if (isTexcoordFaceVarying) rtcSetGeometryVertexAttributeTopology(embreeGeometry, 1, 1); } if (!indexLevelData) rtcSetGeometryTessellationRate(embreeGeometry, level); else { setEmbreeGeometryBuffer( embreeGeometry, RTC_BUFFER_TYPE_LEVEL, indexLevelData); } rtcCommitGeometry(embreeGeometry); getSh()->geom = embreeGeometry; getSh()->flagMask = -1; if (!colorsData) getSh()->flagMask &= ispc::int64(~DG_COLOR); if (!texcoordData) getSh()->flagMask &= ispc::int64(~DG_TEXCOORD); getSh()->super.numPrimitives = numPrimitives(); postCreationInfo(vertexData->size()); } size_t Subdivision::numPrimitives() const { return facesData->size(); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Subdivision.h000066400000000000000000000023541464752671100240400ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" #include "common/Data.h" // ispc shared #include "SubdivisionShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Subdivision : public AddStructShared { Subdivision(api::ISPCDevice &device); virtual ~Subdivision() override = default; virtual std::string toString() const override; virtual void commit() override; virtual size_t numPrimitives() const override; protected: float level{0.f}; Ref> vertexData; Ref> colorsData; size_t generatedIndicesSize{0}; // indices for face varying params Ref> generatedIndicesData; Ref> texcoordData; Ref> indexData; Ref> colorIndexData; Ref> indexLevelData; Ref> facesData; Ref> edge_crease_indicesData; Ref> edge_crease_weightsData; Ref> vertex_crease_indicesData; Ref> vertex_crease_weightsData; OSPSubdivisionMode mode{OSP_SUBDIVISION_SMOOTH_BOUNDARY}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/Subdivision.ih000066400000000000000000000005421464752671100242060ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry/Geometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Not supported/used in SYCL/GPU void Subdivision_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/Subdivision.ispc000066400000000000000000000024061464752671100245450ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Geometry.ih" #include "common/Data.ih" // c++ shared #include "SubdivisionShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE void Subdivision_postIntersect(const Geometry *uniform _self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags) { Subdivision *uniform self = (Subdivision * uniform) _self; dg.Ng = dg.Ns = ray.Ng; flags &= self->flagMask; if (flags & DG_NS) { vec3f dPdu, dPdv; rtcInterpolateV1(self->geom, ray.primID, ray.u, ray.v, RTC_BUFFER_TYPE_VERTEX, 0, NULL, &dPdu.x, &dPdv.x, 3); dg.Ns = cross(dPdu, dPdv); } if (flags & DG_COLOR) { rtcInterpolateV0(self->geom, ray.primID, ray.u, ray.v, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, &dg.color.x, 4); } if (flags & DG_TEXCOORD) { rtcInterpolateV0(self->geom, ray.primID, ray.u, ray.v, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 1, &dg.st.x, 2); } } export void *uniform Subdivision_postIntersect_addr() { return (void *uniform)Subdivision_postIntersect; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/geometry/SubdivisionShared.h000066400000000000000000000007461464752671100251720ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Subdivision { Geometry super; RTCGeometry geom; int64 flagMask; // which attributes are missing and cannot be interpolated #ifdef __cplusplus Subdivision() : geom(nullptr), flagMask(-1) { super.type = GEOMETRY_TYPE_SUBDIVISION; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/geometry/registration.cpp000066400000000000000000000014521464752671100246050ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Boxes.h" #include "Curves.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "Isosurfaces.h" #endif #include "Mesh.h" #include "Planes.h" #include "Spheres.h" #ifndef OSPRAY_TARGET_SYCL #include "Subdivision.h" #endif namespace ospray { void registerAllGeometries() { Geometry::registerType("box"); Geometry::registerType("curve"); #ifdef OSPRAY_ENABLE_VOLUMES Geometry::registerType("isosurface"); #endif Geometry::registerType("mesh"); Geometry::registerType("sphere"); #ifndef OSPRAY_TARGET_SYCL // Subdivision surfaces not supported on the GPU Geometry::registerType("subdivision"); #endif Geometry::registerType("plane"); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/geometry/registration.h000066400000000000000000000002251464752671100242470ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllGeometries(); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/ispc_symbols.txt000066400000000000000000000031031464752671100227760ustar00rootroot00000000000000Distribution2D_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__, Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_CvyfCvyfCvyf_, Renderer_getBackground___un_3C_s_5B__c_unRenderer_5D__3E_REFs_5B__c_vyvec2f_5D_REFs_5B__c_unFeatureFlagsHandler_5D__, Renderer_getMaxDepth___un_3C_s_5B__c_unRenderer_5D__3E_REFs_5B__c_vyvec2f_5D_REFs_5B__c_unFeatureFlagsHandler_5D__, clippingIntersectionFilterV___UM_un_3C_s_5B__c_unRTCFilterFunctionNArguments_5D__3E__, Geometry_dispatch_intersect___UM_un_3C_s_5B_unRTCIntersectFunctionNArguments_5D__3E__, Geometry_dispatch_occluded___UM_un_3C_s_5B_unRTCOccludedFunctionNArguments_5D__3E__, Geometry_dispatch_postIntersect___un_3C_s_5B__c_unGeometry_5D__3E_REFs_5B_vyDifferentialGeometry_5D_REFs_5B__c_vyRay_5D_unIREFs_5B__c_unFeatureFlagsHandler_5D__, get4f___REFs_5B__c_unTextureParam_5D_REFs_5B__c_vyDifferentialGeometry_5D__, FrameBuffer_dispatch_getRenderTaskDesc___un_3C_s_5B_unFrameBuffer_5D__3E_CunuREFs_5B__c_unFeatureFlagsHandler_5D__, FrameBuffer_dispatch_accumulateSample___un_3C_s_5B_unFrameBuffer_5D__3E_REFs_5B__c_vyScreenSample_5D_REFs_5B_unRenderTaskDesc_5D_REFs_5B__c_unFeatureFlagsHandler_5D__, FrameBuffer_dispatch_completeTask___un_3C_s_5B_unFrameBuffer_5D__3E_REFs_5B__c_unRenderTaskDesc_5D_REFs_5B__c_unFeatureFlagsHandler_5D__, Camera_dispatch_initRay___un_3C_s_5B__c_unCamera_5D__3E_REFs_5B_vyRay_5D_REFs_5B_vyRayCone_5D_REFs_5B__c_vyCameraSample_5D_REFs_5B__c_unFeatureFlagsHandler_5D__, RenderKit-ospray-85af292/modules/cpu/ispc_symbols_volume.txt000066400000000000000000000003541464752671100243720ustar00rootroot00000000000000LinearTransferFunction_get___un_3C_s_5B__c_unTransferFunction_5D__3E_vyf_, TransferFunction_dispatch_get___un_3C_s_5B__c_unTransferFunction_5D__3E_vyf_, Volume_intersect_kernel___UM_un_3C_s_5B_unRTCIntersectFunctionNArguments_5D__3E__, RenderKit-ospray-85af292/modules/cpu/ispc_tasksys.cpp000066400000000000000000000034131464752671100227560ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include "common/OSPCommon.h" #include "rkcommon/memory/malloc.h" #include "rkcommon/tasking/parallel_for.h" namespace ospray { /* Signature of ispc-generated 'task' functions */ using ISPCTaskFunc = void (*)(void *data, int threadIndex, int threadCount, int taskIndex, int taskCount, int taskIndex0, int taskIndex1, int taskIndex2, int taskCount0, int taskCount1, int taskCount2); extern "C" OSPRAY_SDK_INTERFACE void *ISPCAlloc( void **taskPtr, int64_t size, int32_t alignment) { if (*taskPtr == nullptr) *taskPtr = new std::vector; std::vector *lst = (std::vector *)(*taskPtr); void *ptr = memory::alignedMalloc((size_t)size, alignment); lst->push_back(ptr); return ptr; } extern "C" OSPRAY_SDK_INTERFACE void ISPCSync(void *task) { std::vector *lst = (std::vector *)task; for (size_t i = 0; i < lst->size(); i++) memory::alignedFree((*lst)[i]); delete lst; } extern "C" OSPRAY_SDK_INTERFACE void ISPCLaunch(void ** /*taskPtr*/, void *func, void *data, int taskCount0, int taskCount1, int taskCount2) { const size_t nTasks = size_t(taskCount0) * size_t(taskCount1) * size_t(taskCount2); tasking::parallel_for(nTasks, [&](const size_t i) { const int taskIndex0 = i % taskCount0; const int taskIndex1 = (i / taskCount0) % taskCount1; const int taskIndex2 = i / (size_t(taskCount0) * taskCount1); ((ISPCTaskFunc)func)(data, i, nTasks, i, nTasks, taskIndex0, taskIndex1, taskIndex2, taskCount0, taskCount1, taskCount2); }); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/000077500000000000000000000000001464752671100210245ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/lights/AmbientLight.cpp000066400000000000000000000031561464752671100241040ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "AmbientLight.h" #include "common/StructShared.h" #ifndef OSPRAY_TARGET_SYCL #include "lights/AmbientLight_ispc.h" #else namespace ispc { void *AmbientLight_sample_addr(); void *AmbientLight_eval_addr(); } // namespace ispc #endif // ispc shared #include "AmbientLightShared.h" namespace ospray { ispc::Light *AmbientLight::createSh( uint32_t, const ispc::Instance *instance) const { ispc::AmbientLight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast( ispc::AmbientLight_sample_addr()); sh->super.eval = reinterpret_cast(ispc::AmbientLight_eval_addr()); #endif sh->super.isVisible = visible; sh->super.instance = instance; sh->radiance = radiance; return &sh->super; } std::string AmbientLight::toString() const { return "ospray::AmbientLight"; } void AmbientLight::commit() { Light::commit(); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_RADIANCE); processIntensityQuantityType(); } void AmbientLight::processIntensityQuantityType() { // validate the correctness of the light quantity type if (intensityQuantity == OSP_INTENSITY_QUANTITY_IRRADIANCE) { radiance = coloredIntensity / M_PI; } else if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { radiance = coloredIntensity; } else { postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; radiance = vec3f(0.0f); } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/AmbientLight.h000066400000000000000000000013071464752671100235450ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Light.h" namespace ospray { //! an AmbientLight is a constant light that is present everywhere struct OSPRAY_SDK_INTERFACE AmbientLight : public Light { AmbientLight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_AMBIENT) {} virtual ~AmbientLight() override = default; virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; vec3f radiance{1.f}; //!< emitted radiance of the AmbientLight private: void processIntensityQuantityType(); }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/AmbientLight.ih000066400000000000000000000010601464752671100237120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes AmbientLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes AmbientLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/AmbientLight.ispc000066400000000000000000000037211464752671100242560ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DifferentialGeometry.ih" #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" // c++ shared #include "AmbientLightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // Implementation ////////////////////////////////////////////////////////////////////////////// // XXX importance sampling is only done into the positive hemisphere // ==> poor support for translucent materials SYCL_EXTERNAL Light_SampleRes AmbientLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float, const uniform FeatureFlagsHandler &) { uniform AmbientLight *uniform self = (uniform AmbientLight * uniform) super; Light_SampleRes res; if (reduce_max(abs(dg.Ns)) > 0) { const vec3f localDir = cosineSampleHemisphere(s); res.dir = frame(dg.Ns) * localDir; res.pdf = cosineSampleHemispherePDF(localDir); } else { res.dir = uniformSampleSphere(1.f, s); res.pdf = uniformSampleSpherePDF(1.f); } res.dist = inf; res.weight = self->radiance * rcp(res.pdf); return res; } SYCL_EXTERNAL Light_EvalRes AmbientLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float, const float maxDist, const float) { uniform AmbientLight *uniform self = (uniform AmbientLight * uniform) super; Light_EvalRes res; res.radiance = (float)inf <= maxDist ? self->radiance : make_vec3f(0.f); if (reduce_max(abs(dg.Ns)) > 0) res.pdf = cosineSampleHemispherePDF(max(dot(dg.Ns, dir), 0.f)); else res.pdf = uniformSampleSpherePDF(1.f); return res; } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform AmbientLight_sample_addr() { return (void *uniform)AmbientLight_sample; } export void *uniform AmbientLight_eval_addr() { return (void *uniform)AmbientLight_eval; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/AmbientLightShared.h000066400000000000000000000006601464752671100246750ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct AmbientLight { Light super; // inherited light fields vec3f radiance; // emitted RGB radiance #ifdef __cplusplus AmbientLight() : radiance(1.f) { super.type = LIGHT_TYPE_AMBIENT; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/CylinderCapSolidAngleTable.ih000066400000000000000000001232431464752671100264620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE const uniform float CylCapSolidAngleTable[] = {0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 1.324344735105687941e-04f, 1.522660324370707656e-04f, 1.573041622823640709e-04f, 1.592206333250290138e-04f, 1.601378902436257539e-04f, 1.606445666452721154e-04f, 1.609530122796813971e-04f, 1.611544049267169627e-04f, 1.612930298554018850e-04f, 1.613924640850384403e-04f, 0.000000000000000000e+00f, 2.079389560425832215e-04f, 2.418569419427302593e-04f, 2.505750744399992008e-04f, 2.539021985766657676e-04f, 2.554967263084124691e-04f, 2.563780999808024769e-04f, 2.569148511271038141e-04f, 2.572653939717546990e-04f, 2.575067219119174088e-04f, 2.576798431415581146e-04f, 0.000000000000000000e+00f, 2.353557656252160569e-04f, 2.747346643900388640e-04f, 2.848935470945746515e-04f, 2.887745253091539743e-04f, 2.906352752629875590e-04f, 2.916640219201449709e-04f, 2.922905986733082559e-04f, 2.926998362668255336e-04f, 2.929815863886020013e-04f, 2.931837124451351423e-04f, 0.000000000000000000e+00f, 2.471449816382869638e-04f, 2.889245245841044274e-04f, 2.997188457314994055e-04f, 3.038443349008019688e-04f, 3.058226611542990336e-04f, 3.069165077355631341e-04f, 3.075827682434436705e-04f, 3.080179382636986712e-04f, 3.083175485132807580e-04f, 3.085324904882438043e-04f, 0.000000000000000000e+00f, 2.530989951023317479e-04f, 2.961026955154546559e-04f, 3.072215014833809088e-04f, 3.114719015023532499e-04f, 3.135103031200374511e-04f, 3.146374152658422646e-04f, 3.153239548826361808e-04f, 3.157723772518377043e-04f, 3.160811148227334185e-04f, 3.163026063990813071e-04f, 0.000000000000000000e+00f, 2.564809353247177529e-04f, 3.001834485672567800e-04f, 3.114876213887419424e-04f, 3.158093939369322942e-04f, 3.178821249299264469e-04f, 3.190282471529652577e-04f, 3.197263758519848921e-04f, 3.201823717808763401e-04f, 3.204963255635058170e-04f, 3.207215602277217921e-04f, 0.000000000000000000e+00f, 2.585734616717737873e-04f, 3.027096121304737692e-04f, 3.141288595804324390e-04f, 3.184949452806097050e-04f, 3.205889914938048245e-04f, 3.217469174426753568e-04f, 3.224522421353280457e-04f, 3.229129407487705650e-04f, 3.232301334775221466e-04f, 3.234576923788846708e-04f, 0.000000000000000000e+00f, 2.599538312189582433e-04f, 3.043765623677294522e-04f, 3.158718799923146523e-04f, 3.202672612340357614e-04f, 3.223753994528717292e-04f, 3.235411292573714057e-04f, 3.242512115177207201e-04f, 3.247150192879226017e-04f, 3.250343534384156656e-04f, 3.252634490080406069e-04f, 0.000000000000000000e+00f, 2.609105553783080608e-04f, 3.055321579139339515e-04f, 3.170802734117933344e-04f, 3.214959888194799482e-04f, 3.236139085749938256e-04f, 3.247850552478668976e-04f, 3.254984398861687973e-04f, 3.259644058287874437e-04f, 3.262852264175356508e-04f, 3.265153886461359851e-04f, 0.000000000000000000e+00f, 2.616001385399520417e-04f, 3.063652066180995947e-04f, 3.179514151471859074e-04f, 3.223818019526446471e-04f, 3.245067793375723542e-04f, 3.256818344500071673e-04f, 3.263976018676227695e-04f, 3.268651250102232240e-04f, 3.271870181202876562e-04f, 3.274179499846075663e-04f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 3.518709244702191308e-04f, 4.683165637320721247e-04f, 5.112354179907870229e-04f, 5.303183442801986426e-04f, 5.401600925084595840e-04f, 5.458213572572553993e-04f, 5.493521299147061847e-04f, 5.516935337888750988e-04f, 5.533222474443736652e-04f, 5.544992454144986914e-04f, 0.000000000000000000e+00f, 7.564274540073267963e-04f, 1.047422775041331137e-03f, 1.157895188902293045e-03f, 1.207568980015362057e-03f, 1.233320234019417332e-03f, 1.248173894431466383e-03f, 1.257452756424457408e-03f, 1.263612327455216049e-03f, 1.267900004232375925e-03f, 1.271000042202091859e-03f, 0.000000000000000000e+00f, 1.003462835547388327e-03f, 1.419131877800553724e-03f, 1.579135209145570828e-03f, 1.651485122984807079e-03f, 1.689091300932595669e-03f, 1.710813997450975378e-03f, 1.724395352762325738e-03f, 1.733415930831165271e-03f, 1.739697458797044528e-03f, 1.744240251854955927e-03f, 0.000000000000000000e+00f, 1.143834031312154515e-03f, 1.636939564350985447e-03f, 1.828099798065667934e-03f, 1.914790679706731419e-03f, 1.959913807652678436e-03f, 1.985998222441378788e-03f, 2.002313918709211060e-03f, 2.013153735013494244e-03f, 2.020703571863047363e-03f, 2.026164358059563773e-03f, 0.000000000000000000e+00f, 1.226309947336103739e-03f, 1.767333086735097024e-03f, 1.977908109642293084e-03f, 2.073560818586137576e-03f, 2.123387906682048902e-03f, 2.152203878442562283e-03f, 2.170232757489803758e-03f, 2.182212740185190698e-03f, 2.190557619589210761e-03f, 2.196593933475704443e-03f, 0.000000000000000000e+00f, 1.277461271335418244e-03f, 1.849154837636200191e-03f, 2.072208855142282369e-03f, 2.173631403692885631e-03f, 2.226489455102349368e-03f, 2.257066262878798871e-03f, 2.276199798626163916e-03f, 2.288915083509291803e-03f, 2.297772751394711651e-03f, 2.304180300992577507e-03f, 0.000000000000000000e+00f, 1.310886684522754274e-03f, 1.903030842774131731e-03f, 2.134428080685532754e-03f, 2.239712232707347355e-03f, 2.294599846438157443e-03f, 2.326356050655218645e-03f, 2.346229600079902024e-03f, 2.359437518863661924e-03f, 2.368638766816207920e-03f, 2.375295065567726085e-03f, 0.000000000000000000e+00f, 1.333742658498826388e-03f, 1.940061354761947118e-03f, 2.177251861166239286e-03f, 2.285219226091063632e-03f, 2.341517535968261950e-03f, 2.374093656364981327e-03f, 2.394481718982423898e-03f, 2.408032177838734678e-03f, 2.417472336517638778e-03f, 2.424301610494127707e-03f, 0.000000000000000000e+00f, 1.349981060688657973e-03f, 1.966465991084871863e-03f, 2.207816820003138340e-03f, 2.317711996277340217e-03f, 2.375024082451204169e-03f, 2.408189497312768039e-03f, 2.428947381262678857e-03f, 2.442744062634739140e-03f, 2.452355959253100376e-03f, 2.459309577158362136e-03f, 0.000000000000000000e+00f, 1.361894711241359206e-03f, 1.985889500491258477e-03f, 2.230316422217705225e-03f, 2.341637485555428909e-03f, 2.399699524599541254e-03f, 2.433300916004638680e-03f, 2.454332418834928586e-03f, 2.468311278606549232e-03f, 2.478050245966633217e-03f, 2.485095868809059950e-03f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 5.148143079474772456e-04f, 7.466963702743565669e-04f, 8.540924768223674864e-04f, 9.090308884320854026e-04f, 9.398167374470985059e-04f, 9.584482807966543567e-04f, 9.704531768272830951e-04f, 9.785903359863293554e-04f, 9.843379804579401558e-04f, 9.885378125159579969e-04f, 0.000000000000000000e+00f, 1.253514637562834185e-03f, 1.937381211125926810e-03f, 2.264953477267791799e-03f, 2.435076592709123963e-03f, 2.531146721947160651e-03f, 2.589542084462958128e-03f, 2.627268588474988235e-03f, 2.652884902384841648e-03f, 2.671000464765789419e-03f, 2.684248870354409826e-03f, 0.000000000000000000e+00f, 1.805645740500164045e-03f, 2.923239499370571155e-03f, 3.469880912448602625e-03f, 3.756492839361498873e-03f, 3.919162270565094107e-03f, 4.018327199393406657e-03f, 4.082508604594513660e-03f, 4.126139500491008902e-03f, 4.157019994337727252e-03f, 4.179616969615533410e-03f, 0.000000000000000000e+00f, 2.166031051752110529e-03f, 3.623367960760648290e-03f, 4.346786328097372240e-03f, 4.728425004110046147e-03f, 4.945730130634628727e-03f, 5.078450242993188049e-03f, 5.164449556490857511e-03f, 5.222957424495248274e-03f, 5.264389371789464193e-03f, 5.294719002811903302e-03f, 0.000000000000000000e+00f, 2.397429617633945256e-03f, 4.102067843197306288e-03f, 4.957450923063252100e-03f, 5.410593565507399588e-03f, 5.669169656332504782e-03f, 5.827292658623370661e-03f, 5.929831656028333210e-03f, 5.999627523881404835e-03f, 6.049070396274724981e-03f, 6.085273449131553547e-03f, 0.000000000000000000e+00f, 2.549368937648944372e-03f, 4.430824716323404980e-03f, 5.382479625796733787e-03f, 5.888099668579335061e-03f, 6.177049414622892871e-03f, 6.353896803602655276e-03f, 6.468638692124228234e-03f, 6.546767941194820209e-03f, 6.602127406276578521e-03f, 6.642669686120350990e-03f, 0.000000000000000000e+00f, 2.652478153375369910e-03f, 4.661169684101590209e-03f, 5.683180157940269719e-03f, 6.227324667582475638e-03f, 6.538617837456350834e-03f, 6.729254639632639874e-03f, 6.852989337057374501e-03f, 6.937262504145540881e-03f, 6.996985390082748058e-03f, 7.040728491883075507e-03f, 0.000000000000000000e+00f, 2.724833704580410364e-03f, 4.826576642897440102e-03f, 5.900647986915204257e-03f, 6.473397323717751048e-03f, 6.801306029919003925e-03f, 7.002205690658911200e-03f, 7.132636668749612469e-03f, 7.221486230823217362e-03f, 7.284459995566929316e-03f, 7.330588179434545208e-03f, 0.000000000000000000e+00f, 2.777193121512918500e-03f, 4.948313722212235519e-03f, 6.061549571150137879e-03f, 6.655874317352564358e-03f, 6.996329873173594109e-03f, 7.204984098087410804e-03f, 7.340476631155143199e-03f, 7.432786208671369500e-03f, 7.498218225694946310e-03f, 7.546150173259567884e-03f, 0.000000000000000000e+00f, 2.816127041162471301e-03f, 5.039991504078758511e-03f, 6.183207539771379095e-03f, 6.794081629995274256e-03f, 7.144169726016271968e-03f, 7.358780144991966012e-03f, 7.498161501484510751e-03f, 7.593129914869260755e-03f, 7.660451201529748164e-03f, 7.709769539512028799e-03f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 6.330630758403497406e-04f, 9.689183242194677158e-04f, 1.147393727860851259e-03f, 1.248824337567151690e-03f, 1.310016946721651813e-03f, 1.348979419893589016e-03f, 1.374985660749956928e-03f, 1.393060169151647334e-03f, 1.406061569536036938e-03f, 1.415691385285003075e-03f, 0.000000000000000000e+00f, 1.622982320300010717e-03f, 2.701938518079526844e-03f, 3.294702983947319502e-03f, 3.636918114345742345e-03f, 3.845154685284924660e-03f, 3.978419795121803000e-03f, 4.067657530720846307e-03f, 4.129812091727653317e-03f, 4.174588465907964896e-03f, 4.207789226664360865e-03f, 0.000000000000000000e+00f, 2.414795568233982399e-03f, 4.318654218803607940e-03f, 5.395581270951582339e-03f, 6.024765956700464144e-03f, 6.410139085803693605e-03f, 6.657744753022374652e-03f, 6.823970299633269967e-03f, 6.939946223429980035e-03f, 7.023596514313117274e-03f, 7.085675836419507052e-03f, 0.000000000000000000e+00f, 2.954155122638248490e-03f, 5.585884539816199715e-03f, 7.117112432957192758e-03f, 8.020644828942680507e-03f, 8.576903781303987090e-03f, 8.935395883314885268e-03f, 9.176532167816170080e-03f, 9.344994335701675356e-03f, 9.466613516980450227e-03f, 9.556931087201311556e-03f, 0.000000000000000000e+00f, 3.309622812366178578e-03f, 6.519673311726707082e-03f, 8.434770609219766069e-03f, 9.574480857880865101e-03f, 1.027907845340537626e-02f, 1.073426714901062028e-02f, 1.104091172683628087e-02f, 1.125535734483322503e-02f, 1.141028395754554135e-02f, 1.152539586104889095e-02f, 0.000000000000000000e+00f, 3.546872447411592976e-03f, 7.197122743859855031e-03f, 9.420419469569327187e-03f, 1.075305604061065762e-02f, 1.157974188162016853e-02f, 1.211483561693207055e-02f, 1.247574371943477312e-02f, 1.272833935428445591e-02f, 1.291092914697953946e-02f, 1.304664963401448372e-02f, 0.000000000000000000e+00f, 3.709598889376596823e-03f, 7.691126070511996801e-03f, 1.015658152587857292e-02f, 1.164308907444725101e-02f, 1.256778608267826794e-02f, 1.316724812456793008e-02f, 1.357195842639335667e-02f, 1.385538992174475091e-02f, 1.406035943214321848e-02f, 1.421276311649024952e-02f, 0.000000000000000000e+00f, 3.824618653025676183e-03f, 8.056429142161470464e-03f, 1.071114747813457953e-02f, 1.231942132085871340e-02f, 1.332210697903568782e-02f, 1.397293583788518541e-02f, 1.441266073211551826e-02f, 1.472076883805627061e-02f, 1.494366122753849543e-02f, 1.510943278865536921e-02f, 0.000000000000000000e+00f, 3.908276579859369312e-03f, 8.331238865437462504e-03f, 1.113438477823026213e-02f, 1.283912775213246968e-02f, 1.390388080150351847e-02f, 1.459568779448104647e-02f, 1.506338519389619802e-02f, 1.539122479106847657e-02f, 1.562845714833507524e-02f, 1.580492889957122241e-02f, 0.000000000000000000e+00f, 3.970714592225201359e-03f, 8.541660185314235709e-03f, 1.146212511353233467e-02f, 1.324374946206734009e-02f, 1.435815175165684396e-02f, 1.508280258434187455e-02f, 1.557294585420195346e-02f, 1.591663025057328193e-02f, 1.616538368357876149e-02f, 1.635045528411100887e-02f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 7.212811140121224915e-04f, 1.145742417107076683e-03f, 1.391883272944551518e-03f, 1.542798871459532314e-03f, 1.639473665637473324e-03f, 1.703890684308947186e-03f, 1.748374322168447757e-03f, 1.780089635894296744e-03f, 1.803348655089967922e-03f, 1.820833937754083587e-03f, 0.000000000000000000e+00f, 1.887340452230905439e-03f, 3.320212172265470454e-03f, 4.179485837867540250e-03f, 4.714296490400989546e-03f, 5.059805189507511798e-03f, 5.291228737426888033e-03f, 5.451582859600462815e-03f, 5.566174678315898364e-03f, 5.650350614937620086e-03f, 5.713706941678609041e-03f, 0.000000000000000000e+00f, 2.834448186751709845e-03f, 5.468555396175245331e-03f, 7.113650880673496810e-03f, 8.152108432206669683e-03f, 8.828034936984537062e-03f, 9.282851385270190700e-03f, 9.598942269980353242e-03f, 9.825292590586972782e-03f, 9.991807914818658445e-03f, 1.011727386957128084e-02f, 0.000000000000000000e+00f, 3.482562777897965905e-03f, 7.230836955609326079e-03f, 9.680161174012684097e-03f, 1.124972903795233570e-02f, 1.227878066863242502e-02f, 1.297412787946376073e-02f, 1.345868672328128825e-02f, 1.380631017143750527e-02f, 1.406237157233477565e-02f, 1.425549161837616485e-02f, 0.000000000000000000e+00f, 3.910125450455917764e-03f, 8.573986045328902544e-03f, 1.175344402795287270e-02f, 1.382224323503398154e-02f, 1.518830623356486054e-02f, 1.611506977648453215e-02f, 1.676250277269603420e-02f, 1.722774511293859862e-02f, 1.757084466358614303e-02f, 1.782982762043219122e-02f, 0.000000000000000000e+00f, 4.195478113700949578e-03f, 9.572553801176924421e-03f, 1.337208257744917743e-02f, 1.587981542579631339e-02f, 1.754687578908758691e-02f, 1.868205174785504685e-02f, 1.947689490705743071e-02f, 2.004892814257227054e-02f, 2.047122494349440380e-02f, 2.079023041572572797e-02f, 0.000000000000000000e+00f, 4.391139168102254839e-03f, 1.031374719492394315e-02f, 1.462190656340965102e-02f, 1.750115447916205519e-02f, 1.942679519129223223e-02f, 2.074244707635598123e-02f, 2.166554766725809281e-02f, 2.233078004469190095e-02f, 2.282233761806777214e-02f, 2.319391222302685795e-02f, 0.000000000000000000e+00f, 4.529394042038001507e-03f, 1.086901209427927791e-02f, 1.558799715383739869e-02f, 1.877549102780820545e-02f, 2.091854264573917224e-02f, 2.238703945070888088e-02f, 2.341923306400309213e-02f, 2.416396003589227695e-02f, 2.471470604294914372e-02f, 2.513126542062316809e-02f, 0.000000000000000000e+00f, 4.629923660528266829e-03f, 1.129079130639894755e-02f, 1.634022180551901460e-02f, 1.978126845756981306e-02f, 2.210521617926395482e-02f, 2.370169823405501863e-02f, 2.482559216036049274e-02f, 2.563730547928672401e-02f, 2.623801094619798019e-02f, 2.669258636203961088e-02f, 0.000000000000000000e+00f, 4.704936553889154868e-03f, 1.161612790425591360e-02f, 1.693193703735837441e-02f, 2.058118757044315530e-02f, 2.305512780417269536e-02f, 2.475831255654708379e-02f, 2.595891243272585233e-02f, 2.682677959716530183e-02f, 2.746942706560224698e-02f, 2.795595112510076627e-02f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 7.886277541261281585e-04f, 1.288083776318236454e-03f, 1.595231749729407802e-03f, 1.794205293561702830e-03f, 1.927825702307663612e-03f, 2.020359060251305031e-03f, 2.086251153426085976e-03f, 2.134382573814292295e-03f, 2.170362532143429047e-03f, 2.197824765211205296e-03f, 0.000000000000000000e+00f, 2.075871817031091186e-03f, 3.813224858676668438e-03f, 4.920759008805931922e-03f, 5.648430922382662728e-03f, 6.140991888636010421e-03f, 6.483794346710756648e-03f, 6.728708363724023034e-03f, 6.908018590856198314e-03f, 7.042280562632280763e-03f, 7.144883080190312166e-03f, 0.000000000000000000e+00f, 3.117381304854234102e-03f, 6.375259184681209869e-03f, 8.566777219774319649e-03f, 1.003128508041885303e-02f, 1.103089239346197181e-02f, 1.173004494238572525e-02f, 1.223118215498218871e-02f, 1.259891109331477341e-02f, 1.287470254726895934e-02f, 1.308571527942264771e-02f, 0.000000000000000000e+00f, 3.825717120065501992e-03f, 8.514634789312950161e-03f, 1.186896531448872714e-02f, 1.415911630965160581e-02f, 1.573767876663084361e-02f, 1.684782962166546383e-02f, 1.764629906813101543e-02f, 1.823356497228816389e-02f, 1.867472804716201196e-02f, 1.901267522803663790e-02f, 0.000000000000000000e+00f, 4.290824483525533355e-03f, 1.016390003634775122e-02f, 1.461213065387898837e-02f, 1.772098796640041857e-02f, 1.988756547327948099e-02f, 2.142046605735105358e-02f, 2.252707718259811323e-02f, 2.334296722288513662e-02f, 2.395691971003124227e-02f, 2.442781050823393529e-02f, 0.000000000000000000e+00f, 4.600251514432151904e-03f, 1.139909612452231005e-02f, 1.680079008919013392e-02f, 2.066199309645985402e-02f, 2.338320775886965769e-02f, 2.532056302592006203e-02f, 2.672449224496529011e-02f, 2.776218338397702309e-02f, 2.854439294144339029e-02f, 2.914508316732965232e-02f, 0.000000000000000000e+00f, 4.811966833600228761e-03f, 1.232039591725546043e-02f, 1.851919219488658980e-02f, 2.304017738419015388e-02f, 2.626031209934483884e-02f, 2.856675316168256346e-02f, 3.024437998247574491e-02f, 3.148741075694074659e-02f, 3.242599367838468888e-02f, 3.314764878185472857e-02f, 0.000000000000000000e+00f, 4.961345092670534258e-03f, 1.301288388128898389e-02f, 1.986461845266174545e-02f, 2.494866092839396338e-02f, 2.860454189137067935e-02f, 3.123772859020323631e-02f, 3.315969831138976254e-02f, 3.458705750859270012e-02f, 3.566654530130984602e-02f, 3.649749476986991620e-02f, 0.000000000000000000e+00f, 5.069848982399235808e-03f, 1.354013275348193990e-02f, 2.092263441641366295e-02f, 2.648029178931736449e-02f, 3.051020421836446103e-02f, 3.342730774392779075e-02f, 3.556323727608656782e-02f, 3.715283217135611354e-02f, 3.835677661573724112e-02f, 3.928450805609219609e-02f, 0.000000000000000000e+00f, 5.150749986807798275e-03f, 1.394751711739385114e-02f, 2.176135386663251986e-02f, 2.771490302859902846e-02f, 3.206294610534261846e-02f, 3.522414215931390230e-02f, 3.754529218616584757e-02f, 3.927598085625663704e-02f, 4.058851195179079274e-02f, 4.160088044039742666e-02f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 8.409049105883540254e-04f, 1.404128719459686852e-03f, 1.765188368639016882e-03f, 2.008796995337924253e-03f, 2.178544808847337338e-03f, 2.299906117061264327e-03f, 2.388668553265759636e-03f, 2.454952271330086699e-03f, 2.505405544133496552e-03f, 2.544488663735909248e-03f, 0.000000000000000000e+00f, 2.211276794768384218e-03f, 4.205942891278083295e-03f, 5.537393703907753963e-03f, 6.447998830919157189e-03f, 7.087164739749489059e-03f, 7.546231432481296901e-03f, 7.883021429449974318e-03f, 8.135064537221082734e-03f, 8.327214095147432785e-03f, 8.476235642834154330e-03f, 0.000000000000000000e+00f, 3.309415263687501968e-03f, 7.078555395920566561e-03f, 9.768119993488632094e-03f, 1.164596828840228429e-02f, 1.297644774436901641e-02f, 1.393714345522122089e-02f, 1.464436793760017820e-02f, 1.517488254254313260e-02f, 1.558001732315511534e-02f, 1.589461677611720899e-02f, 0.000000000000000000e+00f, 4.050730286239253436e-03f, 9.487235508271726903e-03f, 1.366709854910849904e-02f, 1.666953051899764879e-02f, 1.882431979081320220e-02f, 2.039106305104328165e-02f, 2.154933675325849257e-02f, 2.242064567410862255e-02f, 2.308734523799175001e-02f, 2.360580292793293400e-02f, 0.000000000000000000e+00f, 4.535286937466600360e-03f, 1.134611476159541089e-02f, 1.694721425714761781e-02f, 2.109867955125385372e-02f, 2.412438914252086272e-02f, 2.634309090146036078e-02f, 2.799179615553328698e-02f, 2.923620194935939651e-02f, 3.019059610352927900e-02f, 3.093402180179632283e-02f, 0.000000000000000000e+00f, 4.856764952963409966e-03f, 1.273813200608200392e-02f, 1.958802920526525604e-02f, 2.481999190609950404e-02f, 2.869531045468254674e-02f, 3.156345647461759885e-02f, 3.370696880367917564e-02f, 3.533092542090644078e-02f, 3.657964832387837484e-02f, 3.755415734009321521e-02f, 0.000000000000000000e+00f, 5.076341487001670601e-03f, 1.377588337266780205e-02f, 2.167490906914956716e-02f, 2.787110986356607437e-02f, 3.253221801062159552e-02f, 3.601408854351095812e-02f, 3.863157383647888854e-02f, 4.062237364604340262e-02f, 4.215733831870509957e-02f, 4.335758190036979182e-02f, 0.000000000000000000e+00f, 5.231086483603165568e-03f, 1.455546358066520454e-02f, 2.331654516634287452e-02f, 3.034659890518537698e-02f, 3.570968046632597148e-02f, 3.975117471924284607e-02f, 4.280664993000107138e-02f, 4.513950503188909891e-02f, 4.694305546941619778e-02f, 4.835607691153816223e-02f, 0.000000000000000000e+00f, 5.343398176252857866e-03f, 1.514871634855200627e-02f, 2.461199808645184520e-02f, 3.235060518899594145e-02f, 3.832736202473158160e-02f, 4.286730310131266902e-02f, 4.631777880203825914e-02f, 4.896176865226951197e-02f, 5.101111340104958619e-02f, 5.261972191992605324e-02f, 0.000000000000000000e+00f, 5.427089881340583372e-03f, 1.560689566768099813e-02f, 2.564164045356884594e-02f, 3.397721033727196110e-02f, 4.048372286997169167e-02f, 4.546111243969969823e-02f, 4.926218276911005500e-02f, 5.218451437880067267e-02f, 5.445499338070784040e-02f, 5.624029962279188805e-02f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 8.819928697035788563e-04f, 1.499808675898415189e-03f, 1.908225105418749840e-03f, 2.192393595377619547e-03f, 2.396239154598805640e-03f, 2.545843228278368321e-03f, 2.657792261706820678e-03f, 2.743043405345950078e-03f, 2.809018628625797181e-03f, 2.860843823986314143e-03f, 0.000000000000000000e+00f, 2.309604703834023005e-03f, 4.519723640833095586e-03f, 6.050185724869521636e-03f, 7.129594126592466927e-03f, 7.909145032571158682e-03f, 8.483635400819646358e-03f, 8.914722305197662205e-03f, 9.243647113839898247e-03f, 9.498565711386340940e-03f, 9.699027573244036263e-03f, 0.000000000000000000e+00f, 3.441993626605958489e-03f, 7.621663068032521332e-03f, 1.075187088001746533e-02f, 1.301549353337524799e-02f, 1.466792515089303424e-02f, 1.589275460458437761e-02f, 1.681515189784345277e-02f, 1.752066328498773709e-02f, 1.806838645729005530e-02f, 1.849965608010141135e-02f, 0.000000000000000000e+00f, 4.201738591611474220e-03f, 1.021713787947973323e-02f, 1.511696034060911083e-02f, 1.878711774109946553e-02f, 2.151020004638156888e-02f, 2.354613908580450304e-02f, 2.508729736790969028e-02f, 2.627003716202713779e-02f, 2.719038558162066924e-02f, 2.791626932314798457e-02f, 0.000000000000000000e+00f, 4.696687057928286904e-03f, 1.221429317381030229e-02f, 1.880444680860411319e-02f, 2.393282904286624796e-02f, 2.781434330205767233e-02f, 3.074895459913826179e-02f, 3.298548417575247749e-02f, 3.470945032645365858e-02f, 3.605501455116834342e-02f, 3.711856949032635994e-02f, 0.000000000000000000e+00f, 5.024435445393716539e-03f, 1.370594897871207744e-02f, 2.177985357316791770e-02f, 2.829246297011497879e-02f, 3.332552982113546475e-02f, 3.717851557333125279e-02f, 4.013808584602007734e-02f, 4.243127373289958676e-02f, 4.422757557670908835e-02f, 4.565108540542069104e-02f, 0.000000000000000000e+00f, 5.248035000733364611e-03f, 1.481567994456567047e-02f, 2.413389556736813407e-02f, 3.188929233515737371e-02f, 3.800301313475547976e-02f, 4.274262540563071588e-02f, 4.641334665795533027e-02f, 4.927350398863060421e-02f, 5.152275429342469820e-02f, 5.331031390248602841e-02f, 0.000000000000000000e+00f, 5.405496525820404664e-03f, 1.564801264267183870e-02f, 2.598681309218115604e-02f, 3.482120856979355195e-02f, 4.191118616424213683e-02f, 4.747363860785879658e-02f, 5.181659128966996375e-02f, 5.521960355379183089e-02f, 5.790653639116814105e-02f, 6.004825723819562366e-02f, 0.000000000000000000e+00f, 5.519721114539997281e-03f, 1.628064506019030397e-02f, 2.744943573409894255e-02f, 3.720313374981960158e-02f, 4.515400169935586405e-02f, 5.145999443455393646e-02f, 5.642095558640027736e-02f, 6.032922389709499678e-02f, 6.342720140861805855e-02f, 6.590376215915122460e-02f, 0.000000000000000000e+00f, 5.604807172925481938e-03f, 1.676878494454391022e-02f, 2.861211162654109935e-02f, 3.914175575307056454e-02f, 4.784084480994308525e-02f, 5.480714130841123771e-02f, 6.032558356131666188e-02f, 6.469486252637586532e-02f, 6.817107846412569228e-02f, 7.095772783148365792e-02f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 9.146083830287583642e-04f, 1.579466856061922161e-03f, 2.029488185763906292e-03f, 2.350141314220413613e-03f, 2.585532485783417593e-03f, 2.762039714184235176e-03f, 2.896705517765219007e-03f, 3.001026726814950626e-03f, 3.082973043715643222e-03f, 3.148178209924899686e-03f, 0.000000000000000000e+00f, 2.381923649558957169e-03f, 4.771564976138984587e-03f, 6.477660849154662052e-03f, 7.710637905019568188e-03f, 8.621560397996115566e-03f, 9.307164465156857192e-03f, 9.831533372309179952e-03f, 1.023844968121729107e-02f, 1.055849739339442817e-02f, 1.081340653973560974e-02f, 0.000000000000000000e+00f, 3.535394475345355822e-03f, 8.041696433516517042e-03f, 1.155489757345273122e-02f, 1.417049695167621123e-02f, 1.612711144661847784e-02f, 1.760921674056959568e-02f, 1.874710505678665179e-02f, 1.963233381291838026e-02f, 2.032980615371487304e-02f, 2.088603811178604483e-02f, 0.000000000000000000e+00f, 4.305761889290633283e-03f, 1.076538989099030258e-02f, 1.627663864269695074e-02f, 2.055251087807164270e-02f, 2.381497047720437799e-02f, 2.631238608553041619e-02f, 2.824170594523811931e-02f, 2.974859390027098302e-02f, 3.093907698776395335e-02f, 3.189031186244749294e-02f, 0.000000000000000000e+00f, 4.806493448779084431e-03f, 1.285280603117577684e-02f, 2.026429933233919040e-02f, 2.626995208535578760e-02f, 3.096391948219001308e-02f, 3.460749201784794199e-02f, 3.744638174270890907e-02f, 3.967603736834866834e-02f, 4.144423551014510959e-02f, 4.286092010174952921e-02f, 0.000000000000000000e+00f, 5.137662194585928405e-03f, 1.440720060696200518e-02f, 2.347862141063761232e-02f, 3.112856878432999561e-02f, 3.725816810538268992e-02f, 4.209069272126627487e-02f, 4.589397915749048040e-02f, 4.890130600633454949e-02f, 5.129749328254108037e-02f, 5.322387085040267835e-02f, 0.000000000000000000e+00f, 5.363429462624667160e-03f, 1.556110912888218796e-02f, 2.601869761382172297e-02f, 3.514450605321959437e-02f, 4.262920439588310795e-02f, 4.862302407365758777e-02f, 5.339053744130816542e-02f, 5.718817021170410214e-02f, 6.023003236992537784e-02f, 6.268496109512571024e-02f, 0.000000000000000000e+00f, 5.522343068669122342e-03f, 1.642522820790207408e-02f, 2.801586174906607260e-02f, 3.842179910921796060e-02f, 4.713538023233512786e-02f, 5.421668062745129552e-02f, 5.990809922566721346e-02f, 6.447563789424214098e-02f, 6.815420154092251270e-02f, 7.113509806267460933e-02f, 0.000000000000000000e+00f, 5.637584583779466779e-03f, 1.708127107996294802e-02f, 2.959086256581842239e-02f, 4.108621225472355171e-02f, 5.088622500212632016e-02f, 5.895706762814859753e-02f, 6.550738910549069871e-02f, 7.080215473675173510e-02f, 7.508935702281148428e-02f, 7.857763544664297939e-02f, 0.000000000000000000e+00f, 5.723409014370593739e-03f, 1.758704298274597899e-02f, 3.084188567563100197e-02f, 4.325572603690309298e-02f, 5.400162213255688126e-02f, 6.295602341423879589e-02f, 7.028825445802376615e-02f, 7.625490487763730840e-02f, 8.111082141276432234e-02f, 8.507736160994681940e-02f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 0.000000000000000000e+00f, 9.407175649717369140e-04f, 1.646344177610784259e-03f, 2.133022545851611784e-03f, 2.486368129260723737e-03f, 2.750626368692035174e-03f, 2.952322151141739161e-03f, 3.108750693981697597e-03f, 3.231745439960234754e-03f, 3.329650157514978896e-03f, 3.408471310692032588e-03f, 0.000000000000000000e+00f, 2.435828950196621163e-03f, 4.974727915303407688e-03f, 6.835291369405445752e-03f, 8.206972502698303001e-03f, 9.239229846344653926e-03f, 1.002978347962796626e-02f, 1.064423803298986983e-02f, 1.112808885472833624e-02f, 1.151365936870699970e-02f, 1.182433136920202181e-02f, 0.000000000000000000e+00f, 3.602555256674739963e-03f, 8.368077737178299114e-03f, 1.221054718799924679e-02f, 1.514283600888060091e-02f, 1.738166808092690349e-02f, 1.910867140094551359e-02f, 2.045652908204030271e-02f, 2.152068013770556260e-02f, 2.237019693720150235e-02f, 2.305557241678675082e-02f, 0.000000000000000000e+00f, 4.379251827572607468e-03f, 1.117978193107454360e-02f, 1.720234016040313521e-02f, 2.201620195010858469e-02f, 2.577798151457473541e-02f, 2.871637658705877144e-02f, 3.102661519549590463e-02f, 3.285907988714027728e-02f, 3.432651952566168757e-02f, 3.551303224345320891e-02f, 0.000000000000000000e+00f, 4.883336402690426417e-03f, 1.332632627032051542e-02f, 2.140812375876842075e-02f, 2.818059142001937828e-02f, 3.362163715849737083e-02f, 3.794276055337758580e-02f, 4.137547846997025047e-02f, 4.411681001711743877e-02f, 4.632228985032173924e-02f, 4.811145835127387388e-02f, 0.000000000000000000e+00f, 5.216458452347733261e-03f, 1.492052170740058165e-02f, 2.479039304084246567e-02f, 3.341922235530064150e-02f, 4.054846000436074238e-02f, 4.631490055836424286e-02f, 5.095191227795443922e-02f, 5.468596768919504331e-02f, 5.770784088044408899e-02f, 6.016979812822989548e-02f, 0.000000000000000000e+00f, 5.443452390953965048e-03f, 1.610184242266437388e-02f, 2.745791860035587395e-02f, 3.774735773987216575e-02f, 4.647087682887238863e-02f, 5.365611441928514608e-02f, 5.950828411399150530e-02f, 6.426398211234400637e-02f, 6.813822608265847347e-02f, 7.131020298760183673e-02f, 0.000000000000000000e+00f, 5.603182869318606638e-03f, 1.698537988167880472e-02f, 2.955196761958390692e-02f, 4.127727827674304573e-02f, 5.144592380528976300e-02f, 5.996410190786041067e-02f, 6.698880813872078177e-02f, 7.275015724326128197e-02f, 7.747610674357763294e-02f, 8.136570783515832683e-02f, 0.000000000000000000e+00f, 5.718994165839363757e-03f, 1.765556418075154080e-02f, 3.120130665078258217e-02f, 4.414527445525694149e-02f, 5.559042754703297923e-02f, 6.532404806963165722e-02f, 7.344467067117703418e-02f, 8.016402447511272733e-02f, 8.571334926782668562e-02f, 9.030469447376583692e-02f, 0.000000000000000000e+00f, 5.805231126591313059e-03f, 1.817189858907889560e-02f, 3.251008336421949002e-02f, 4.647919386144636761e-02f, 5.903462270333981188e-02f, 6.985498102082771110e-02f, 7.897742990674293251e-02f, 8.658805699566379799e-02f, 9.291411037656233107e-02f, 9.817477042468102100e-02f}; 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 p0 = (1.f - w) * p00 + w * p10; 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 p1 = (1.f - w) * p01 + w * p11; return (1.f - v) * p0 + v * p1; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/CylinderLight.cpp000066400000000000000000000056751464752671100243060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "CylinderLight.h" #include "common/StructShared.h" #ifndef OSPRAY_TARGET_SYCL #include "lights/CylinderLight_ispc.h" #else namespace ispc { void CylinderLight_Transform(const void *self, const void *xfm, void *dyn); void *CylinderLight_sample_addr(); void *CylinderLight_sample_instanced_addr(); void *CylinderLight_eval_addr(); void *CylinderLight_eval_instanced_addr(); } // namespace ispc #endif #include "CylinderLightShared.h" #include "common/InstanceShared.h" namespace ospray { ispc::Light *CylinderLight::createSh( uint32_t, const ispc::Instance *instance) const { ispc::CylinderLight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast( ispc::CylinderLight_sample_addr()); sh->super.eval = reinterpret_cast(ispc::CylinderLight_eval_addr()); #endif sh->super.isVisible = visible; sh->super.instance = instance; const float zMax = length(position1 - position0); if (zMax <= 0.f || radius <= 0.f) { sh->radiance = 0.f; return &sh->super; } sh->radiance = radiance; sh->radius = radius; sh->pre.position0 = position0; sh->pre.position1 = position1; // Enable dynamic runtime instancing or apply static transformation if (instance) { if (instance->motionBlur) { #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast( ispc::CylinderLight_sample_instanced_addr()); sh->super.eval = reinterpret_cast( ispc::CylinderLight_eval_instanced_addr()); #endif } else ispc::CylinderLight_Transform(sh, instance->xfm, &sh->pre); } return &sh->super; } 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 { postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/CylinderLight.h000066400000000000000000000015321464752671100237370ustar00rootroot00000000000000// Copyright 2009 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(api::ISPCDevice &device) : Light(device, FFO_LIGHT_CYLINDER) {} virtual ~CylinderLight() override = default; virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); vec3f position0{0.f}; // start of the cylinder vec3f position1{0.f, 0.f, 1.f}; // end of the cylinder vec3f radiance{1.0f, 1.0f, 1.0f}; float radius{1.f}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/CylinderLight.ih000066400000000000000000000017501464752671100241120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes CylinderLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_SampleRes CylinderLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes CylinderLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); SYCL_EXTERNAL Light_EvalRes CylinderLight_eval_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/CylinderLight.ispc000066400000000000000000000200521464752671100244440ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "CylinderCapSolidAngleTable.ih" #include "SphericalQuadSampling.ih" #include "common/DifferentialGeometry.ih" #include "common/Instance.ih" #include "common/Intersect.ih" #include "rkcommon/math/AffineSpace.ih" // c++ shared #include "CylinderLightShared.h" // Implementation ////////////////////////////////////////////////////////////////////////////// OSPRAY_BEGIN_ISPC_NAMESPACE inline void Transform(const CylinderLight *uniform self, const uniform affine3f &xfm, uniform CylinderLightDynamic &dyn) { dyn.position0 = xfmPoint(xfm, self->pre.position0); dyn.position1 = xfmPoint(xfm, self->pre.position1); } export void CylinderLight_Transform( const void *uniform self, const void *uniform xfm, void *uniform dyn) { Transform((CylinderLight * uniform) self, *((affine3f * uniform) xfm), *((CylinderLightDynamic * uniform) dyn)); } 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 vec3f n = normalize(cross(e0, e1)); SphericalQuad quad = SphericalQuad_create(q0, e0, e1, 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 CylinderLight *uniform self, const uniform CylinderLightDynamic &dyn, const DifferentialGeometry &dg, const vec2f &sp) { Light_SampleRes res; res.weight = make_vec3f(0.f); res.pdf = 0.f; float S = 0.f; float pdf = 0.f; vec3f dir; if (sp.x == 0.0f && sp.y == 0.0f) { // XXX SciVis dir = 0.5f * (dyn.position0 + dyn.position1) - dg.P; // to center vec3f q0, e0, e1; cylinderComputeRectBounds( dyn.position0, dyn.position1, self->radius, dg.P, q0, e0, e1, S); if (S > 0.f) { pdf = 1.f; } } else { cylinderSampleSolidAngle( dg, sp, dyn.position0, dyn.position1, self->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, dyn.position0, dyn.position1, self->radius); if (isect.entry.hit) { res.pdf = pdf / S; res.weight = self->radiance * rcp(res.pdf); res.dist = isect.entry.t; } return res; } SYCL_EXTERNAL Light_SampleRes CylinderLight_sample( const uniform Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float, const uniform FeatureFlagsHandler &) { const CylinderLight *uniform self = (CylinderLight * uniform) super; assert(self); return Sample(self, self->pre, dg, s); } SYCL_EXTERNAL Light_SampleRes CylinderLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float time, const uniform FeatureFlagsHandler &) { 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); uniform CylinderLightDynamic dyn; Transform(self, xfm, dyn); res = Sample(self, dyn, dg, s); } return res; } inline Light_EvalRes Eval(const CylinderLight *uniform self, const uniform CylinderLightDynamic &dyn, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { Light_EvalRes res; res.radiance = make_vec3f(0.f); // check if intersecting cylinder Intersections isect = intersectCylinder(dg.P, dir, dyn.position0, dyn.position1, self->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( dyn.position0, dyn.position1, self->radius, dg.P, q0, e0, e1, S); if (S > 0.f) { res.radiance = self->radiance; res.pdf = rcp(S); } } } return res; } SYCL_EXTERNAL Light_EvalRes CylinderLight_eval( const uniform Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float) { CylinderLight *uniform self = (CylinderLight * uniform) super; assert(self); return Eval(self, self->pre, dg, dir, minDist, maxDist); } SYCL_EXTERNAL 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); uniform CylinderLightDynamic dyn; Transform(self, xfm, dyn); res = Eval(self, dyn, dg, dir, minDist, maxDist); } return res; } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform CylinderLight_sample_addr() { return (void *uniform)CylinderLight_sample; } #ifndef OSPRAY_TARGET_SYCL export void *uniform CylinderLight_sample_instanced_addr() { return (void *uniform)CylinderLight_sample_instanced; } #endif export void *uniform CylinderLight_eval_addr() { return (void *uniform)CylinderLight_eval; } #ifndef OSPRAY_TARGET_SYCL export void *uniform CylinderLight_eval_instanced_addr() { return (void *uniform)CylinderLight_eval_instanced; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/CylinderLightShared.h000066400000000000000000000012601464752671100250640ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // state that changes under transformations struct CylinderLightDynamic { vec3f position0; vec3f position1; #ifdef __cplusplus CylinderLightDynamic() : position0(0.f), position1(0.f, 0.f, 1.f) {} #endif }; struct CylinderLight { Light super; vec3f radiance; float radius; CylinderLightDynamic pre; // un- or pre-transformed state #ifdef __cplusplus CylinderLight() : radiance(1.f), radius(1.f) { super.type = LIGHT_TYPE_CYLINDER; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/DirectionalLight.cpp000066400000000000000000000062031464752671100247560ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DirectionalLight.h" #include "common/StructShared.h" #include "math/sampling.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "lights/DirectionalLight_ispc.h" #else namespace ispc { void *DirectionalLight_sample_addr(); void *DirectionalLight_sample_instanced_addr(); void *DirectionalLight_eval_addr(); void *DirectionalLight_eval_instanced_addr(); } // namespace ispc #endif // ispc shared #include "DirectionalLightShared.h" #include "common/InstanceShared.h" namespace ispc { void DirectionalLight::set(bool isVisible, const Instance *instance, const vec3f &direction, const vec3f &irradiance, float cosAngle) { super.isVisible = isVisible; super.instance = instance; #ifndef OSPRAY_TARGET_SYCL super.sample = reinterpret_cast( ispc::DirectionalLight_sample_addr()); super.eval = reinterpret_cast( ispc::DirectionalLight_eval_addr()); #endif frame = rkcommon::math::frame(direction); this->irradiance = irradiance; this->cosAngle = cosAngle; pdf = cosAngle < COS_ANGLE_MAX ? ospray::uniformSampleConePDF(cosAngle) : inf; // Enable dynamic runtime instancing or apply static transformation if (instance) { if (instance->motionBlur) { #ifndef OSPRAY_TARGET_SYCL super.sample = reinterpret_cast( ispc::DirectionalLight_sample_instanced_addr()); super.eval = reinterpret_cast( ispc::DirectionalLight_eval_instanced_addr()); #endif } else { frame = instance->xfm.l * frame; } } } } // namespace ispc namespace ospray { ispc::Light *DirectionalLight::createSh( uint32_t, const ispc::Instance *instance) const { ispc::DirectionalLight *sh = StructSharedCreate( getISPCDevice().getDRTDevice()); sh->set(visible, instance, direction, irradiance, cosAngle); return &sh->super; } std::string DirectionalLight::toString() const { return "ospray::DirectionalLight"; } void DirectionalLight::commit() { Light::commit(); direction = getParam("direction", vec3f(0.f, 0.f, 1.f)); angularDiameter = getParam("angularDiameter", .0f); // the ispc::DirLight expects direction towards light source direction = -normalize(direction); angularDiameter = clamp(angularDiameter, 0.f, 180.f); cosAngle = std::cos(deg2rad(0.5f * angularDiameter)); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_IRRADIANCE); processIntensityQuantityType(); } void DirectionalLight::processIntensityQuantityType() { // validate the correctness of the light quantity type if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { // convert from radiance to irradiance float cosineCapIntegral = 2.0f * M_PI * (1.0f - cosAngle); irradiance = cosineCapIntegral * coloredIntensity; } else if (intensityQuantity == OSP_INTENSITY_QUANTITY_IRRADIANCE) { irradiance = coloredIntensity; } else { postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; irradiance = vec3f(0.0f); } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/DirectionalLight.h000066400000000000000000000017531464752671100244300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Light.h" namespace ospray { /*! a DirectionalLight is a singular light which is infinitely distant and * thus projects parallel rays of light across the entire scene */ struct OSPRAY_SDK_INTERFACE DirectionalLight : public Light { DirectionalLight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_DIRECTIONAL) {} virtual ~DirectionalLight() override = default; virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); 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 RenderKit-ospray-85af292/modules/cpu/lights/DirectionalLight.ih000066400000000000000000000017711464752671100246010ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes DirectionalLight_sample( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_SampleRes DirectionalLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes DirectionalLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); SYCL_EXTERNAL Light_EvalRes DirectionalLight_eval_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/DirectionalLight.ispc000066400000000000000000000071461464752671100251410ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/Instance.ih" #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" // c++ shared #include "DirectionalLightShared.h" // Implementation ////////////////////////////////////////////////////////////////////////////// OSPRAY_BEGIN_ISPC_NAMESPACE inline Light_SampleRes Sample(const DirectionalLight *uniform self, const uniform linear3f &frame, const vec2f &s) { Light_SampleRes res; res.dir = frame.vz; res.dist = inf; res.pdf = self->pdf; if (self->cosAngle < COS_ANGLE_MAX) res.dir = frame * uniformSampleCone(self->cosAngle, s); res.weight = self->irradiance; // *pdf/pdf cancel return res; } SYCL_EXTERNAL Light_SampleRes DirectionalLight_sample( const Light *uniform super, const DifferentialGeometry &, const vec2f &s, const float, const uniform FeatureFlagsHandler &) { const DirectionalLight *uniform self = (DirectionalLight * uniform) super; assert(self); return Sample(self, self->frame, s); } SYCL_EXTERNAL Light_SampleRes DirectionalLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &, const vec2f &s, const float time, const uniform FeatureFlagsHandler &) { 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 maxDist) { Light_EvalRes res; res.radiance = make_vec3f(0.f); if ((float)inf <= maxDist && self->cosAngle < COS_ANGLE_MAX && dot(frame.vz, dir) > self->cosAngle) { res.radiance = self->irradiance * self->pdf; res.pdf = self->pdf; } return res; } SYCL_EXTERNAL Light_EvalRes DirectionalLight_eval(const Light *uniform super, const DifferentialGeometry &, const vec3f &dir, const float /*minDist*/, const float maxDist, const float) { const DirectionalLight *uniform self = (DirectionalLight * uniform) super; assert(self); return Eval(self, self->frame, dir, maxDist); } SYCL_EXTERNAL Light_EvalRes DirectionalLight_eval_instanced( const Light *uniform super, const DifferentialGeometry &, const vec3f &dir, const float /*minDist*/, 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++) ////////////////////////////////////////////////////////////////////////////// export void *uniform DirectionalLight_sample_addr() { return (void *uniform)DirectionalLight_sample; } #ifndef OSPRAY_TARGET_SYCL export void *uniform DirectionalLight_sample_instanced_addr() { return (void *uniform)DirectionalLight_sample_instanced; } #endif export void *uniform DirectionalLight_eval_addr() { return (void *uniform)DirectionalLight_eval; } #ifndef OSPRAY_TARGET_SYCL export void *uniform DirectionalLight_eval_instanced_addr() { return (void *uniform)DirectionalLight_eval_instanced; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/DirectionalLightShared.h000066400000000000000000000020761464752671100255560ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // for very small cones treat as singular light, because float precision is not // good enough #define COS_ANGLE_MAX 0.99999988f struct DirectionalLight { Light super; // inherited light fields linear3f frame; // coordinate frame, with vz == direction *towards* the // light source vec3f irradiance; // RGB irradiance contribution of the light float cosAngle; // Angular limit of the cone light in an easier to use form: // cosine of the half angle in radians float pdf; // Probability to sample a direction to the light #ifdef __cplusplus DirectionalLight() : frame(one), irradiance(0.f), cosAngle(1.f), pdf(inf) { super.type = LIGHT_TYPE_DIRECTIONAL; } void set(bool isVisible, const Instance *instance, const vec3f &direction, const vec3f &irradiance, float cosAngle); }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/HDRILight.cpp000066400000000000000000000060551464752671100232540ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "HDRILight.h" #include "common/StructShared.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "lights/HDRILight_ispc.h" #include "lights/Light_ispc.h" #else namespace ispc { void HDRILight_initDistribution(const void *map, void *distribution); } #endif // ispc shared #include "HDRILightShared.h" #include "common/InstanceShared.h" namespace ispc { void HDRILight::set(bool isVisible, const Instance *instance, const vec3f &radianceScale, const linear3f &light2world, const Texture2D *map, const Distribution2D *distribution) { super.isVisible = isVisible; super.instance = instance; #ifndef OSPRAY_TARGET_SYCL super.sample = reinterpret_cast(ispc::HDRILight_sample_addr()); super.eval = reinterpret_cast(ispc::HDRILight_eval_addr()); #endif this->radianceScale = radianceScale; this->map = map; this->distribution = distribution; this->rcpSize = 1.f / this->map->size; this->light2world = light2world; // Enable dynamic runtime instancing or apply static transformation if (instance) { if (instance->motionBlur) { #ifndef OSPRAY_TARGET_SYCL super.sample = reinterpret_cast( ispc::HDRILight_sample_instanced_addr()); super.eval = reinterpret_cast( ispc::HDRILight_eval_instanced_addr()); #endif } else { this->light2world = instance->xfm.l * this->light2world; } } world2light = rcp(this->light2world); } } // namespace ispc namespace ospray { ispc::Light *HDRILight::createSh(uint32_t, const ispc::Instance *instance) const { ispc::HDRILight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); sh->set(visible, instance, coloredIntensity, frame, map->getSh(), distribution->getSh()); return &sh->super; } std::string HDRILight::toString() const { return "ospray::HDRILight"; } void HDRILight::commit() { Light::commit(); 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 = getParamObject("map"); if (!map) throw std::runtime_error(toString() + " must have 'map'"); // recreate distribution distribution = new Distribution2D(map->getSh()->size, getISPCDevice()); distribution->refDec(); // Release extra local ref ispc::HDRILight_initDistribution(map->getSh(), distribution->getSh()); frame.vx = normalize(-dir); frame.vy = normalize(cross(frame.vx, up)); frame.vz = cross(frame.vx, frame.vy); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_SCALE); processIntensityQuantityType(); } void HDRILight::processIntensityQuantityType() { // validate the correctness of the light quantity type if (intensityQuantity != OSP_INTENSITY_QUANTITY_SCALE) { postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; coloredIntensity = vec3f(0.0f); } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/HDRILight.h000066400000000000000000000012621464752671100227140ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Light.h" #include "math/Distribution2D.h" #include "texture/Texture2D.h" namespace ospray { struct OSPRAY_SDK_INTERFACE HDRILight : public Light { HDRILight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_HDRI) {} virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); linear3f frame{one}; // light orientation Ref map; Ref distribution; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/HDRILight.ih000066400000000000000000000017231464752671100230670ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes HDRILight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_SampleRes HDRILight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes HDRILight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); SYCL_EXTERNAL Light_EvalRes HDRILight_eval_instanced(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/HDRILight.ispc000066400000000000000000000162761464752671100234360ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/Instance.ih" #include "math/Distribution1D.ih" #include "math/Distribution2D.ih" #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" #include "texture/Texture2D.ih" // c++ shared #include "HDRILightShared.h" // Implementation ////////////////////////////////////////////////////////////////////////////// OSPRAY_BEGIN_ISPC_NAMESPACE inline Light_SampleRes Sample(const HDRILight *uniform self, const uniform linear3f &light2world, const vec2f &s) { Light_SampleRes res; Sample2D sample2d = Distribution2D_sample(self->distribution, s); // Distribution2D samples within bin i as (i, i+1), whereas we provided // average importance for (i-0.5, i+0.5), thus shift by 0.5 const vec2f halfTexel = rcp(make_vec2f(self->map->size.x, self->map->size.y)) * 0.5f; sample2d.uv = sample2d.uv - halfTexel; const float phi = (float)two_pi * sample2d.uv.x; const float theta = (float)pi * sample2d.uv.y; float sinTheta, cosTheta; sincos(theta, &sinTheta, &cosTheta); const vec3f localDir = cartesian(phi, sinTheta, cosTheta); res.dir = light2world * localDir; res.pdf = sample2d.pdf * (float)one_over_two_pi_sqr * rcp(sinTheta); res.dist = inf; // clamp2edge for theta for tex lookup, to prevent light leaks at the poles sample2d.uv.y = clamp(sample2d.uv.y, halfTexel.y, 1.0f - halfTexel.y); DifferentialGeometry lookup; initDgFromTexCoord(lookup, sample2d.uv); res.weight = get3f(self->map, lookup) * self->radianceScale / res.pdf; return res; } SYCL_EXTERNAL Light_SampleRes HDRILight_sample(const Light *uniform super, const DifferentialGeometry &, const vec2f &s, const float, const uniform FeatureFlagsHandler &) { const HDRILight *uniform self = (HDRILight * uniform) super; assert(self); return Sample(self, self->light2world, s); } SYCL_EXTERNAL Light_SampleRes HDRILight_sample_instanced( const Light *uniform super, const DifferentialGeometry &, const vec2f &s, const float time, const uniform FeatureFlagsHandler &) { 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(const HDRILight *uniform self, const uniform linear3f &world2light, const vec3f &dir, const float maxDist) { Light_EvalRes res; res.radiance = make_vec3f(0.f); if ((float)inf > maxDist) return res; const vec3f localDir = world2light * dir; const float u = atan2(localDir.y, localDir.x) * (float)one_over_two_pi; const float v = acos(clamp(localDir.z, -1.f, 1.f)) * (float)one_over_pi; // clamp2edge for theta for tex lookup, to prevent light leaks at the poles const vec2f halfTexel = rcp(make_vec2f(self->map->size.x, self->map->size.y)) * 0.5f; const vec2f uvc = make_vec2f(u, clamp(v, halfTexel.y, 1.0f - halfTexel.y)); DifferentialGeometry lookup; initDgFromTexCoord(lookup, uvc); res.radiance = get3f(self->map, lookup) * self->radianceScale; // domain of Distribution2D is shifted by half a texel compared to texture vec2f uv = uvc + halfTexel; // atan2 can get negative, shift can lead to values > 1.f: reproject to [0..1) uv.x = frac(uv.x); res.pdf = Distribution2D_pdf(self->distribution, uv); res.pdf *= (float)one_over_two_pi_sqr * rsqrt(1.f - sqr(localDir.z)); return res; } SYCL_EXTERNAL 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); } SYCL_EXTERNAL 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 // not for y (theta), because then light (importance) from the south-pole is // leaking to the north-pole // however, sin(theta) is zero then, thus we will never sample there #ifndef OSPRAY_TARGET_SYCL task #endif unmasked void HDRILight_calcRowImportance(const Texture2D *uniform const map, float *uniform const importance, float *uniform const row_importance #ifdef OSPRAY_TARGET_SYCL , const int taskIndex #endif ) { const uniform int y = taskIndex; const uniform vec2f rcpSize = 1.f / make_vec2f(map->size.x, map->size.y); const uniform float fy = y * rcpSize.y; const uniform int width = map->size.x; const uniform float sinTheta = sin(fy * M_PI); #ifdef OSPRAY_TARGET_SYCL for (int x = 0; x < width; ++x) { #else foreach (x = 0 ... width) { #endif 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(map, lookup); importance[y * width + x] = sinTheta * luminance(col); } row_importance[y] = Distribution1D_create(width, importance + y * width); } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform HDRILight_sample_addr() { return (void *uniform)HDRILight_sample; } #ifndef OSPRAY_TARGET_SYCL export void *uniform HDRILight_sample_instanced_addr() { return (void *uniform)HDRILight_sample_instanced; } #endif export void *uniform HDRILight_eval_addr() { return (void *uniform)HDRILight_eval; } #ifndef OSPRAY_TARGET_SYCL export void *uniform HDRILight_eval_instanced_addr() { return (void *uniform)HDRILight_eval_instanced; } #endif export void HDRILight_initDistribution( const void *uniform _map, void *uniform _distribution) { // calculate importance in parallel const Texture2D *uniform m = (const Texture2D *uniform)_map; Distribution2D *uniform distribution = (Distribution2D * uniform) _distribution; const uniform int height = m->size.y; float *uniform cdf_x = distribution->cdf_x; float *uniform row_importance = distribution->cdf_y; #ifdef OSPRAY_TARGET_SYCL // TODO: Should become a kernel launch in SYCL for (int i = 0; i < height; ++i) { HDRILight_calcRowImportance(m, cdf_x, row_importance, i); } #else launch[height] HDRILight_calcRowImportance(m, cdf_x, row_importance); sync; #endif // Initialize the distribution with the computed cdf/f values Distribution2D_init(distribution); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/HDRILightShared.h000066400000000000000000000020421464752671100240400ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Texture2D; struct Distribution2D; struct HDRILight { Light super; linear3f light2world; linear3f world2light; const Texture2D *map; // Environment map in latitude / longitude format const Distribution2D *distribution; // The 2D distribution used to importance sample vec2f rcpSize; // precomputed 1/map.size vec3f radianceScale; // scaling factor of emitted RGB radiance #ifdef __cplusplus HDRILight() : light2world(one), world2light(one), map(nullptr), distribution(nullptr), rcpSize(0.f), radianceScale(1.f) { super.type = LIGHT_TYPE_HDRI; } void set(bool isVisible, const Instance *instance, const vec3f &radianceScale, const linear3f &light2world, const Texture2D *map, const Distribution2D *distribution); }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/IntensityDistribution.cpp000066400000000000000000000026041464752671100261200ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "IntensityDistribution.h" #include "IntensityDistributionShared.h" namespace ospray { void IntensityDistribution::readParams(ISPCDeviceObject &obj) { c0 = obj.getParam("c0", c0); lid = obj.getParamDataT("intensityDistribution"); if (lid) { if (lid->numItems.z > 1) throw std::runtime_error(obj.toString() + " must have (at most 2D) 'intensityDistribution' array using the first two dimensions."); size = vec2i(lid->numItems.x, lid->numItems.y); if (size.x < 2) throw std::runtime_error(obj.toString() + " 'intensityDistribution' must have data for at least two gamma angles."); if (!lid->compact()) { postStatusMsg(OSP_LOG_WARNING) << obj.toString() << " does currently not support strides for 'intensityDistribution', copying data."; const auto data = new Data(obj.getISPCDevice(), OSP_FLOAT, lid->numItems); data->copy(*lid, vec3ui(0)); lid = &(data->as()); data->refDec(); } } } void IntensityDistribution::setSh(ispc::IntensityDistribution &sh) const { sh.lid = lid ? lid->data() : nullptr; sh.size = size; sh.scale.x = nextafter(float(size.x - 1) * float(one_over_pi), -1.0f); sh.scale.y = nextafter(float(size.y) * float(one_over_two_pi), -1.0f); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/IntensityDistribution.h000066400000000000000000000010211464752671100255550ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/Data.h" namespace ispc { struct IntensityDistribution; } namespace ospray { struct OSPRAY_SDK_INTERFACE IntensityDistribution { void readParams(ISPCDeviceObject &); operator bool() const { return lid; } void setSh(ispc::IntensityDistribution &sh) const; vec2i size{0}; vec3f c0{1.f, 0.f, 0.f}; private: Ref> lid; // luminous intensity distribution }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/IntensityDistribution.ih000066400000000000000000000023571464752671100257430ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" // c++ shared #include "IntensityDistributionShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline float IntensityDistribution_eval( const IntensityDistribution *uniform self, const uniform vec3f &c0, const uniform vec3f &c90, float cosAngle, const vec3f &dir /*normalized*/) { const float u = acos(clamp(cosAngle, -1.f, 1.f)) * 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; float intensity; if (self->size.y == 1) { // 1D intensity = lerp(u_frac, self->lid[u0], self->lid[u1]); } else { // 2D const float v = (atan2(dot(dir, c90), dot(dir, c0)) + (float)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; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/IntensityDistributionShared.h000066400000000000000000000006161464752671100267150ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct IntensityDistribution { float *lid; // luminance intensity distribution vec2i size; vec2f scale; #ifdef __cplusplus IntensityDistribution() : lid{nullptr}, size(0), scale(1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/Light.cpp000066400000000000000000000016121464752671100225770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Light.h" #ifndef OSPRAY_TARGET_SYCL #include "lights/Light_ispc.h" #endif namespace ospray { // Light definitions ////////////////////////////////////////////////////////// Light::Light(api::ISPCDevice &device, const FeatureFlagsOther ffo) : ISPCDeviceObject(device), featureFlags(ffo) { managedObjectType = OSP_LIGHT; } void Light::commit() { visible = getParam("visible", true); coloredIntensity = getParam("color", vec3f(1.f)) * getParam("intensity", 1.f); } std::string Light::toString() const { return "ospray::Light"; } void Light::queryIntensityQuantityType(const OSPIntensityQuantity &defaultIQ) { intensityQuantity = (OSPIntensityQuantity)getParam("intensityQuantity", defaultIQ); } OSPTYPEFOR_DEFINITION(Light *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/Light.h000066400000000000000000000025721464752671100222520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDeviceObject.h" #include "common/FeatureFlagsEnum.h" #include "common/ObjectFactory.h" namespace ispc { struct Light; struct Instance; } // namespace ispc namespace ospray { //! Base class for Light objects struct OSPRAY_SDK_INTERFACE Light : public ISPCDeviceObject, public ObjectFactory { Light(api::ISPCDevice &device, const FeatureFlagsOther ffo); virtual ~Light() override = default; virtual uint32_t getShCount() const; virtual ispc::Light *createSh( uint32_t index, const ispc::Instance *instance = nullptr) const = 0; virtual void commit() override; virtual std::string toString() const override; bool visible{true}; vec3f coloredIntensity{1.0f, 1.0f, 1.0f}; OSPIntensityQuantity intensityQuantity = OSP_INTENSITY_QUANTITY_UNKNOWN; FeatureFlags getFeatureFlags() const; protected: FeatureFlagsOther featureFlags; void queryIntensityQuantityType(const OSPIntensityQuantity &defaultIQ); }; OSPTYPEFOR_SPECIALIZATION(Light *, OSP_LIGHT); // Inlined definitions ///////////////////////////////////////////////////////// inline uint32_t Light::getShCount() const { return 1; } inline FeatureFlags Light::getFeatureFlags() const { FeatureFlags ff; ff.other = featureFlags; return ff; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/Light.ispc000066400000000000000000000011631464752671100227540ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DifferentialGeometry.ih" // c++ shared #include "LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE Light_EvalRes Light_eval(const Light *uniform, const DifferentialGeometry &, const vec3f &, const float, const float, const float) { Light_EvalRes res; res.radiance = make_vec3f(0.f); return res; } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform Light_eval_addr() { return (void *uniform)Light_eval; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/LightDispatch.ih000066400000000000000000000027771464752671100241120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "common/OSPCommon.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE struct Light; struct DifferentialGeometry; // compute the weighted radiance at a point caused by a sample on the light // source // 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) SYCL_EXTERNAL __noinline Light_SampleRes Light_dispatch_sample( 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, // generate the sample at time (motion blur) const uniform FeatureFlagsHandler &ffh); //! compute the radiance and pdf caused by the light source (pointed to by the //! given direction up until maxDist) SYCL_EXTERNAL __noinline Light_EvalRes Light_dispatch_eval( 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, // evaluate at time (motion blur) const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/LightDispatch.ispc000066400000000000000000000131331464752671100244340ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DifferentialGeometry.ih" #include "common/FeatureFlagsEnum.h" #include "common/Instance.ih" #include "lights/LightDispatch.ih" #include "lights/LightShared.h" #include "lights/AmbientLight.ih" #include "lights/CylinderLight.ih" #include "lights/DirectionalLight.ih" #include "lights/HDRILight.ih" #include "lights/PointLight.ih" #include "lights/QuadLight.ih" #include "lights/SpotLight.ih" #include "render/pathtracer/GeometryLight.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL __noinline Light_SampleRes Light_dispatch_sample( const Light *uniform self, const DifferentialGeometry &dg, const vec2f &s, const float time, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); #ifndef OSPRAY_TARGET_SYCL return self->sample(self, dg, s, time, ffh); #else if ((self->type == LIGHT_TYPE_AMBIENT) && (ffo & FFO_LIGHT_AMBIENT)) { return AmbientLight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_DIRECTIONAL) && (ffo & FFO_LIGHT_DIRECTIONAL)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return DirectionalLight_sample_instanced(self, dg, s, time, ffh); else return DirectionalLight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_POINT) && (ffo & FFO_LIGHT_POINT)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return PointLight_sample_instanced(self, dg, s, time, ffh); else return PointLight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_SPOT) && (ffo & FFO_LIGHT_SPOT)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return SpotLight_sample_instanced(self, dg, s, time, ffh); else return SpotLight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_HDRI) && (ffo & FFO_LIGHT_HDRI)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return HDRILight_sample_instanced(self, dg, s, time, ffh); else return HDRILight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_QUAD) && (ffo & FFO_LIGHT_QUAD)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return QuadLight_sample_instanced(self, dg, s, time, ffh); else return QuadLight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_CYLINDER) && (ffo & FFO_LIGHT_CYLINDER)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return CylinderLight_sample_instanced(self, dg, s, time, ffh); else return CylinderLight_sample(self, dg, s, time, ffh); } else if ((self->type == LIGHT_TYPE_GEOMETRY) && (ffo & FFO_LIGHT_GEOMETRY)) { return GeometryLight_sample(self, dg, s, time, ffh); } else { Light_SampleRes res; res.weight = make_vec3f(0.f); res.dir = make_vec3f(0.f); res.dist = inf; res.pdf = 0.f; return res; } #endif } SYCL_EXTERNAL __noinline Light_EvalRes Light_dispatch_eval( const Light *uniform self, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); #ifndef OSPRAY_TARGET_SYCL return self->eval(self, dg, dir, minDist, maxDist, time); #else if ((self->type == LIGHT_TYPE_AMBIENT) && (ffo & FFO_LIGHT_AMBIENT)) { return AmbientLight_eval(self, dg, dir, minDist, maxDist, time); } else if ((self->type == LIGHT_TYPE_DIRECTIONAL) && (ffo & FFO_LIGHT_DIRECTIONAL)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return DirectionalLight_eval_instanced( self, dg, dir, minDist, maxDist, time); else return DirectionalLight_eval(self, dg, dir, minDist, maxDist, time); } else if ((self->type == LIGHT_TYPE_POINT) && (ffo & FFO_LIGHT_POINT)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return PointLight_eval_instanced(self, dg, dir, minDist, maxDist, time); else return PointLight_eval(self, dg, dir, minDist, maxDist, time); } else if ((self->type == LIGHT_TYPE_SPOT) && (ffo & FFO_LIGHT_SPOT)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return SpotLight_eval_instanced(self, dg, dir, minDist, maxDist, time); else return SpotLight_eval(self, dg, dir, minDist, maxDist, time); } else if ((self->type == LIGHT_TYPE_HDRI) && (ffo & FFO_LIGHT_HDRI)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return HDRILight_eval_instanced(self, dg, dir, minDist, maxDist, time); else return HDRILight_eval(self, dg, dir, minDist, maxDist, time); } else if ((self->type == LIGHT_TYPE_QUAD) && (ffo & FFO_LIGHT_QUAD)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return QuadLight_eval_instanced(self, dg, dir, minDist, maxDist, time); else return QuadLight_eval(self, dg, dir, minDist, maxDist, time); } else if ((self->type == LIGHT_TYPE_CYLINDER) && (ffo & FFO_LIGHT_CYLINDER)) { if (self->instance->motionBlur && (ffg & FFG_MOTION_BLUR)) return CylinderLight_eval_instanced( self, dg, dir, minDist, maxDist, time); else return CylinderLight_eval(self, dg, dir, minDist, maxDist, time); } else { Light_EvalRes res; res.radiance = make_vec3f(0.f); res.pdf = 0.f; return res; } #endif } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/LightShared.h000066400000000000000000000053331464752671100233770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #if defined(ISPC) || defined(OSPRAY_TARGET_SYCL) #include "common/FeatureFlags.ih" #endif #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *Light_SampleFunc; typedef void *Light_EvalFunc; #else struct Light; struct DifferentialGeometry; struct Light_SampleRes { vec3f weight; // radiance that arrives at the given point divided by pdf vec3f dir; // direction towards the light source, normalized float dist; // largest valid t_far value for a shadow ray, including epsilon // to avoid self-intersection float pdf; // probability density that this sample was taken }; // compute the weighted radiance at a point caused by a sample on the light // source // 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 Light *uniform self, const DifferentialGeometry &dg, // point (&normal) to generate the sample const vec2f &s, // random numbers to generate the sample const float time, // generate the sample at time (motion blur) const uniform FeatureFlagsHandler &ffh); struct Light_EvalRes { vec3f radiance; // radiance that arrives at the given point (not weighted by // pdf) float pdf; // probability density that the direction would have been sampled }; //! 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 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); // evaluate at time (motion blur) #endif struct Instance; enum LightType { LIGHT_TYPE_AMBIENT, LIGHT_TYPE_CYLINDER, LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_HDRI, LIGHT_TYPE_POINT, LIGHT_TYPE_QUAD, LIGHT_TYPE_SPOT, LIGHT_TYPE_GEOMETRY, LIGHT_TYPE_UNKNOWN, }; struct Light { LightType type; Light_SampleFunc sample; Light_EvalFunc eval; bool isVisible; // either directly in camera, or via a straight path (i.e. // through ThinGlass) const Instance *instance; #ifdef __cplusplus Light() : type(LIGHT_TYPE_UNKNOWN), sample(nullptr), eval(nullptr), isVisible(true), instance(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/PointLight.cpp000066400000000000000000000075531464752671100236230ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "PointLight.h" #ifndef OSPRAY_TARGET_SYCL #include "lights/PointLight_ispc.h" #else namespace ispc { void PointLight_Transform(const void *self, const void *xfm, void *dyn); void *PointLight_sample_addr(); void *PointLight_sample_instanced_addr(); void *PointLight_eval_addr(); void *PointLight_eval_instanced_addr(); } // namespace ispc #endif #include "PointLightShared.h" #include "common/InstanceShared.h" namespace ospray { ispc::Light *PointLight::createSh( uint32_t, const ispc::Instance *instance) const { ispc::PointLight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); sh->super.isVisible = visible; sh->super.instance = instance; #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast(ispc::PointLight_sample_addr()); sh->super.eval = reinterpret_cast(ispc::PointLight_eval_addr()); #endif sh->radiance = radiance; sh->intensity = radIntensity; sh->radius = radius; sh->pre.position = position; sh->pre.direction = normalize(direction); intensityDistribution.setSh(sh->intensityDistribution); // Enable dynamic runtime instancing or apply static transformation if (instance) { sh->pre.c0 = intensityDistribution.c0; if (instance->motionBlur) { #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast( ispc::PointLight_sample_instanced_addr()); sh->super.eval = reinterpret_cast( ispc::PointLight_eval_instanced_addr()); #endif } else ispc::PointLight_Transform(sh, instance->xfm, &sh->pre); } else { sh->pre.c90 = normalize(cross(intensityDistribution.c0, sh->pre.direction)); sh->pre.c0 = cross(sh->pre.direction, sh->pre.c90); } return &sh->super; } std::string PointLight::toString() const { return "ospray::PointLight"; } void PointLight::commit() { Light::commit(); position = getParam("position", vec3f(0.f)); radius = getParam("radius", 0.f); // per default perpendicular to direction direction = getParam("direction", vec3f(0.f, 0.f, 1.f)); intensityDistribution.c0 = std::abs(direction.x) < std::abs(direction.y) ? vec3f(0.0f, direction.z, direction.y) : vec3f(direction.z, 0.0f, direction.x); intensityDistribution.readParams(*this); queryIntensityQuantityType(intensityDistribution ? OSP_INTENSITY_QUANTITY_SCALE : OSP_INTENSITY_QUANTITY_INTENSITY); processIntensityQuantityType(); } void PointLight::processIntensityQuantityType() { radIntensity = 0.0f; radiance = 0.0f; const float sphereArea = 4.0f * M_PI * radius * radius; // converting from the chosen intensity quantity type to radiance // (for r > 0) or radiative intensity (r = 0) if (intensityDistribution ? intensityQuantity == OSP_INTENSITY_QUANTITY_SCALE : intensityQuantity == OSP_INTENSITY_QUANTITY_INTENSITY) { radIntensity = coloredIntensity; if (radius > 0.0f) { // the visible surface are of a sphere in one direction is equal // to the surface area of a disk oriented to this direction radiance = coloredIntensity / (sphereArea / 4.0f); } return; } if (!intensityDistribution) { if (intensityQuantity == OSP_INTENSITY_QUANTITY_POWER) { radIntensity = coloredIntensity / (4.0f * M_PI); if (radius > 0.0f) radiance = coloredIntensity / (M_PI * sphereArea); return; } if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { // a virtual point light has no surface area therefore // radIntensity stays zero if (radius > 0.0f) radiance = coloredIntensity; return; } } postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/PointLight.h000066400000000000000000000017251464752671100232630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "IntensityDistribution.h" #include "Light.h" namespace ospray { //! a PointLight is a singular light emitting from a point uniformly into all //! directions struct OSPRAY_SDK_INTERFACE PointLight : public Light { PointLight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_POINT) {} virtual ~PointLight() override = default; virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); vec3f position{0.f}; //!< world-space position of the light float radius{0.f}; //!< Radius of SphereLight vec3f radiance{1.f}; //!< emitted radiance of the SphereLight vec3f radIntensity{0.f}; IntensityDistribution intensityDistribution; vec3f direction{0.f, 0.f, 1.f}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/PointLight.ih000066400000000000000000000017341464752671100234340ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes PointLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_SampleRes PointLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes PointLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); SYCL_EXTERNAL Light_EvalRes PointLight_eval_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/PointLight.ispc000066400000000000000000000145721464752671100237760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "IntensityDistribution.ih" #include "common/Instance.ih" #include "common/Intersect.ih" #include "common/Ray.ih" #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" // c++ shared #include "PointLightShared.h" // Implementation ////////////////////////////////////////////////////////////////////////////// OSPRAY_BEGIN_ISPC_NAMESPACE inline void Transform(const PointLight *uniform self, const uniform affine3f &xfm, uniform PointLightDynamic &dyn) { dyn.position = xfmPoint(xfm, self->pre.position); if (self->intensityDistribution.lid) { dyn.direction = normalize(xfmVector(xfm, self->pre.direction)); dyn.c90 = normalize(cross(xfmVector(xfm, self->pre.c0), dyn.direction)); dyn.c0 = cross(dyn.direction, dyn.c90); } } export void PointLight_Transform( const void *uniform self, const void *uniform xfm, void *uniform dyn) { Transform((PointLight * uniform) self, *((affine3f * uniform) xfm), *((PointLightDynamic * uniform) dyn)); } inline Light_SampleRes Sample(const PointLight *uniform self, const uniform PointLightDynamic &dyn, const DifferentialGeometry &dg, const vec2f &s) { Light_SampleRes res; // extant light vector from the hit point const vec3f dir = dyn.position - dg.P; const float dist2 = dot(dir, dir); const float invdist = rsqrt(dist2); // normalized light vector res.dir = dir * invdist; res.dist = dist2 * invdist; res.pdf = inf; // per default we always take this sample const float sinTheta = self->radius * invdist; if ((self->radius > 0.f) & (sinTheta > 0.005f)) { // sample surface of sphere as seen by hit point -> cone of directions // for very small cones treat as point light, because float precision is not // good enough if (sinTheta < 1.f) { const float cosTheta = sqrt(1.f - sinTheta * sinTheta); const vec3f localDir = uniformSampleCone(cosTheta, s); res.dir = frame(res.dir) * localDir; res.pdf = uniformSampleConePDF(cosTheta); const float c = localDir.z; res.dist = c * res.dist - sqrt_safe(sqr(self->radius) - (1.f - c * c) * dist2); // note the sampling PDF is already in solid angle therefore, we do not // need to divide it by the squared distance res.weight = self->radiance / res.pdf; } else { // emit only from the surface to the outside res.weight = make_vec3f(0.f); } } else { // convert from intensity to radiance by attenuating by distance^2 res.weight = self->intensity * sqr(invdist); } if (self->intensityDistribution.lid) { const float cosd = -dot(dyn.direction, res.dir); res.weight = res.weight * IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosd, res.dir); } return res; } SYCL_EXTERNAL Light_SampleRes PointLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float, const uniform FeatureFlagsHandler &) { const PointLight *uniform self = (PointLight * uniform) super; assert(self); return Sample(self, self->pre, dg, s); } SYCL_EXTERNAL Light_SampleRes PointLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float time, const uniform FeatureFlagsHandler &) { 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); uniform PointLightDynamic dyn; Transform(self, xfm, dyn); res = Sample(self, dyn, dg, s); } return res; } inline Light_EvalRes Eval(const PointLight *uniform self, const uniform PointLightDynamic &dyn, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { Light_EvalRes res; res.radiance = make_vec3f(0.f); const vec3f A = dyn.position - dg.P; const float centerDist2 = dot(A, A); const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); if (self->radius > 0.f && sqrt(sinTheta2) > 0.005f) { const Intersections isect = intersectSphere(dg.P, dir, dyn.position, self->radius); if (isect.entry.hit && isect.entry.t > minDist && isect.entry.t < maxDist) { const float cosTheta = sqrt(1.f - sinTheta2); res.pdf = uniformSampleConePDF(cosTheta); res.radiance = self->radiance; if (self->intensityDistribution.lid) { const float cosAngle = -dot(dyn.direction, dir); res.radiance = res.radiance * IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosAngle, dir); } } } return res; } SYCL_EXTERNAL 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->pre, dg, dir, minDist, maxDist); } SYCL_EXTERNAL 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); uniform PointLightDynamic dyn; Transform(self, xfm, dyn); res = Eval(self, dyn, dg, dir, minDist, maxDist); } return res; } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform PointLight_sample_addr() { return (void *uniform)PointLight_sample; } #ifndef OSPRAY_TARGET_SYCL export void *uniform PointLight_sample_instanced_addr() { return (void *uniform)PointLight_sample_instanced; } #endif export void *uniform PointLight_eval_addr() { return (void *uniform)PointLight_eval; } #ifndef OSPRAY_TARGET_SYCL export void *uniform PointLight_eval_instanced_addr() { return (void *uniform)PointLight_eval_instanced; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/PointLightShared.h000066400000000000000000000020631464752671100244060ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "IntensityDistributionShared.h" #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // state that changes under transformations struct PointLightDynamic { vec3f position; vec3f direction; vec3f c0; // orientation for intensityDistribution: direction of the C0- vec3f c90; // and the C90-(half)plane #ifdef __cplusplus PointLightDynamic() : position(0.f), direction(0.f, 0.f, 1.f), c0(1.f, 0.f, 0.f), c90(0.f, 1.f, 0.f) {} #endif }; struct PointLight { Light super; vec3f intensity; // RGB color and intensity of light vec3f radiance; // emitted RGB radiance float radius; // defines the size of the SphereLight IntensityDistribution intensityDistribution; PointLightDynamic pre; // un- or pre-transformed state #ifdef __cplusplus PointLight() : intensity(1.f), radiance(1.f), radius(0.f) { super.type = LIGHT_TYPE_POINT; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/QuadLight.cpp000066400000000000000000000063341464752671100234200ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "QuadLight.h" #ifndef OSPRAY_TARGET_SYCL #include "lights/QuadLight_ispc.h" #else namespace ispc { void QuadLight_Transform(const void *self, const void *xfm, void *dyn); } #endif #include "QuadLightShared.h" #include "common/InstanceShared.h" namespace ospray { ispc::Light *QuadLight::createSh(uint32_t, const ispc::Instance *instance) const { ispc::QuadLight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast(ispc::QuadLight_sample_addr()); sh->super.eval = reinterpret_cast(ispc::QuadLight_eval_addr()); #endif sh->super.isVisible = visible; sh->super.instance = instance; sh->radiance = radiance; sh->pre.position = position; sh->pre.edge1 = edge1; sh->pre.edge2 = edge2; intensityDistribution.setSh(sh->intensityDistribution); // Enable dynamic runtime instancing or apply static transformation if (instance) { sh->pre.c0 = intensityDistribution.c0; if (instance->motionBlur) { #ifndef OSPRAY_TARGET_SYCL // TODO: QuadLight sample/eval dispatch needs to handle this case now sh->super.sample = reinterpret_cast( ispc::QuadLight_sample_instanced_addr()); sh->super.eval = reinterpret_cast( ispc::QuadLight_eval_instanced_addr()); #endif } else ispc::QuadLight_Transform(sh, instance->xfm, &sh->pre); } else { const vec3f ndirection = cross(edge2, edge1); sh->pre.ppdf = rcp(length(ndirection)); // 1/area sh->pre.nnormal = ndirection * sh->pre.ppdf; // normalize sh->pre.c90 = normalize(cross(sh->pre.nnormal, intensityDistribution.c0)); sh->pre.c0 = cross(sh->pre.c90, sh->pre.nnormal); } return &sh->super; } std::string QuadLight::toString() const { return "ospray::QuadLight"; } void QuadLight::commit() { Light::commit(); position = getParam("position", vec3f(0.f)); edge1 = getParam("edge1", vec3f(1.f, 0.f, 0.f)); edge2 = getParam("edge2", vec3f(0.f, 1.f, 0.f)); intensityDistribution.c0 = edge2; intensityDistribution.readParams(*this); queryIntensityQuantityType(intensityDistribution ? OSP_INTENSITY_QUANTITY_SCALE : OSP_INTENSITY_QUANTITY_RADIANCE); processIntensityQuantityType(); } void QuadLight::processIntensityQuantityType() { const float quadArea = length(cross(edge1, edge2)); // converting from the chosen intensity quantity type to radiance if (intensityDistribution ? intensityQuantity == OSP_INTENSITY_QUANTITY_SCALE : intensityQuantity == OSP_INTENSITY_QUANTITY_INTENSITY) { radiance = coloredIntensity / quadArea; return; } if (!intensityDistribution) { if (intensityQuantity == OSP_INTENSITY_QUANTITY_POWER) { radiance = coloredIntensity / (M_PI * quadArea); return; } if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { radiance = coloredIntensity; return; } } postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; radiance = vec3f(0.0f); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/QuadLight.h000066400000000000000000000020001464752671100230470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "IntensityDistribution.h" #include "Light.h" namespace ospray { /*! a QuadLight is a virtual area light uniformly emitting from a rectangular * area into the positive half space */ struct OSPRAY_SDK_INTERFACE QuadLight : public Light { QuadLight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_QUAD) {} virtual ~QuadLight() override = default; virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); 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.f}; //!< emitted radiance of the QuadLight IntensityDistribution intensityDistribution; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/QuadLight.ih000066400000000000000000000017231464752671100232330ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes QuadLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_SampleRes QuadLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes QuadLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); SYCL_EXTERNAL Light_EvalRes QuadLight_eval_instanced(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/QuadLight.ispc000066400000000000000000000177711464752671100236030ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "IntensityDistribution.ih" #include "SphericalQuadSampling.ih" #include "common/DifferentialGeometry.ih" #include "common/Instance.ih" // c++ shared #include "QuadLightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // Implementation ////////////////////////////////////////////////////////////////////////////// inline void Transform(const QuadLight *uniform self, const uniform affine3f &xfm, uniform QuadLightDynamic &dyn) { // transform light into the world space dyn.position = xfmPoint(xfm, self->pre.position); dyn.edge1 = xfmVector(xfm, self->pre.edge1); dyn.edge2 = xfmVector(xfm, self->pre.edge2); // calculate quad normal vector const uniform vec3f ndirection = cross(dyn.edge2, dyn.edge1); dyn.ppdf = rcp(length(ndirection)); // 1/area dyn.nnormal = ndirection * dyn.ppdf; // normalize if (self->intensityDistribution.lid) { dyn.c90 = normalize(cross(dyn.nnormal, xfmVector(xfm, self->pre.c0))); dyn.c0 = cross(dyn.c90, dyn.nnormal); } } export void QuadLight_Transform( const void *uniform self, const void *uniform xfm, void *uniform dyn) { Transform((QuadLight * uniform) self, *((affine3f * uniform) xfm), *((QuadLightDynamic * uniform) dyn)); } inline Light_SampleRes SampleArea(const QuadLight *uniform self, const uniform QuadLightDynamic &dyn, const DifferentialGeometry &dg, const vec2f &s) { Light_SampleRes res; const vec3f p = dyn.position + dyn.edge1 * s.x + dyn.edge2 * s.y; // extant light vector from the hit point const vec3f dir = p - dg.P; const float dist = length(dir); // normalized light vector res.dir = dir / dist; res.dist = dist; // convert to pdf wrt. solid angle const float cosd = dot(dyn.nnormal, res.dir); res.pdf = dyn.ppdf * sqr(dist) / abs(cosd); float weight; if (self->intensityDistribution.lid) { weight = IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosd, res.dir); // 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. weight /= dyn.ppdf * sqr(dist); } else { // emit only to one side weight = cosd > 0.f ? rcp(res.pdf) : 0.f; } res.weight = self->radiance * weight; return res; } inline Light_SampleRes Sample(const QuadLight *uniform self, const uniform QuadLightDynamic &dyn, const DifferentialGeometry &dg, const vec2f &s) { Light_SampleRes res; if (s.x == 0.0f && s.y == 0.0f) { // XXX SciVis vec2f ss = make_vec2f(0.5f); return SampleArea(self, dyn, dg, ss); } // create spherical quad for solid angle sampling SphericalQuad quad = SphericalQuad_create( dyn.position, dyn.edge1, dyn.edge2, neg(dyn.nnormal), dg.P); // bilinear warped cosine weight approximation const vec3f cosW = computeCosineWeightedRNG( dyn.position, dyn.edge1, dyn.edge2, dg.P, dg.Ng, s); // sample quad const vec3f dir = sampleSphericalQuad(quad, make_vec2f(cosW.x, cosW.y)); const float dist = length(dir); // normalized light vector res.dir = dir / dist; res.dist = dist; // convert to pdf wrt. solid angle const float cosd = dot(dyn.nnormal, res.dir); res.pdf = quad.S == 0.f ? 0.f : cosW.z / quad.S; if (self->intensityDistribution.lid) { if (abs(cosd) < 0.005f) // handle numerical edge case return SampleArea(self, dyn, dg, s); else { float weight = IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosd, res.dir); // 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. weight /= abs(cosd) * res.pdf; res.weight = res.pdf != 0.f ? self->radiance * weight : make_vec3f(0.f); } } else { // emit only to one side res.weight = (cosd > 0.f) && (res.pdf != 0.f) ? self->radiance * rcp(res.pdf) : make_vec3f(0.f); } return res; } SYCL_EXTERNAL Light_SampleRes QuadLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &) { const QuadLight *uniform self = (QuadLight * uniform) super; assert(self); return Sample(self, self->pre, dg, sp); } SYCL_EXTERNAL Light_SampleRes QuadLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &) { 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); uniform QuadLightDynamic dyn; Transform(self, xfm, dyn); res = Sample(self, dyn, dg, sp); } return res; } inline Light_EvalRes Eval(const QuadLight *uniform self, const uniform QuadLightDynamic &dyn, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { Light_EvalRes res; res.radiance = make_vec3f(0.f); // backfacing? const float cosd = dot(dyn.nnormal, dir); // denominator = dot(cross(edge1, edge2), dir) == cosd/ppdf if (cosd <= 0.f && !self->intensityDistribution.lid) return res; const vec3f c = dyn.position - dg.P; const vec3f r = cross(c, dir); const float rcosd = rcp(cosd); const float u = dot(r, dyn.edge1) * rcosd; const float v = -dot(r, dyn.edge2) * rcosd; // u/denominator > 1? if (min(u, v) < 0.f || max(u, v) * dyn.ppdf > 1.0f) return res; const float dist = dot(dyn.nnormal, c) * rcosd; if (dist <= minDist || dist > maxDist) return res; SphericalQuad quad = SphericalQuad_create( dyn.position, dyn.edge1, dyn.edge2, neg(dyn.nnormal), dg.P); if (quad.S > 0.f) { res.radiance = self->radiance; if (self->intensityDistribution.lid) { // convert from intensity to radiance by canceling the the cosine // term introduced by the Lambertian area light res.radiance = res.radiance * (IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosd, dir) / abs(cosd)); } res.pdf = rcp(quad.S); } return res; } SYCL_EXTERNAL 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->pre, dg, dir, minDist, maxDist); } SYCL_EXTERNAL 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); uniform QuadLightDynamic dyn; Transform(self, xfm, dyn); res = Eval(self, dyn, dg, dir, minDist, maxDist); } return res; } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform QuadLight_sample_addr() { return (void *uniform)QuadLight_sample; } #ifndef OSPRAY_TARGET_SYCL export void *uniform QuadLight_sample_instanced_addr() { return (void *uniform)QuadLight_sample_instanced; } #endif export void *uniform QuadLight_eval_addr() { return (void *uniform)QuadLight_eval; } #ifndef OSPRAY_TARGET_SYCL export void *uniform QuadLight_eval_instanced_addr() { return (void *uniform)QuadLight_eval_instanced; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/QuadLightShared.h000066400000000000000000000022571464752671100242140ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "IntensityDistributionShared.h" #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // state that changes under transformations struct QuadLightDynamic { vec3f position; vec3f edge1; vec3f edge2; vec3f nnormal; // negated normal, the direction that the QuadLight is not // emitting; normalized float ppdf; // probability to sample point on light = 1/area vec3f c0; // orientation for intensityDistribution: direction of the C0- vec3f c90; // and the C90-(half)plane #ifdef __cplusplus QuadLightDynamic() : position(0.f), edge1(1.f, 0.f, 0.f), edge2(0.f, 1.f, 0.f), nnormal(0.f, 0.f, 1.f), ppdf(1.f), c0(0.f, 1.f, 0.f), c90(1.f, 0.f, 0.f) {} #endif }; struct QuadLight { Light super; vec3f radiance; // emitted RGB radiance IntensityDistribution intensityDistribution; QuadLightDynamic pre; // un- or pre-transformed state #ifdef __cplusplus QuadLight() : radiance(0.f) { super.type = LIGHT_TYPE_QUAD; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/SphericalQuadSampling.ih000066400000000000000000000247701464752671100256000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct SphericalQuad { vec3f e0, e1, z; float S, k, n0z, n0z2, n2z, x0, x1, y0, y02, y1, y12, z0, z02; }; #define template_SphericalQuad_create(univary) \ inline SphericalQuad SphericalQuad_create(const univary vec3f &q0, \ const univary vec3f &e0, \ const univary vec3f &e1, \ const univary vec3f &n, \ const vec3f &P) \ { \ const univary float e0l = length(e0); \ const univary float e1l = length(e1); \ SphericalQuad quad; \ quad.e0 = e0 / e0l; \ quad.e1 = e1 / e1l; \ 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; \ } #ifndef OSPRAY_TARGET_SYCL template_SphericalQuad_create(varying); #endif template_SphericalQuad_create(uniform); #undef template_SphericalQuad_create inline float sign(float x) { return ((float)(0.f < x) - (float)(x < 0.f)); } inline 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); } inline 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); } #define template_computeCosineWeightedRNG(univary) \ inline vec3f computeCosineWeightedRNG(const univary vec3f &q0, \ const univary vec3f &e0, \ const univary vec3f &e1, \ const vec3f &P, \ const vec3f &Ng, \ const vec2f &s) \ { \ /*code from \ https://casual-effects.com/research/Hart2020Sampling/Hart2020Sampling.pdf*/ \ vec3f wpn[4]; \ univary vec3f 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); \ } #ifndef OSPRAY_TARGET_SYCL template_computeCosineWeightedRNG(varying); #endif template_computeCosineWeightedRNG(uniform); #undef template_computeCosineWeightedRNG OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/SpotLight.cpp000066400000000000000000000116341464752671100234520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "SpotLight.h" #include "math/sampling.h" #ifndef OSPRAY_TARGET_SYCL #include "lights/SpotLight_ispc.h" #else namespace ispc { void SpotLight_Transform(const void *self, const void *xfm, void *dyn); void *SpotLight_sample_addr(); void *SpotLight_sample_instanced_addr(); void *SpotLight_eval_addr(); void *SpotLight_eval_instanced_addr(); } // namespace ispc #endif // ispc shared #include "SpotLightShared.h" #include "common/InstanceShared.h" namespace ospray { ispc::Light *SpotLight::createSh(uint32_t, const ispc::Instance *instance) const { ispc::SpotLight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast(ispc::SpotLight_sample_addr()); sh->super.eval = reinterpret_cast(ispc::SpotLight_eval_addr()); #endif sh->super.isVisible = visible; sh->super.instance = instance; sh->pre.position = position; sh->pre.direction = normalize(direction); intensityDistribution.setSh(sh->intensityDistribution); // Enable dynamic runtime instancing or apply static transformation if (instance) { sh->pre.c0 = intensityDistribution.c0; if (instance->motionBlur) { #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast( ispc::SpotLight_sample_instanced_addr()); sh->super.eval = reinterpret_cast( ispc::SpotLight_eval_instanced_addr()); #endif } else ispc::SpotLight_Transform(&sh->pre, instance->xfm, &sh->pre); } else { sh->pre.c90 = normalize(cross(intensityDistribution.c0, sh->pre.direction)); sh->pre.c0 = cross(sh->pre.direction, sh->pre.c90); } sh->radiance = radiance; sh->intensity = radIntensity; sh->cosAngleMax = cosAngleMax; sh->cosAngleScale = cosAngleScale; sh->radius = radius; sh->innerRadius = innerRadius; sh->areaPdf = uniformSampleRingPDF(radius, innerRadius); return &sh->super; } std::string SpotLight::toString() const { return "ospray::SpotLight"; } void SpotLight::commit() { Light::commit(); 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 intensityDistribution.c0 = std::abs(direction.x) < std::abs(direction.y) ? vec3f(0.0f, direction.z, direction.y) : vec3f(direction.z, 0.0f, direction.x); intensityDistribution.readParams(*this); // check ranges and pre-compute parameters openingAngle = clamp(openingAngle, 0.f, 360.f); penumbraAngle = clamp(penumbraAngle, 0.f, 0.5f * openingAngle); cosAngleMax = std::cos(deg2rad(0.5f * openingAngle)); const float cosAngleMin = std::cos(deg2rad(0.5f * openingAngle - penumbraAngle)); cosAngleScale = 1.0f / (cosAngleMin - cosAngleMax); queryIntensityQuantityType(intensityDistribution ? OSP_INTENSITY_QUANTITY_SCALE : OSP_INTENSITY_QUANTITY_INTENSITY); processIntensityQuantityType(openingAngle); } void SpotLight::processIntensityQuantityType(const float openingAngle) { radIntensity = 0.0f; radiance = 0.0f; const float halfOpeningAngleRad = M_PI * (openingAngle * 0.5f) / 180.0f; const float cosHalfOpeningAngle = cos(halfOpeningAngleRad); const auto sqr = [](const float f) { return f * f; }; const float ringDiskArea = M_PI * (sqr(radius) - sqr(innerRadius)); const float sphericalCapCosInt = M_PI * (1.0f - sqr(cosHalfOpeningAngle)); // converting from the chosen intensity quantity type to radiance if (intensityDistribution ? intensityQuantity == OSP_INTENSITY_QUANTITY_SCALE : intensityQuantity == OSP_INTENSITY_QUANTITY_INTENSITY) { radIntensity = coloredIntensity; if (radius > 0.0f) radiance = radIntensity / ringDiskArea; return; } if (!intensityDistribution) { if (intensityQuantity == OSP_INTENSITY_QUANTITY_POWER) { // since our spot light implementation includes the cosine term we need // to consider the integrated cosine cap instead of the usually used // integrated cap radIntensity = coloredIntensity / sphericalCapCosInt; if (radius > 0.0f) radiance = coloredIntensity / (sphericalCapCosInt * ringDiskArea); return; } if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { // a virtual spot light has no surface area therefore radIntensity stays 0 if (radius > 0.0f) radiance = coloredIntensity; return; } } postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/SpotLight.h000066400000000000000000000017531464752671100231200ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "IntensityDistribution.h" #include "Light.h" namespace ospray { /*! a SpotLight is a singular light emitting from a point uniformly into a * cone of directions bounded by halfAngle */ struct OSPRAY_SDK_INTERFACE SpotLight : public Light { SpotLight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_SPOT) {} virtual ~SpotLight() override = default; virtual ispc::Light *createSh( uint32_t, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(const float openingAngle); vec3f position{0.f}; vec3f direction{0.f, 0.f, 1.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}; IntensityDistribution intensityDistribution; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/SpotLight.ih000066400000000000000000000017231464752671100232660ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Light_SampleRes SpotLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_SampleRes SpotLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &sp, const float time, const uniform FeatureFlagsHandler &); SYCL_EXTERNAL Light_EvalRes SpotLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float); SYCL_EXTERNAL Light_EvalRes SpotLight_eval_instanced(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist, const float time); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/SpotLight.ispc000066400000000000000000000156061464752671100236310ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "IntensityDistribution.ih" #include "common/Instance.ih" #include "math/sampling.ih" // c++ shared #include "SpotLightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // Implementation ////////////////////////////////////////////////////////////////////////////// inline void Transform(const uniform SpotLightDynamic &pre, const uniform affine3f &xfm, uniform SpotLightDynamic &dyn) { dyn.position = xfmPoint(xfm, pre.position); dyn.direction = normalize(xfmVector(xfm, pre.direction)); dyn.c90 = normalize(cross(xfmVector(xfm, pre.c0), dyn.direction)); dyn.c0 = cross(dyn.direction, dyn.c90); } export void SpotLight_Transform( const void *uniform self, const void *uniform xfm, void *uniform dyn) { Transform(*((const SpotLightDynamic *uniform)self), *((affine3f * uniform) xfm), *((SpotLightDynamic * uniform) dyn)); } inline float AngularAttenuation(const SpotLight *uniform self, float cosAngle) { return clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale); } inline Light_SampleRes Sample(const SpotLight *uniform self, const uniform SpotLightDynamic &dyn, const DifferentialGeometry &dg, const vec2f &s) { Light_SampleRes res; // extant light vector from the hit point res.dir = dyn.position - dg.P; if (self->radius > 0.0f) { uniform linear3f l2w; l2w.vx = dyn.c0; l2w.vy = dyn.c90; l2w.vz = dyn.direction; res.dir = l2w * uniformSampleRing(self->radius, self->innerRadius, s) + res.dir; } const float dist2 = dot(res.dir, res.dir); const float invdist = rsqrt(dist2); // normalized light vector res.dir = res.dir * invdist; res.dist = dist2 * invdist; // cosine of the negated light direction and light vector. const float cosAngle = -dot(dyn.direction, res.dir); float weight = AngularAttenuation(self, cosAngle); if (self->intensityDistribution.lid) weight *= IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosAngle, res.dir); if (self->radius > 0.0f) { // convert area PDF to solid angle PDF res.pdf = self->areaPdf * (dist2 / abs(cosAngle)); if (self->intensityDistribution.lid) { // 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. weight /= self->areaPdf * dist2; } else { weight /= res.pdf; } res.weight = self->radiance * weight; } else { res.pdf = inf; // we always take this sample if (!self->intensityDistribution.lid) { // if the spotlight does not use a measured LDF we // simulate Lambertian behavior by multiplication with cosineAngle weight *= abs(cosAngle); } // convert from intensity to radiance by attenuating by distance^2; // attenuate by angle res.weight = self->intensity * (sqr(invdist) * weight); } return res; } SYCL_EXTERNAL Light_SampleRes SpotLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float, const uniform FeatureFlagsHandler &) { const SpotLight *uniform self = (SpotLight * uniform) super; assert(self); return Sample(self, self->pre, dg, s); } SYCL_EXTERNAL Light_SampleRes SpotLight_sample_instanced( const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float time, const uniform FeatureFlagsHandler &) { 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); uniform SpotLightDynamic dyn; Transform(self->pre, xfm, dyn); res = Sample(self, dyn, dg, s); } return res; } inline Light_EvalRes Eval(const SpotLight *uniform self, const uniform SpotLightDynamic &dyn, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { Light_EvalRes res; res.radiance = make_vec3f(0.f); if (self->radius > 0.f) { // intersect ring const float cosAngle = -dot(dyn.direction, dir); if (cosAngle > self->cosAngleMax) { // inside illuminated cone? const vec3f vp = dg.P - dyn.position; const float t = dot(vp, dyn.direction) * rcp(cosAngle); if (t > minDist & t <= maxDist) { const vec3f vd = vp + t * dir; const float d2 = dot(vd, vd); // inside ring? if (d2 < sqr(self->radius) && d2 > sqr(self->innerRadius)) { float attenuation = AngularAttenuation(self, cosAngle); if (self->intensityDistribution.lid) { attenuation *= IntensityDistribution_eval( &self->intensityDistribution, dyn.c0, dyn.c90, cosAngle, dir); // convert from intensity to radiance by canceling the the cosine // term introduced by 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; } SYCL_EXTERNAL 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->pre, dg, dir, minDist, maxDist); } SYCL_EXTERNAL 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); uniform SpotLightDynamic dyn; Transform(self->pre, xfm, dyn); res = Eval(self, dyn, dg, dir, minDist, maxDist); } return res; } // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// export void *uniform SpotLight_sample_addr() { return (void *uniform)SpotLight_sample; } #ifndef OSPRAY_TARGET_SYCL export void *uniform SpotLight_sample_instanced_addr() { return (void *uniform)SpotLight_sample_instanced; } #endif export void *uniform SpotLight_eval_addr() { return (void *uniform)SpotLight_eval; } #ifndef OSPRAY_TARGET_SYCL export void *uniform SpotLight_eval_instanced_addr() { return (void *uniform)SpotLight_eval_instanced; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/lights/SpotLightShared.h000066400000000000000000000031311464752671100242370ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "IntensityDistributionShared.h" #include "LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // state that changes under transformations struct SpotLightDynamic { vec3f position; vec3f direction; vec3f c0; vec3f c90; #ifdef __cplusplus SpotLightDynamic() : position(0.f), direction(0.f, 0.f, 1.f), c0(1.f, 0.f, 0.f), c90(0.f, 1.f, 0.f) {} #endif // __cplusplus }; struct SpotLight { Light super; vec3f intensity; // RGB radiative intensity of the SpotLight vec3f radiance; // emitted RGB radiance float cosAngleMax; // Angular limit of the spot in an easier to use form: // cosine of the half angle in radians float cosAngleScale; // 1/(cos(border of the penumbra area) - cosAngleMax); // positive float radius; // defines the size of the DiskLight represented using // the (extended) SpotLight float innerRadius; // defines the size of the inner cut out of the DiskLight // to represent a RingLight float areaPdf; // pdf of disk/ring with radius/innerRadius IntensityDistribution intensityDistribution; SpotLightDynamic pre; // un- or pre-transformed state #ifdef __cplusplus SpotLight() : intensity(0.f), radiance(1.f), cosAngleMax(1.f), cosAngleScale(1.f), radius(0.f), innerRadius(0.f), areaPdf(inf) { super.type = LIGHT_TYPE_SPOT; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/lights/SunSkyLight.cpp000066400000000000000000000144021464752671100237550ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "SunSkyLight.h" #include "texture/Texture2D.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "lights/HDRILight_ispc.h" #else namespace ispc { void HDRILight_initDistribution(const void *map, void *distribution); } #endif // ispc shared #include "DirectionalLightShared.h" #include "HDRILightShared.h" namespace ospray { SunSkyLight::SunSkyLight(api::ISPCDevice &device) : Light(device, FFO_LIGHT_HDRI | FFO_LIGHT_DIRECTIONAL) { static const int skyResolution = 512; this->skySize = vec2i(skyResolution, skyResolution / 2); this->skyImage = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), skySize.product()); static auto format = static_cast(OSP_TEXTURE_RGB32F); static auto filter = static_cast(OSP_TEXTURE_FILTER_LINEAR); map = new Texture2D(getISPCDevice()); map->refDec(); void *data = skyImage->data(); map->getSh()->set(skySize, &data, 0, format, filter, vec2ui(OSP_TEXTURE_WRAP_REPEAT, OSP_TEXTURE_WRAP_CLAMP_TO_EDGE)); } ispc::Light *SunSkyLight::createSh( uint32_t index, const ispc::Instance *instance) const { switch (index) { case 0: { ispc::HDRILight *sh = StructSharedCreate(getISPCDevice().getDRTDevice()); sh->set(visible, instance, coloredIntensity, frame, map->getSh(), distribution->getSh()); return &sh->super; } case 1: { ispc::DirectionalLight *sh = StructSharedCreate( getISPCDevice().getDRTDevice()); sh->set(visible, instance, direction, solarIrradiance, cosAngle); return &sh->super; } default: assert(false && "Incorrect SunSky sublight index"); } return nullptr; } std::string SunSkyLight::toString() const { return "ospray::SunSkyLight"; } void SunSkyLight::commit() { Light::commit(); const float lambdaMin = 320.0f; const float lambdaMax = 720.0f; const vec3f up = normalize(getParam("up", 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 = clamp(getParam("horizonExtension", 0.01f), 0.0f, 1.f); const float sunTheta = dot(up, direction); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_SCALE); processIntensityQuantityType(); frame.vz = up; if (std::abs(sunTheta) > 0.99f) { const vec3f dx0 = vec3f(0.0f, up.z, -up.y); const vec3f dx1 = vec3f(-up.z, 0.0f, up.x); frame.vx = normalize(std::abs(up.x) < std::abs(up.y) ? dx0 : dx1); frame.vy = cross(up, frame.vx); } else { frame.vy = normalize(cross(-direction, frame.vz)); frame.vx = cross(frame.vy, frame.vz); } // clamp sun to horizon if (sunTheta < 0) direction = frame.vx; // sun doesn't go beneath the horizon as theta clamped to pi/2 const float sunThetaMax = min(std::acos(sunTheta), (float)pi * 0.999f / 2.0f); const float sunPhi = pi; const float sunElevation = (float)pi / 2.0f - sunThetaMax; ArHosekSkyModelState *spectralModel = arhosekskymodelstate_alloc_init(sunElevation, turbidity, albedo); // angular diameter of the sun in degrees // using this value produces matching solar irradiance results from the model // and directional light const float angularDiameter = 0.53; solarIrradiance = zero; // calculate solar radiance for (int i = 0; i < cieSize; ++i) { if (cieLambda[i] >= lambdaMin && cieLambda[i] <= lambdaMax) { float r = arhosekskymodel_solar_radiance_internal2( spectralModel, cieLambda[i], sunElevation, 1); solarIrradiance += r * cieXyz(i); } } arhosekskymodelstate_free(spectralModel); 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; ArHosekSkyModelState *rgbModel = arhosek_rgb_skymodelstate_alloc_init(turbidity, albedo, sunElevation); tasking::parallel_for(skySize.y, [&](int y) { for (int x = 0; x < skySize.x; x++) { float theta = (y + 0.5) / skySize.y * float(pi); const size_t index = skySize.x * y + x; // const size_t index = skySize.x * y + x * 3; vec3f skyRadiance = zero; const float maxTheta = 0.999 * float(pi) / 2.0; const float maxThetaHorizon = (horizon + 1.0) * float(pi) / 2.0; if (theta <= maxThetaHorizon) { float shadow = (horizon > 0.f) ? float( clamp((maxThetaHorizon - theta) / (maxThetaHorizon - maxTheta), 0.f, 1.f)) : 1.f; theta = min(theta, maxTheta); float phi = ((x + 0.5) / skySize.x - 0.5) * (2.0 * (float)pi); float cosGamma = cos(theta) * cos(sunThetaMax) + sin(theta) * sin(sunThetaMax) * cos(phi - sunPhi); float gamma = std::acos(clamp(cosGamma, -1.f, 1.f)); float rgbData[3]; for (int i = 0; i < 3; ++i) { rgbData[i] = arhosek_tristim_skymodel_radiance(rgbModel, theta, gamma, i); } skyRadiance = vec3f(rgbData[0], rgbData[1], rgbData[2]); skyRadiance = skyRadiance * shadow; skyRadiance *= intensityScale; } skyImage->data()[index] = max(skyRadiance, vec3f(0.0f)); } }); arhosekskymodelstate_free(rgbModel); // recreate distribution distribution = new Distribution2D(skySize, getISPCDevice()); // Release extra local ref distribution->refDec(); ispc::HDRILight_initDistribution(map->getSh(), distribution->getSh()); } void SunSkyLight::processIntensityQuantityType() { // validate the correctness of the light quantity type if (intensityQuantity == OSP_INTENSITY_QUANTITY_SCALE) { coloredIntensity = getParam("color", vec3f(1.f)); intensityScale = getParam("intensity", 0.025f); } else { postStatusMsg(OSP_LOG_WARNING) << toString() << " unsupported 'intensityQuantity' value"; coloredIntensity = vec3f(0.0f); } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/SunSkyLight.h000066400000000000000000000035451464752671100234300ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Light.h" #include "math/Distribution2D.h" #include "math/spectrum.h" #include "rkcommon/tasking/parallel_for.h" #include "sky_model/color_info.h" #include "sky_model/sky_model.h" // ispc shared #include "texture/Texture2D.h" // Sun and sky environment lights // [Hosek and Wilkie 2012, "An Analytic Model for Full Spectral Sky-Dome // Radiance"] [Hosek and Wilkie 2013, "Adding a Solar Radiance Function to the // Hosek Skylight Model"] namespace ospray { // // CIE XYZ color matching functions // // -------------------------------- inline vec3f cieXyz(int i) { return vec3f(cieX[i], cieY[i], cieZ[i]); } inline vec3f xyzToRgb(const vec3f &c) { float r = 3.240479f * c.x - 1.537150f * c.y - 0.498535f * c.z; float g = -0.969256f * c.x + 1.875991f * c.y + 0.041556f * c.z; float b = 0.055648f * c.x - 0.204043f * c.y + 1.057311f * c.z; return vec3f(r, g, b); } struct OSPRAY_SDK_INTERFACE SunSkyLight : public Light { SunSkyLight(api::ISPCDevice &device); virtual uint32_t getShCount() const override; virtual ispc::Light *createSh( uint32_t index, const ispc::Instance *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); BufferSharedUq skyImage; Ref map; Ref distribution; 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}; }; // Inlined definitions ///////////////////////////////////////////////////////// inline uint32_t SunSkyLight::getShCount() const { return 2; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/registration.cpp000066400000000000000000000013151464752671100242420ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "AmbientLight.h" #include "CylinderLight.h" #include "DirectionalLight.h" #include "HDRILight.h" #include "PointLight.h" #include "QuadLight.h" #include "SpotLight.h" #include "SunSkyLight.h" namespace ospray { void registerAllLights() { Light::registerType("ambient"); Light::registerType("cylinder"); Light::registerType("distant"); Light::registerType("hdri"); Light::registerType("sphere"); Light::registerType("quad"); Light::registerType("spot"); Light::registerType("sunSky"); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/registration.h000066400000000000000000000002211464752671100237020ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllLights(); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/sky_model/000077500000000000000000000000001464752671100230125ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/lights/sky_model/color_info.h000066400000000000000000000664621464752671100253320ustar00rootroot00000000000000// Copyright 2010-2020 Attila T. Afra // Copyright 2015 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { static const int cieSize = 471; const float cieX[cieSize] = {0.0001299000f, 0.0001458470f, 0.0001638021f, 0.0001840037f, 0.0002066902f, 0.0002321000f, 0.0002607280f, 0.0002930750f, 0.0003293880f, 0.0003699140f, 0.0004149000f, 0.0004641587f, 0.0005189860f, 0.0005818540f, 0.0006552347f, 0.0007416000f, 0.0008450296f, 0.0009645268f, 0.001094949f, 0.001231154f, 0.001368000f, 0.001502050f, 0.001642328f, 0.001802382f, 0.001995757f, 0.002236000f, 0.002535385f, 0.002892603f, 0.003300829f, 0.003753236f, 0.004243000f, 0.004762389f, 0.005330048f, 0.005978712f, 0.006741117f, 0.007650000f, 0.008751373f, 0.01002888f, 0.01142170f, 0.01286901f, 0.01431000f, 0.01570443f, 0.01714744f, 0.01878122f, 0.02074801f, 0.02319000f, 0.02620736f, 0.02978248f, 0.03388092f, 0.03846824f, 0.04351000f, 0.04899560f, 0.05502260f, 0.06171880f, 0.06921200f, 0.07763000f, 0.08695811f, 0.09717672f, 0.1084063f, 0.1207672f, 0.1343800f, 0.1493582f, 0.1653957f, 0.1819831f, 0.1986110f, 0.2147700f, 0.2301868f, 0.2448797f, 0.2587773f, 0.2718079f, 0.2839000f, 0.2949438f, 0.3048965f, 0.3137873f, 0.3216454f, 0.3285000f, 0.3343513f, 0.3392101f, 0.3431213f, 0.3461296f, 0.3482800f, 0.3495999f, 0.3501474f, 0.3500130f, 0.3492870f, 0.3480600f, 0.3463733f, 0.3442624f, 0.3418088f, 0.3390941f, 0.3362000f, 0.3331977f, 0.3300411f, 0.3266357f, 0.3228868f, 0.3187000f, 0.3140251f, 0.3088840f, 0.3032904f, 0.2972579f, 0.2908000f, 0.2839701f, 0.2767214f, 0.2689178f, 0.2604227f, 0.2511000f, 0.2408475f, 0.2298512f, 0.2184072f, 0.2068115f, 0.1953600f, 0.1842136f, 0.1733273f, 0.1626881f, 0.1522833f, 0.1421000f, 0.1321786f, 0.1225696f, 0.1132752f, 0.1042979f, 0.09564000f, 0.08729955f, 0.07930804f, 0.07171776f, 0.06458099f, 0.05795001f, 0.05186211f, 0.04628152f, 0.04115088f, 0.03641283f, 0.03201000f, 0.02791720f, 0.02414440f, 0.02068700f, 0.01754040f, 0.01470000f, 0.01216179f, 0.009919960f, 0.007967240f, 0.006296346f, 0.004900000f, 0.003777173f, 0.002945320f, 0.002424880f, 0.002236293f, 0.002400000f, 0.002925520f, 0.003836560f, 0.005174840f, 0.006982080f, 0.009300000f, 0.01214949f, 0.01553588f, 0.01947752f, 0.02399277f, 0.02910000f, 0.03481485f, 0.04112016f, 0.04798504f, 0.05537861f, 0.06327000f, 0.07163501f, 0.08046224f, 0.08973996f, 0.09945645f, 0.1096000f, 0.1201674f, 0.1311145f, 0.1423679f, 0.1538542f, 0.1655000f, 0.1772571f, 0.1891400f, 0.2011694f, 0.2133658f, 0.2257499f, 0.2383209f, 0.2510668f, 0.2639922f, 0.2771017f, 0.2904000f, 0.3038912f, 0.3175726f, 0.3314384f, 0.3454828f, 0.3597000f, 0.3740839f, 0.3886396f, 0.4033784f, 0.4183115f, 0.4334499f, 0.4487953f, 0.4643360f, 0.4800640f, 0.4959713f, 0.5120501f, 0.5282959f, 0.5446916f, 0.5612094f, 0.5778215f, 0.5945000f, 0.6112209f, 0.6279758f, 0.6447602f, 0.6615697f, 0.6784000f, 0.6952392f, 0.7120586f, 0.7288284f, 0.7455188f, 0.7621000f, 0.7785432f, 0.7948256f, 0.8109264f, 0.8268248f, 0.8425000f, 0.8579325f, 0.8730816f, 0.8878944f, 0.9023181f, 0.9163000f, 0.9297995f, 0.9427984f, 0.9552776f, 0.9672179f, 0.9786000f, 0.9893856f, 0.9995488f, 1.0090892f, 1.0180064f, 1.0263000f, 1.0339827f, 1.0409860f, 1.0471880f, 1.0524667f, 1.0567000f, 1.0597944f, 1.0617992f, 1.0628068f, 1.0629096f, 1.0622000f, 1.0607352f, 1.0584436f, 1.0552244f, 1.0509768f, 1.0456000f, 1.0390369f, 1.0313608f, 1.0226662f, 1.0130477f, 1.0026000f, 0.9913675f, 0.9793314f, 0.9664916f, 0.9528479f, 0.9384000f, 0.9231940f, 0.9072440f, 0.8905020f, 0.8729200f, 0.8544499f, 0.8350840f, 0.8149460f, 0.7941860f, 0.7729540f, 0.7514000f, 0.7295836f, 0.7075888f, 0.6856022f, 0.6638104f, 0.6424000f, 0.6215149f, 0.6011138f, 0.5811052f, 0.5613977f, 0.5419000f, 0.5225995f, 0.5035464f, 0.4847436f, 0.4661939f, 0.4479000f, 0.4298613f, 0.4120980f, 0.3946440f, 0.3775333f, 0.3608000f, 0.3444563f, 0.3285168f, 0.3130192f, 0.2980011f, 0.2835000f, 0.2695448f, 0.2561184f, 0.2431896f, 0.2307272f, 0.2187000f, 0.2070971f, 0.1959232f, 0.1851708f, 0.1748323f, 0.1649000f, 0.1553667f, 0.1462300f, 0.1374900f, 0.1291467f, 0.1212000f, 0.1136397f, 0.1064650f, 0.09969044f, 0.09333061f, 0.08740000f, 0.08190096f, 0.07680428f, 0.07207712f, 0.06768664f, 0.06360000f, 0.05980685f, 0.05628216f, 0.05297104f, 0.04981861f, 0.04677000f, 0.04378405f, 0.04087536f, 0.03807264f, 0.03540461f, 0.03290000f, 0.03056419f, 0.02838056f, 0.02634484f, 0.02445275f, 0.02270000f, 0.02108429f, 0.01959988f, 0.01823732f, 0.01698717f, 0.01584000f, 0.01479064f, 0.01383132f, 0.01294868f, 0.01212920f, 0.01135916f, 0.01062935f, 0.009938846f, 0.009288422f, 0.008678854f, 0.008110916f, 0.007582388f, 0.007088746f, 0.006627313f, 0.006195408f, 0.005790346f, 0.005409826f, 0.005052583f, 0.004717512f, 0.004403507f, 0.004109457f, 0.003833913f, 0.003575748f, 0.003334342f, 0.003109075f, 0.002899327f, 0.002704348f, 0.002523020f, 0.002354168f, 0.002196616f, 0.002049190f, 0.001910960f, 0.001781438f, 0.001660110f, 0.001546459f, 0.001439971f, 0.001340042f, 0.001246275f, 0.001158471f, 0.001076430f, 0.0009999493f, 0.0009287358f, 0.0008624332f, 0.0008007503f, 0.0007433960f, 0.0006900786f, 0.0006405156f, 0.0005945021f, 0.0005518646f, 0.0005124290f, 0.0004760213f, 0.0004424536f, 0.0004115117f, 0.0003829814f, 0.0003566491f, 0.0003323011f, 0.0003097586f, 0.0002888871f, 0.0002695394f, 0.0002515682f, 0.0002348261f, 0.0002191710f, 0.0002045258f, 0.0001908405f, 0.0001780654f, 0.0001661505f, 0.0001550236f, 0.0001446219f, 0.0001349098f, 0.0001258520f, 0.0001174130f, 0.0001095515f, 0.0001022245f, 0.00009539445f, 0.00008902390f, 0.00008307527f, 0.00007751269f, 0.00007231304f, 0.00006745778f, 0.00006292844f, 0.00005870652f, 0.00005477028f, 0.00005109918f, 0.00004767654f, 0.00004448567f, 0.00004150994f, 0.00003873324f, 0.00003614203f, 0.00003372352f, 0.00003146487f, 0.00002935326f, 0.00002737573f, 0.00002552433f, 0.00002379376f, 0.00002217870f, 0.00002067383f, 0.00001927226f, 0.00001796640f, 0.00001674991f, 0.00001561648f, 0.00001455977f, 0.00001357387f, 0.00001265436f, 0.00001179723f, 0.00001099844f, 0.00001025398f, 0.000009559646f, 0.000008912044f, 0.000008308358f, 0.000007745769f, 0.000007221456f, 0.000006732475f, 0.000006276423f, 0.000005851304f, 0.000005455118f, 0.000005085868f, 0.000004741466f, 0.000004420236f, 0.000004120783f, 0.000003841716f, 0.000003581652f, 0.000003339127f, 0.000003112949f, 0.000002902121f, 0.000002705645f, 0.000002522525f, 0.000002351726f, 0.000002192415f, 0.000002043902f, 0.000001905497f, 0.000001776509f, 0.000001656215f, 0.000001544022f, 0.000001439440f, 0.000001341977f, 0.000001251141f}; const float cieY[cieSize] = {0.000003917000f, 0.000004393581f, 0.000004929604f, 0.000005532136f, 0.000006208245f, 0.000006965000f, 0.000007813219f, 0.000008767336f, 0.000009839844f, 0.00001104323f, 0.00001239000f, 0.00001388641f, 0.00001555728f, 0.00001744296f, 0.00001958375f, 0.00002202000f, 0.00002483965f, 0.00002804126f, 0.00003153104f, 0.00003521521f, 0.00003900000f, 0.00004282640f, 0.00004691460f, 0.00005158960f, 0.00005717640f, 0.00006400000f, 0.00007234421f, 0.00008221224f, 0.00009350816f, 0.0001061361f, 0.0001200000f, 0.0001349840f, 0.0001514920f, 0.0001702080f, 0.0001918160f, 0.0002170000f, 0.0002469067f, 0.0002812400f, 0.0003185200f, 0.0003572667f, 0.0003960000f, 0.0004337147f, 0.0004730240f, 0.0005178760f, 0.0005722187f, 0.0006400000f, 0.0007245600f, 0.0008255000f, 0.0009411600f, 0.001069880f, 0.001210000f, 0.001362091f, 0.001530752f, 0.001720368f, 0.001935323f, 0.002180000f, 0.002454800f, 0.002764000f, 0.003117800f, 0.003526400f, 0.004000000f, 0.004546240f, 0.005159320f, 0.005829280f, 0.006546160f, 0.007300000f, 0.008086507f, 0.008908720f, 0.009767680f, 0.01066443f, 0.01160000f, 0.01257317f, 0.01358272f, 0.01462968f, 0.01571509f, 0.01684000f, 0.01800736f, 0.01921448f, 0.02045392f, 0.02171824f, 0.02300000f, 0.02429461f, 0.02561024f, 0.02695857f, 0.02835125f, 0.02980000f, 0.03131083f, 0.03288368f, 0.03452112f, 0.03622571f, 0.03800000f, 0.03984667f, 0.04176800f, 0.04376600f, 0.04584267f, 0.04800000f, 0.05024368f, 0.05257304f, 0.05498056f, 0.05745872f, 0.06000000f, 0.06260197f, 0.06527752f, 0.06804208f, 0.07091109f, 0.07390000f, 0.07701600f, 0.08026640f, 0.08366680f, 0.08723280f, 0.09098000f, 0.09491755f, 0.09904584f, 0.1033674f, 0.1078846f, 0.1126000f, 0.1175320f, 0.1226744f, 0.1279928f, 0.1334528f, 0.1390200f, 0.1446764f, 0.1504693f, 0.1564619f, 0.1627177f, 0.1693000f, 0.1762431f, 0.1835581f, 0.1912735f, 0.1994180f, 0.2080200f, 0.2171199f, 0.2267345f, 0.2368571f, 0.2474812f, 0.2586000f, 0.2701849f, 0.2822939f, 0.2950505f, 0.3085780f, 0.3230000f, 0.3384021f, 0.3546858f, 0.3716986f, 0.3892875f, 0.4073000f, 0.4256299f, 0.4443096f, 0.4633944f, 0.4829395f, 0.5030000f, 0.5235693f, 0.5445120f, 0.5656900f, 0.5869653f, 0.6082000f, 0.6293456f, 0.6503068f, 0.6708752f, 0.6908424f, 0.7100000f, 0.7281852f, 0.7454636f, 0.7619694f, 0.7778368f, 0.7932000f, 0.8081104f, 0.8224962f, 0.8363068f, 0.8494916f, 0.8620000f, 0.8738108f, 0.8849624f, 0.8954936f, 0.9054432f, 0.9148501f, 0.9237348f, 0.9320924f, 0.9399226f, 0.9472252f, 0.9540000f, 0.9602561f, 0.9660074f, 0.9712606f, 0.9760225f, 0.9803000f, 0.9840924f, 0.9874812f, 0.9903128f, 0.9928116f, 0.9949501f, 0.9967108f, 0.9980983f, 0.9991120f, 0.9997482f, 1.0000000f, 0.9998567f, 0.9993046f, 0.9983255f, 0.9968987f, 0.9950000f, 0.9926005f, 0.9897426f, 0.9864444f, 0.9827241f, 0.9786000f, 0.9740837f, 0.9691712f, 0.9638568f, 0.9581349f, 0.9520000f, 0.9454504f, 0.9384992f, 0.9311628f, 0.9234576f, 0.9154000f, 0.9070064f, 0.8982772f, 0.8892048f, 0.8797816f, 0.8700000f, 0.8598613f, 0.8493920f, 0.8386220f, 0.8275813f, 0.8163000f, 0.8047947f, 0.7930820f, 0.7811920f, 0.7691547f, 0.7570000f, 0.7447541f, 0.7324224f, 0.7200036f, 0.7074965f, 0.6949000f, 0.6822192f, 0.6694716f, 0.6566744f, 0.6438448f, 0.6310000f, 0.6181555f, 0.6053144f, 0.5924756f, 0.5796379f, 0.5668000f, 0.5539611f, 0.5411372f, 0.5283528f, 0.5156323f, 0.5030000f, 0.4904688f, 0.4780304f, 0.4656776f, 0.4534032f, 0.4412000f, 0.4290800f, 0.4170360f, 0.4050320f, 0.3930320f, 0.3810000f, 0.3689184f, 0.3568272f, 0.3447768f, 0.3328176f, 0.3210000f, 0.3093381f, 0.2978504f, 0.2865936f, 0.2756245f, 0.2650000f, 0.2547632f, 0.2448896f, 0.2353344f, 0.2260528f, 0.2170000f, 0.2081616f, 0.1995488f, 0.1911552f, 0.1829744f, 0.1750000f, 0.1672235f, 0.1596464f, 0.1522776f, 0.1451259f, 0.1382000f, 0.1315003f, 0.1250248f, 0.1187792f, 0.1127691f, 0.1070000f, 0.1014762f, 0.09618864f, 0.09112296f, 0.08626485f, 0.08160000f, 0.07712064f, 0.07282552f, 0.06871008f, 0.06476976f, 0.06100000f, 0.05739621f, 0.05395504f, 0.05067376f, 0.04754965f, 0.04458000f, 0.04175872f, 0.03908496f, 0.03656384f, 0.03420048f, 0.03200000f, 0.02996261f, 0.02807664f, 0.02632936f, 0.02470805f, 0.02320000f, 0.02180077f, 0.02050112f, 0.01928108f, 0.01812069f, 0.01700000f, 0.01590379f, 0.01483718f, 0.01381068f, 0.01283478f, 0.01192000f, 0.01106831f, 0.01027339f, 0.009533311f, 0.008846157f, 0.008210000f, 0.007623781f, 0.007085424f, 0.006591476f, 0.006138485f, 0.005723000f, 0.005343059f, 0.004995796f, 0.004676404f, 0.004380075f, 0.004102000f, 0.003838453f, 0.003589099f, 0.003354219f, 0.003134093f, 0.002929000f, 0.002738139f, 0.002559876f, 0.002393244f, 0.002237275f, 0.002091000f, 0.001953587f, 0.001824580f, 0.001703580f, 0.001590187f, 0.001484000f, 0.001384496f, 0.001291268f, 0.001204092f, 0.001122744f, 0.001047000f, 0.0009765896f, 0.0009111088f, 0.0008501332f, 0.0007932384f, 0.0007400000f, 0.0006900827f, 0.0006433100f, 0.0005994960f, 0.0005584547f, 0.0005200000f, 0.0004839136f, 0.0004500528f, 0.0004183452f, 0.0003887184f, 0.0003611000f, 0.0003353835f, 0.0003114404f, 0.0002891656f, 0.0002684539f, 0.0002492000f, 0.0002313019f, 0.0002146856f, 0.0001992884f, 0.0001850475f, 0.0001719000f, 0.0001597781f, 0.0001486044f, 0.0001383016f, 0.0001287925f, 0.0001200000f, 0.0001118595f, 0.0001043224f, 0.00009733560f, 0.00009084587f, 0.00008480000f, 0.00007914667f, 0.00007385800f, 0.00006891600f, 0.00006430267f, 0.00006000000f, 0.00005598187f, 0.00005222560f, 0.00004871840f, 0.00004544747f, 0.00004240000f, 0.00003956104f, 0.00003691512f, 0.00003444868f, 0.00003214816f, 0.00003000000f, 0.00002799125f, 0.00002611356f, 0.00002436024f, 0.00002272461f, 0.00002120000f, 0.00001977855f, 0.00001845285f, 0.00001721687f, 0.00001606459f, 0.00001499000f, 0.00001398728f, 0.00001305155f, 0.00001217818f, 0.00001136254f, 0.00001060000f, 0.000009885877f, 0.000009217304f, 0.000008592362f, 0.000008009133f, 0.000007465700f, 0.000006959567f, 0.000006487995f, 0.000006048699f, 0.000005639396f, 0.000005257800f, 0.000004901771f, 0.000004569720f, 0.000004260194f, 0.000003971739f, 0.000003702900f, 0.000003452163f, 0.000003218302f, 0.000003000300f, 0.000002797139f, 0.000002607800f, 0.000002431220f, 0.000002266531f, 0.000002113013f, 0.000001969943f, 0.000001836600f, 0.000001712230f, 0.000001596228f, 0.000001488090f, 0.000001387314f, 0.000001293400f, 0.000001205820f, 0.000001124143f, 0.000001048009f, 0.0000009770578f, 0.0000009109300f, 0.0000008492513f, 0.0000007917212f, 0.0000007380904f, 0.0000006881098f, 0.0000006415300f, 0.0000005980895f, 0.0000005575746f, 0.0000005198080f, 0.0000004846123f, 0.0000004518100f}; const float cieZ[cieSize] = {0.0006061000f, 0.0006808792f, 0.0007651456f, 0.0008600124f, 0.0009665928f, 0.001086000f, 0.001220586f, 0.001372729f, 0.001543579f, 0.001734286f, 0.001946000f, 0.002177777f, 0.002435809f, 0.002731953f, 0.003078064f, 0.003486000f, 0.003975227f, 0.004540880f, 0.005158320f, 0.005802907f, 0.006450001f, 0.007083216f, 0.007745488f, 0.008501152f, 0.009414544f, 0.01054999f, 0.01196580f, 0.01365587f, 0.01558805f, 0.01773015f, 0.02005001f, 0.02251136f, 0.02520288f, 0.02827972f, 0.03189704f, 0.03621000f, 0.04143771f, 0.04750372f, 0.05411988f, 0.06099803f, 0.06785001f, 0.07448632f, 0.08136156f, 0.08915364f, 0.09854048f, 0.1102000f, 0.1246133f, 0.1417017f, 0.1613035f, 0.1832568f, 0.2074000f, 0.2336921f, 0.2626114f, 0.2947746f, 0.3307985f, 0.3713000f, 0.4162091f, 0.4654642f, 0.5196948f, 0.5795303f, 0.6456000f, 0.7184838f, 0.7967133f, 0.8778459f, 0.9594390f, 1.0390501f, 1.1153673f, 1.1884971f, 1.2581233f, 1.3239296f, 1.3856000f, 1.4426352f, 1.4948035f, 1.5421903f, 1.5848807f, 1.6229600f, 1.6564048f, 1.6852959f, 1.7098745f, 1.7303821f, 1.7470600f, 1.7600446f, 1.7696233f, 1.7762637f, 1.7804334f, 1.7826000f, 1.7829682f, 1.7816998f, 1.7791982f, 1.7758671f, 1.7721100f, 1.7682589f, 1.7640390f, 1.7589438f, 1.7524663f, 1.7441000f, 1.7335595f, 1.7208581f, 1.7059369f, 1.6887372f, 1.6692000f, 1.6475287f, 1.6234127f, 1.5960223f, 1.5645280f, 1.5281000f, 1.4861114f, 1.4395215f, 1.3898799f, 1.3387362f, 1.2876400f, 1.2374223f, 1.1878243f, 1.1387611f, 1.0901480f, 1.0419000f, 0.9941976f, 0.9473473f, 0.9014531f, 0.8566193f, 0.8129501f, 0.7705173f, 0.7294448f, 0.6899136f, 0.6521049f, 0.6162000f, 0.5823286f, 0.5504162f, 0.5203376f, 0.4919673f, 0.4651800f, 0.4399246f, 0.4161836f, 0.3938822f, 0.3729459f, 0.3533000f, 0.3348578f, 0.3175521f, 0.3013375f, 0.2861686f, 0.2720000f, 0.2588171f, 0.2464838f, 0.2347718f, 0.2234533f, 0.2123000f, 0.2011692f, 0.1901196f, 0.1792254f, 0.1685608f, 0.1582000f, 0.1481383f, 0.1383758f, 0.1289942f, 0.1200751f, 0.1117000f, 0.1039048f, 0.09666748f, 0.08998272f, 0.08384531f, 0.07824999f, 0.07320899f, 0.06867816f, 0.06456784f, 0.06078835f, 0.05725001f, 0.05390435f, 0.05074664f, 0.04775276f, 0.04489859f, 0.04216000f, 0.03950728f, 0.03693564f, 0.03445836f, 0.03208872f, 0.02984000f, 0.02771181f, 0.02569444f, 0.02378716f, 0.02198925f, 0.02030000f, 0.01871805f, 0.01724036f, 0.01586364f, 0.01458461f, 0.01340000f, 0.01230723f, 0.01130188f, 0.01037792f, 0.009529306f, 0.008749999f, 0.008035200f, 0.007381600f, 0.006785400f, 0.006242800f, 0.005749999f, 0.005303600f, 0.004899800f, 0.004534200f, 0.004202400f, 0.003900000f, 0.003623200f, 0.003370600f, 0.003141400f, 0.002934800f, 0.002749999f, 0.002585200f, 0.002438600f, 0.002309400f, 0.002196800f, 0.002100000f, 0.002017733f, 0.001948200f, 0.001889800f, 0.001840933f, 0.001800000f, 0.001766267f, 0.001737800f, 0.001711200f, 0.001683067f, 0.001650001f, 0.001610133f, 0.001564400f, 0.001513600f, 0.001458533f, 0.001400000f, 0.001336667f, 0.001270000f, 0.001205000f, 0.001146667f, 0.001100000f, 0.001068800f, 0.001049400f, 0.001035600f, 0.001021200f, 0.001000000f, 0.0009686400f, 0.0009299200f, 0.0008868800f, 0.0008425600f, 0.0008000000f, 0.0007609600f, 0.0007236800f, 0.0006859200f, 0.0006454400f, 0.0006000000f, 0.0005478667f, 0.0004916000f, 0.0004354000f, 0.0003834667f, 0.0003400000f, 0.0003072533f, 0.0002831600f, 0.0002654400f, 0.0002518133f, 0.0002400000f, 0.0002295467f, 0.0002206400f, 0.0002119600f, 0.0002021867f, 0.0001900000f, 0.0001742133f, 0.0001556400f, 0.0001359600f, 0.0001168533f, 0.0001000000f, 0.00008613333f, 0.00007460000f, 0.00006500000f, 0.00005693333f, 0.00004999999f, 0.00004416000f, 0.00003948000f, 0.00003572000f, 0.00003264000f, 0.00003000000f, 0.00002765333f, 0.00002556000f, 0.00002364000f, 0.00002181333f, 0.00002000000f, 0.00001813333f, 0.00001620000f, 0.00001420000f, 0.00001213333f, 0.00001000000f, 0.000007733333f, 0.000005400000f, 0.000003200000f, 0.000001333333f, 0.000000000000f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; const float cieLambda[cieSize] = {360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830}; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/lights/sky_model/sky_model.cpp000066400000000000000000000607001464752671100255070ustar00rootroot00000000000000/* This source is published under the following 3-clause BSD license. Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * None of the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // with slight modifications // Copyright 2020 Intel Corporation /* ============================================================================ This file is part of a sample implementation of the analytical skylight and solar radiance models presented in the SIGGRAPH 2012 paper "An Analytic Model for Full Spectral Sky-Dome Radiance" and the 2013 IEEE CG&A paper "Adding a Solar Radiance Function to the Hosek Skylight Model" both by Lukas Hosek and Alexander Wilkie Charles University in Prague, Czech Republic Version: 1.4a, February 22nd, 2013 Version history: 1.4a February 22nd, 2013 Removed unnecessary and counter-intuitive solar radius parameters from the interface of the colourspace sky dome initialisation functions. 1.4 February 11th, 2013 Fixed a bug which caused the relative brightness of the solar disc and the sky dome to be off by a factor of about 6. The sun was too bright: this affected both normal and alien sun scenarios. The coefficients of the solar radiance function were changed to fix this. 1.3 January 21st, 2013 (not released to the public) Added support for solar discs that are not exactly the same size as the terrestrial sun. Also added support for suns with a different emission spectrum ("Alien World" functionality). 1.2a December 18th, 2012 Fixed a mistake and some inaccuracies in the solar radiance function explanations found in ArHosekSkyModel.h. The actual source code is unchanged compared to version 1.2. 1.2 December 17th, 2012 Native RGB data and a solar radiance function that matches the turbidity conditions were added. 1.1 September 2012 The coefficients of the spectral model are now scaled so that the output is given in physical units: W / (m^-2 * sr * nm). Also, the output of the XYZ model is now no longer scaled to the range [0...1]. Instead, it is the result of a simple conversion from spectral data via the CIE 2 degree standard observer matching functions. Therefore, after multiplication with 683 lm / W, the Y channel now corresponds to luminance in lm. 1.0 May 11th, 2012 Initial release. Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if an updated version of this code has been published! ============================================================================ */ /* All instructions on how to use this code are in the accompanying header file. */ #include "sky_model.h" #include #include #include #include #include "sky_model_data_ciexyz.h" #include "sky_model_data_rgb.h" #include "sky_model_data_spectral.h" // Some macro definitions that occur elsewhere in ART, and that have to be // replicated to make this a stand-alone module. #ifndef MATH_PI #define MATH_PI 3.141592653589793 #endif #ifndef MATH_DEG_TO_RAD #define MATH_DEG_TO_RAD (MATH_PI / 180.0) #endif #ifndef DEGREES #define DEGREES *MATH_DEG_TO_RAD #endif #ifndef TERRESTRIAL_SOLAR_RADIUS #define TERRESTRIAL_SOLAR_RADIUS ((0.51 DEGREES) / 2.0) #endif #ifndef ALLOC #define ALLOC(_struct) (new (_struct)) #endif // internal definitions typedef float *ArHosekSkyModel_Dataset; typedef float *ArHosekSkyModel_Radiance_Dataset; // internal functions void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset, ArHosekSkyModelConfiguration config, float turbidity, float albedo, float solar_elevation) { float *elev_matrix; int int_turbidity = (int)turbidity; float turbidity_rem = turbidity - (float)int_turbidity; solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0)); // alb 0 low turb elev_matrix = dataset + (9 * 6 * (int_turbidity - 1)); for (unsigned int i = 0; i < 9; ++i) { //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; config[i] = (1.0 - albedo) * (1.0 - turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] + pow(solar_elevation, 5.0) * elev_matrix[i + 45]); } // alb 1 low turb elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity - 1)); for (unsigned int i = 0; i < 9; ++i) { //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; config[i] += (albedo) * (1.0 - turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] + pow(solar_elevation, 5.0) * elev_matrix[i + 45]); } if (int_turbidity == 10) return; // alb 0 high turb elev_matrix = dataset + (9 * 6 * (int_turbidity)); for (unsigned int i = 0; i < 9; ++i) { //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; config[i] += (1.0 - albedo) * (turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] + pow(solar_elevation, 5.0) * elev_matrix[i + 45]); } // alb 1 high turb elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity)); for (unsigned int i = 0; i < 9; ++i) { //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; config[i] += (albedo) * (turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] + pow(solar_elevation, 5.0) * elev_matrix[i + 45]); } } float ArHosekSkyModel_CookRadianceConfiguration( ArHosekSkyModel_Radiance_Dataset dataset, float turbidity, float albedo, float solar_elevation) { float *elev_matrix; int int_turbidity = (int)turbidity; float turbidity_rem = turbidity - (float)int_turbidity; float res; solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0)); // alb 0 low turb elev_matrix = dataset + (6 * (int_turbidity - 1)); //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; res = (1.0 - albedo) * (1.0 - turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] + pow(solar_elevation, 5.0) * elev_matrix[5]); // alb 1 low turb elev_matrix = dataset + (6 * 10 + 6 * (int_turbidity - 1)); //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; res += (albedo) * (1.0 - turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] + pow(solar_elevation, 5.0) * elev_matrix[5]); if (int_turbidity == 10) return res; // alb 0 high turb elev_matrix = dataset + (6 * (int_turbidity)); //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; res += (1.0 - albedo) * (turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] + pow(solar_elevation, 5.0) * elev_matrix[5]); // alb 1 high turb elev_matrix = dataset + (6 * 10 + 6 * (int_turbidity)); //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; res += (albedo) * (turbidity_rem) * (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] + 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] + 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] + 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] + 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] + pow(solar_elevation, 5.0) * elev_matrix[5]); return res; } float ArHosekSkyModel_GetRadianceInternal( ArHosekSkyModelConfiguration configuration, float theta, float gamma) { const float expM = exp(configuration[4] * gamma); const float rayM = cos(gamma) * cos(gamma); const float mieM = (1.0 + cos(gamma) * cos(gamma)) / pow((1.0 + configuration[8] * configuration[8] - 2.0 * configuration[8] * cos(gamma)), 1.5); const float zenith = sqrt(cos(theta)); return (1.0 + configuration[0] * exp(configuration[1] / (cos(theta) + 0.01))) * (configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith); } // spectral version ArHosekSkyModelState *arhosekskymodelstate_alloc_init( const float solar_elevation, const float atmospheric_turbidity, const float ground_albedo) { ArHosekSkyModelState *state = ALLOC(ArHosekSkyModelState); state->solar_radius = (0.51 DEGREES) / 2.0; state->turbidity = atmospheric_turbidity; state->albedo = ground_albedo; state->elevation = solar_elevation; for (unsigned int wl = 0; wl < 11; ++wl) { ArHosekSkyModel_CookConfiguration(datasets[wl], state->configs[wl], atmospheric_turbidity, ground_albedo, solar_elevation); state->radiances[wl] = ArHosekSkyModel_CookRadianceConfiguration( datasetsRad[wl], atmospheric_turbidity, ground_albedo, solar_elevation); state->emission_correction_factor_sun[wl] = 1.0; state->emission_correction_factor_sky[wl] = 1.0; } return state; } // 'blackbody_scaling_factor' // // Fudge factor, computed in Mathematica, to scale the results of the // following function to match the solar radiance spectrum used in the // original simulation. The scaling is done so their integrals over the // range from 380.0 to 720.0 nanometers match for a blackbody temperature // of 5800 K. // Which leaves the original spectrum being less bright overall than the 5.8k // blackbody radiation curve if the ultra-violet part of the spectrum is // also considered. But the visible brightness should be very similar. const float blackbody_scaling_factor = 3.19992 * 10E-11; // 'art_blackbody_dd_value()' function // // Blackbody radiance, Planck's formula float art_blackbody_dd_value(const float temperature, const float lambda) { float c1 = 3.74177 * 10E-17; float c2 = 0.0143878; float value; value = (c1 / (pow(lambda, 5.0))) * (1.0 / (exp(c2 / (lambda * temperature)) - 1.0)); return value; } // 'originalSolarRadianceTable[]' // // The solar spectrum incident at the top of the atmosphere, as it was used // in the brute force path tracer that generated the reference results the // model was fitted to. We need this as the yardstick to compare any altered // Blackbody emission spectra for alien world stars to. // This is just the data from the Preetham paper, extended into the UV range. const float originalSolarRadianceTable[] = {7500.0, 12500.0, 21127.5, 26760.5, 30663.7, 27825.0, 25503.8, 25134.2, 23212.1, 21526.7, 19870.8}; ArHosekSkyModelState *arhosekskymodelstate_alienworld_alloc_init( const float solar_elevation, const float solar_intensity, const float solar_surface_temperature_kelvin, const float atmospheric_turbidity, const float ground_albedo) { ArHosekSkyModelState *state = ALLOC(ArHosekSkyModelState); state->turbidity = atmospheric_turbidity; state->albedo = ground_albedo; state->elevation = solar_elevation; for (unsigned int wl = 0; wl < 11; ++wl) { // Basic init as for the normal scenario ArHosekSkyModel_CookConfiguration(datasets[wl], state->configs[wl], atmospheric_turbidity, ground_albedo, solar_elevation); state->radiances[wl] = ArHosekSkyModel_CookRadianceConfiguration( datasetsRad[wl], atmospheric_turbidity, ground_albedo, solar_elevation); // The wavelength of this band in nanometers float owl = (320.0 + 40.0 * wl) * 10E-10; // The original intensity we just computed float osr = originalSolarRadianceTable[wl]; // The intensity of a blackbody with the desired temperature // The fudge factor described above is used to make sure the BB // function matches the used radiance data reasonably well // in magnitude. float nsr = art_blackbody_dd_value(solar_surface_temperature_kelvin, owl) * blackbody_scaling_factor; // Correction factor for this waveband is simply the ratio of // the two. state->emission_correction_factor_sun[wl] = nsr / osr; } // We then compute the average correction factor of all wavebands. // Theoretically, some weighting to favour wavelengths human vision is // more sensitive to could be introduced here - think V(lambda). But // given that the whole effort is not *that* accurate to begin with (we // are talking about the appearance of alien worlds, after all), simple // averaging over the visible wavelengths (! - this is why we start at // WL #2, and only use 2-11) seems like a sane first approximation. float correctionFactor = 0.0; for (unsigned int i = 2; i < 11; i++) { correctionFactor += state->emission_correction_factor_sun[i]; } // This is the average ratio in emitted energy between our sun, and an // equally large sun with the blackbody spectrum we requested. // Division by 9 because we only used 9 of the 11 wavelengths for this // (see above). float ratio = correctionFactor / 9.0; // This ratio is then used to determine the radius of the alien sun // on the sky dome. The additional factor 'solar_intensity' can be used // to make the alien sun brighter or dimmer compared to our sun. state->solar_radius = (sqrt(solar_intensity) * TERRESTRIAL_SOLAR_RADIUS) / sqrt(ratio); // Finally, we have to reduce the scaling factor of the sky by the // ratio used to scale the solar disc size. The rationale behind this is // that the scaling factors apply to the new blackbody spectrum, which // can be more or less bright than the one our sun emits. However, we // just scaled the size of the alien solar disc so it is roughly as // bright (in terms of energy emitted) as the terrestrial sun. So the sky // dome has to be reduced in brightness appropriately - but not in an // uniform fashion across wavebands. If we did that, the sky colour would // be wrong. for (unsigned int i = 0; i < 11; i++) { state->emission_correction_factor_sky[i] = solar_intensity * state->emission_correction_factor_sun[i] / ratio; } return state; } void arhosekskymodelstate_free(ArHosekSkyModelState *state) { delete state; } float arhosekskymodel_radiance( ArHosekSkyModelState *state, float theta, float gamma, float wavelength) { int low_wl = (wavelength - 320.0) / 40.0; if (low_wl < 0 || low_wl >= 11) return 0.0f; float interp = fmod((wavelength - 320.0) / 40.0, 1.0); float val_low = ArHosekSkyModel_GetRadianceInternal(state->configs[low_wl], theta, gamma) * state->radiances[low_wl] * state->emission_correction_factor_sky[low_wl]; if (interp < 1e-6) return val_low; float result = (1.0 - interp) * val_low; if (low_wl + 1 < 11) { result += interp * ArHosekSkyModel_GetRadianceInternal( state->configs[low_wl + 1], theta, gamma) * state->radiances[low_wl + 1] * state->emission_correction_factor_sky[low_wl + 1]; } return result; } // xyz and rgb versions ArHosekSkyModelState *arhosek_xyz_skymodelstate_alloc_init( const float turbidity, const float albedo, const float elevation) { ArHosekSkyModelState *state = ALLOC(ArHosekSkyModelState); state->solar_radius = TERRESTRIAL_SOLAR_RADIUS; state->turbidity = turbidity; state->albedo = albedo; state->elevation = elevation; for (unsigned int channel = 0; channel < 3; ++channel) { ArHosekSkyModel_CookConfiguration(datasetsXYZ[channel], state->configs[channel], turbidity, albedo, elevation); state->radiances[channel] = ArHosekSkyModel_CookRadianceConfiguration( datasetsXYZRad[channel], turbidity, albedo, elevation); } return state; } ArHosekSkyModelState *arhosek_rgb_skymodelstate_alloc_init( const float turbidity, const float albedo, const float elevation) { ArHosekSkyModelState *state = ALLOC(ArHosekSkyModelState); state->solar_radius = TERRESTRIAL_SOLAR_RADIUS; state->turbidity = turbidity; state->albedo = albedo; state->elevation = elevation; for (unsigned int channel = 0; channel < 3; ++channel) { ArHosekSkyModel_CookConfiguration(datasetsRGB[channel], state->configs[channel], turbidity, albedo, elevation); state->radiances[channel] = ArHosekSkyModel_CookRadianceConfiguration( datasetsRGBRad[channel], turbidity, albedo, elevation); } return state; } float arhosek_tristim_skymodel_radiance( ArHosekSkyModelState *state, float theta, float gamma, int channel) { return ArHosekSkyModel_GetRadianceInternal( state->configs[channel], theta, gamma) * state->radiances[channel]; } const int pieces = 45; const int order = 4; float arhosekskymodel_sr_internal( ArHosekSkyModelState *state, int turbidity, int wl, float elevation) { int pos = (int)(pow(2.0 * elevation / MATH_PI, 1.0 / 3.0) * pieces); // floor if (pos > 44) pos = 44; const float break_x = pow(((float)pos / (float)pieces), 3.0) * (MATH_PI * 0.5); const float *coefs = solarDatasets[wl] + (order * pieces * turbidity + order * (pos + 1) - 1); float res = 0.0; const float x = elevation - break_x; float x_exp = 1.0; for (int i = 0; i < order; ++i) { res += x_exp * *coefs--; x_exp *= x; } return res * state->emission_correction_factor_sun[wl]; } float arhosekskymodel_solar_radiance_internal2(ArHosekSkyModelState *state, float wavelength, float elevation, float gamma) { assert(wavelength >= 320.0 && wavelength <= 720.0 && state->turbidity >= 1.0 && state->turbidity <= 10.0); int turb_low = (int)state->turbidity - 1; float turb_frac = state->turbidity - (float)(turb_low + 1); if (turb_low == 9) { turb_low = 8; turb_frac = 1.0; } int wl_low = (int)((wavelength - 320.0) / 40.0); float wl_frac = fmod(wavelength, 40.0) / 40.0; if (wl_low == 10) { wl_low = 9; wl_frac = 1.0; } float direct_radiance = (1.0 - turb_frac) * ((1.0 - wl_frac) * arhosekskymodel_sr_internal( state, turb_low, wl_low, elevation) + wl_frac * arhosekskymodel_sr_internal( state, turb_low, wl_low + 1, elevation)) + turb_frac * ((1.0 - wl_frac) * arhosekskymodel_sr_internal( state, turb_low + 1, wl_low, elevation) + wl_frac * arhosekskymodel_sr_internal( state, turb_low + 1, wl_low + 1, elevation)); float ldCoefficient[6]; for (int i = 0; i < 6; i++) ldCoefficient[i] = (1.0 - wl_frac) * limbDarkeningDatasets[wl_low][i] + wl_frac * limbDarkeningDatasets[wl_low + 1][i]; // sun distance to diameter ratio, squared const float sol_rad_sin = sin(state->solar_radius); const float ar2 = 1 / (sol_rad_sin * sol_rad_sin); const float singamma = sin(gamma); float sc2 = 1.0 - ar2 * singamma * singamma; if (sc2 < 0.0) sc2 = 0.0; float sampleCosine = sqrt(sc2); // The following will be improved in future versions of the model: // here, we directly use fitted 5th order polynomials provided by the // astronomical community for the limb darkening effect. Astronomers need // such accurate fittings for their predictions. However, this sort of // accuracy is not really needed for CG purposes, so an approximated // dataset based on quadratic polynomials will be provided in a future // release. float darkeningFactor = ldCoefficient[0] + ldCoefficient[1] * sampleCosine + ldCoefficient[2] * pow(sampleCosine, 2.0) + ldCoefficient[3] * pow(sampleCosine, 3.0) + ldCoefficient[4] * pow(sampleCosine, 4.0) + ldCoefficient[5] * pow(sampleCosine, 5.0); direct_radiance *= darkeningFactor; return direct_radiance; } float arhosekskymodel_solar_radiance( ArHosekSkyModelState *state, float theta, float gamma, float wavelength) { float direct_radiance = arhosekskymodel_solar_radiance_internal2( state, wavelength, ((MATH_PI / 2.0) - theta), gamma); float inscattered_radiance = arhosekskymodel_radiance(state, theta, gamma, wavelength); return direct_radiance + inscattered_radiance; } RenderKit-ospray-85af292/modules/cpu/lights/sky_model/sky_model.h000066400000000000000000000454531464752671100251640ustar00rootroot00000000000000/* This source is published under the following 3-clause BSD license. Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * None of the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // with slight modifications // Copyright 2020 Intel Corporation /* ============================================================================ This file is part of a sample implementation of the analytical skylight and solar radiance models presented in the SIGGRAPH 2012 paper "An Analytic Model for Full Spectral Sky-Dome Radiance" and the 2013 IEEE CG&A paper "Adding a Solar Radiance Function to the Hosek Skylight Model" both by Lukas Hosek and Alexander Wilkie Charles University in Prague, Czech Republic Version: 1.4a, February 22nd, 2013 Version history: 1.4a February 22nd, 2013 Removed unnecessary and counter-intuitive solar radius parameters from the interface of the colourspace sky dome initialisation functions. 1.4 February 11th, 2013 Fixed a bug which caused the relative brightness of the solar disc and the sky dome to be off by a factor of about 6. The sun was too bright: this affected both normal and alien sun scenarios. The coefficients of the solar radiance function were changed to fix this. 1.3 January 21st, 2013 (not released to the public) Added support for solar discs that are not exactly the same size as the terrestrial sun. Also added support for suns with a different emission spectrum ("Alien World" functionality). 1.2a December 18th, 2012 Fixed a mistake and some inaccuracies in the solar radiance function explanations found in ArHosekSkyModel.h. The actual source code is unchanged compared to version 1.2. 1.2 December 17th, 2012 Native RGB data and a solar radiance function that matches the turbidity conditions were added. 1.1 September 2012 The coefficients of the spectral model are now scaled so that the output is given in physical units: W / (m^-2 * sr * nm). Also, the output of the XYZ model is now no longer scaled to the range [0...1]. Instead, it is the result of a simple conversion from spectral data via the CIE 2 degree standard observer matching functions. Therefore, after multiplication with 683 lm / W, the Y channel now corresponds to luminance in lm. 1.0 May 11th, 2012 Initial release. Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if an updated version of this code has been published! ============================================================================ */ /* This code is taken from ART, a rendering research system written in a mix of C99 / Objective C. Since ART is not a small system and is intended to be inter-operable with other libraries, and since C does not have namespaces, the structures and functions in ART all have to have somewhat wordy canonical names that begin with Ar.../ar..., like those seen in this example. Usage information: ================== Model initialisation -------------------- A separate ArHosekSkyModelState has to be maintained for each spectral band you want to use the model for. So in a renderer with 'num_channels' bands, you would need something like ArHosekSkyModelState * skymodel_state[num_channels]; You then have to allocate and initialise these states. In the following code snippet, we assume that 'albedo' is defined as float albedo[num_channels]; with a ground albedo value between [0,1] for each channel. The solar elevation is given in radians. for ( unsigned int i = 0; i < num_channels; i++ ) skymodel_state[i] = arhosekskymodelstate_alloc_init( turbidity, albedo[i], solarElevation ); Note that starting with version 1.3, there is also a second initialisation function which generates skydome states for different solar emission spectra and solar radii: 'arhosekskymodelstate_alienworld_alloc_init()'. See the notes about the "Alien World" functionality provided further down for a discussion of the usefulness and limits of that second initialisation function. Sky model states that have been initialised with either function behave in a completely identical fashion during use and cleanup. Using the model to generate skydome samples ------------------------------------------- Generating a skydome radiance spectrum "skydome_result" for a given location on the skydome determined via the angles theta and gamma works as follows: float skydome_result[num_channels]; for ( unsigned int i = 0; i < num_channels; i++ ) skydome_result[i] = arhosekskymodel_radiance( skymodel_state[i], theta, gamma, channel_center[i] ); The variable "channel_center" is assumed to hold the channel center wavelengths for each of the num_channels samples of the spectrum we are building. Cleanup after use ----------------- After rendering is complete, the content of the sky model states should be disposed of via for ( unsigned int i = 0; i < num_channels; i++ ) arhosekskymodelstate_free( skymodel_state[i] ); CIE XYZ Version of the Model ---------------------------- Usage of the CIE XYZ version of the model is exactly the same, except that num_channels is of course always 3, and that ArHosekTristimSkyModelState and arhosek_tristim_skymodel_radiance() have to be used instead of their spectral counterparts. RGB Version of the Model ------------------------ The RGB version uses sRGB primaries with a linear gamma ramp. The same set of functions as with the XYZ data is used, except the model is initialized by calling arhosek_rgb_skymodelstate_alloc_init. Solar Radiance Function ----------------------- For each position on the solar disc, this function returns the entire radiance one sees - direct emission, as well as in-scattered light in the area of the solar disc. The latter is important for low solar elevations - nice images of the setting sun would not be possible without this. This is also the reason why this function, just like the regular sky dome model evaluation function, needs access to the sky dome data structures, as these provide information on in-scattered radiance. CAVEAT #1: in this release, this function is only provided in spectral form! RGB/XYZ versions to follow at a later date. CAVEAT #2: (fixed from release 1.3 onwards) CAVEAT #3: limb darkening renders the brightness of the solar disc inhomogeneous even for high solar elevations - only taking a single sample at the centre of the sun will yield an incorrect power estimate for the solar disc! Always take multiple random samples across the entire solar disc to estimate its power! CAVEAT #4: in this version, the limb darkening calculations still use a fairly computationally expensive 5th order polynomial that was directly taken from astronomical literature. For the purposes of Computer Graphics, this is needlessly accurate, though, and will be replaced by a cheaper approximation in a future release. "Alien World" functionality --------------------------- The Hosek sky model can be used to roughly (!) predict the appearance of outdoor scenes on earth-like planets, i.e. planets of a similar size and atmospheric make-up. Since the spectral version of our model predicts sky dome luminance patterns and solar radiance independently for each waveband, and since the intensity of each waveband is solely dependent on the input radiance from the star that the world in question is orbiting, it is trivial to re-scale the wavebands to match a different star radiance. At least in theory, the spectral version of the model has always been capable of this sort of thing, and the actual sky dome and solar radiance models were actually not altered at all in this release. All we did was to add some support functionality for doing this more easily with the existing data and functions, and to add some explanations. Just use 'arhosekskymodelstate_alienworld_alloc_init()' to initialise the sky model states (you will have to provide values for star temperature and solar intensity compared to the terrestrial sun), and do everything else as you did before. CAVEAT #1: we assume the emission of the star that illuminates the alien world to be a perfect blackbody emission spectrum. This is never entirely realistic - real star emission spectra are considerably more complex than this, mainly due to absorption effects in the outer layers of stars. However, blackbody spectra are a reasonable first assumption in a usage scenario like this, where 100% accuracy is simply not necessary: for rendering purposes, there are likely no visible differences between a highly accurate solution based on a more involved simulation, and this approximation. CAVEAT #2: we always use limb darkening data from our own sun to provide this "appearance feature", even for suns of strongly different temperature. Which is presumably not very realistic, but (as with the unaltered blackbody spectrum from caveat #1) probably not a bad first guess, either. If you need more accuracy than we provide here, please make inquiries with a friendly astro-physicst of your choice. CAVEAT #3: you have to provide a value for the solar intensity of the star which illuminates the alien world. For this, please bear in mind that there is very likely a comparatively tight range of absolute solar irradiance values for which an earth-like planet with an atmosphere like the one we assume in our model can exist in the first place! Too much irradiance, and the atmosphere probably boils off into space, too little, it freezes. Which means that stars of considerably different emission colour than our sun will have to be fairly different in size from it, to still provide a reasonable and inhabitable amount of irradiance. Red stars will need to be much larger than our sun, while white or blue stars will have to be comparatively tiny. The initialisation function handles this and computes a plausible solar radius for a given emission spectrum. In terms of absolute radiometric values, you should probably not stray all too far from a solar intensity value of 1.0. CAVEAT #4: although we now support different solar radii for the actual solar disc, the sky dome luminance patterns are *not* parameterised by this value - i.e. the patterns stay exactly the same for different solar radii! Which is of course not correct. But in our experience, solar discs up to several degrees in diameter (! - our own sun is half a degree across) do not cause the luminance patterns on the sky to change perceptibly. The reason we know this is that we initially used unrealistically large suns in our brute force path tracer, in order to improve convergence speeds (which in the beginning were abysmal). Later, we managed to do the reference renderings much faster even with realistically small suns, and found that there was no real difference in skydome appearance anyway. Conclusion: changing the solar radius should not be over-done, so close orbits around red supergiants are a no-no. But for the purposes of getting a fairly credible first impression of what an alien world with a reasonably sized sun would look like, what we are doing here is probably still o.k. HINT #1: if you want to model the sky of an earth-like planet that orbits a binary star, just super-impose two of these models with solar intensity of ~0.5 each, and closely spaced solar positions. Light is additive, after all. Tattooine, here we come... :-) P.S. according to Star Wars canon, Tattooine orbits a binary that is made up of a G and K class star, respectively. So ~5500K and ~4200K should be good first guesses for their temperature. Just in case you were wondering, after reading the previous paragraph. */ #ifndef _ARHOSEK_SKYMODEL_H_ #define _ARHOSEK_SKYMODEL_H_ typedef float ArHosekSkyModelConfiguration[9]; // Spectral version of the model /* ---------------------------------------------------------------------------- ArHosekSkyModelState struct --------------------------- This struct holds the pre-computation data for one particular albedo value. Most fields are self-explanatory, but users should never directly manipulate any of them anyway. The only consistent way to manipulate such structs is via the functions 'arhosekskymodelstate_alloc_init' and 'arhosekskymodelstate_free'. 'emission_correction_factor_sky' 'emission_correction_factor_sun' The original model coefficients were fitted against the emission of our local sun. If a different solar emission is desired (i.e. if the model is being used to predict skydome appearance for an earth-like planet that orbits a different star), these correction factors, which are determined during the alloc_init step, are applied to each waveband separately (they default to 1.0 in normal usage). This is the simplest way to retrofit this sort of capability to the existing model. The different factors for sky and sun are needed since the solar disc may be of a different size compared to the terrestrial sun. ---------------------------------------------------------------------------- */ typedef struct ArHosekSkyModelState { ArHosekSkyModelConfiguration configs[11]; float radiances[11]; float turbidity; float solar_radius; float emission_correction_factor_sky[11]; float emission_correction_factor_sun[11]; float albedo; float elevation; } ArHosekSkyModelState; /* ---------------------------------------------------------------------------- arhosekskymodelstate_alloc_init() function ------------------------------------------ Initialises an ArHosekSkyModelState struct for a terrestrial setting. ---------------------------------------------------------------------------- */ ArHosekSkyModelState *arhosekskymodelstate_alloc_init( const float solar_elevation, const float atmospheric_turbidity, const float ground_albedo); /* ---------------------------------------------------------------------------- arhosekskymodelstate_alienworld_alloc_init() function ----------------------------------------------------- Initialises an ArHosekSkyModelState struct for an "alien world" setting with a sun of a surface temperature given in 'kelvin'. The parameter 'solar_intensity' controls the overall brightness of the sky, relative to the solar irradiance on Earth. A value of 1.0 yields a sky dome that is, on average over the wavelengths covered in the model (!), as bright as the terrestrial sky in radiometric terms. Which means that the solar radius has to be adjusted, since the emissivity of a solar surface with a given temperature is more or less fixed. So hotter suns have to be smaller to be equally bright as the terrestrial sun, while cooler suns have to be larger. Note that there are limits to the validity of the luminance patterns of the underlying model: see the discussion above for more on this. In particular, an alien sun with a surface temperature of only 2000 Kelvin has to be very large if it is to be as bright as the terrestrial sun - so large that the luminance patterns are no longer a really good fit in that case. If you need information about the solar radius that the model computes for a given temperature (say, for light source sampling purposes), you have to query the 'solar_radius' variable of the sky model state returned *after* running this function. ---------------------------------------------------------------------------- */ ArHosekSkyModelState *arhosekskymodelstate_alienworld_alloc_init( const float solar_elevation, const float solar_intensity, const float solar_surface_temperature_kelvin, const float atmospheric_turbidity, const float ground_albedo); void arhosekskymodelstate_free(ArHosekSkyModelState *state); float arhosekskymodel_radiance( ArHosekSkyModelState *state, float theta, float gamma, float wavelength); // CIE XYZ and RGB versions ArHosekSkyModelState *arhosek_xyz_skymodelstate_alloc_init( const float turbidity, const float albedo, const float elevation); ArHosekSkyModelState *arhosek_rgb_skymodelstate_alloc_init( const float turbidity, const float albedo, const float elevation); float arhosek_tristim_skymodel_radiance( ArHosekSkyModelState *state, float theta, float gamma, int channel); // Delivers the complete function: sky + sun, including limb darkening. // Please read the above description before using this - there are several // caveats! float arhosekskymodel_solar_radiance( ArHosekSkyModelState *state, float theta, float gamma, float wavelength); float arhosekskymodel_solar_radiance_internal2(ArHosekSkyModelState *state, float wavelength, float elevation, float gamma); #endif // _ARHOSEK_SKYMODEL_H_ RenderKit-ospray-85af292/modules/cpu/lights/sky_model/sky_model_data_ciexyz.h000066400000000000000000002303761464752671100275500ustar00rootroot00000000000000/* This source is published under the following 3-clause BSD license. Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * None of the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // with slight modifications // Copyright 2020 Intel Corporation /* ============================================================================ This file is part of a sample implementation of the analytical skylight and solar radiance models presented in the SIGGRAPH 2012 paper "An Analytic Model for Full Spectral Sky-Dome Radiance" and the 2013 IEEE CG&A paper "Adding a Solar Radiance Function to the Hosek Skylight Model" both by Lukas Hosek and Alexander Wilkie Charles University in Prague, Czech Republic Version: 1.4a, February 22nd, 2013 Version history: 1.4a February 22nd, 2013 Removed unnecessary and counter-intuitive solar radius parameters from the interface of the colourspace sky dome initialisation functions. 1.4 February 11th, 2013 Fixed a bug which caused the relative brightness of the solar disc and the sky dome to be off by a factor of about 6. The sun was too bright: this affected both normal and alien sun scenarios. The coefficients of the solar radiance function were changed to fix this. 1.3 January 21st, 2013 (not released to the public) Added support for solar discs that are not exactly the same size as the terrestrial sun. Also added support for suns with a different emission spectrum ("Alien World" functionality). 1.2a December 18th, 2012 Fixed a mistake and some inaccuracies in the solar radiance function explanations found in ArHosekSkyModel.h. The actual source code is unchanged compared to version 1.2. 1.2 December 17th, 2012 Native RGB data and a solar radiance function that matches the turbidity conditions were added. 1.1 September 2012 The coefficients of the spectral model are now scaled so that the output is given in physical units: W / (m^-2 * sr * nm). Also, the output of the XYZ model is now no longer scaled to the range [0...1]. Instead, it is the result of a simple conversion from spectral data via the CIE 2 degree standard observer matching functions. Therefore, after multiplication with 683 lm / W, the Y channel now corresponds to luminance in lm. 1.0 May 11th, 2012 Initial release. Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if an updated version of this code has been published! ============================================================================ */ /* This file contains the coefficient data for the XYZ colour space version of the model. */ // Uses Sep 9 pattern / Aug 23 mean dataset static float datasetXYZ1[] = { // albedo 0, turbidity 1 -1.117001e+000, -1.867262e-001, -1.113505e+001, 1.259865e+001, -3.937339e-002, 1.167571e+000, 7.100686e-003, 3.592678e+000, 6.083296e-001, -1.152006e+000, -1.926669e-001, 6.152049e+000, -4.770802e+000, -8.704701e-002, 7.483626e-001, 3.372718e-002, 4.464592e+000, 4.036546e-001, -1.072371e+000, -2.696632e-001, 2.816168e-001, 1.820571e+000, -3.742666e-001, 2.080607e+000, -7.675295e-002, -2.835366e+000, 1.129329e+000, -1.109935e+000, -1.532764e-001, 1.198787e+000, -9.015183e-001, 5.173015e-003, 5.749178e-001, 1.075633e-001, 4.387949e+000, 2.650413e-001, -1.052297e+000, -2.229452e-001, 1.952347e+000, 5.727205e-001, -4.885070e+000, 1.984016e+000, -1.106197e-001, -4.898361e-001, 8.907873e-001, -1.070108e+000, -1.600465e-001, 1.593886e+000, -4.479251e-005, -3.306541e+000, 9.390193e-001, 9.513168e-002, 2.343583e+000, 5.335404e-001, // albedo 0, turbidity 2 -1.113253e+000, -1.699600e-001, -1.038822e+001, 1.137513e+001, -4.040911e-002, 1.037455e+000, 4.991792e-002, 4.801919e+000, 6.302710e-001, -1.135747e+000, -1.678594e-001, 4.970755e+000, -4.430230e+000, -6.657408e-002, 3.636161e-001, 1.558009e-001, 6.013370e+000, 3.959601e-001, -1.095892e+000, -2.732595e-001, 7.666496e-001, 1.350731e+000, -4.401401e-001, 2.470135e+000, -1.707929e-001, -3.260793e+000, 1.170337e+000, -1.073668e+000, -2.603929e-002, -1.944589e-001, 4.575207e-001, 6.878164e-001, -1.390770e-001, 3.690299e-001, 7.885781e+000, 1.877694e-001, -1.070091e+000, -2.798957e-001, 2.338478e+000, -2.647221e+000, -7.387808e+000, 2.329210e+000, -1.644639e-001, -2.003710e+000, 9.874527e-001, -1.067120e+000, -1.418866e-001, 1.254090e+000, 6.053048e+000, -2.918892e+000, 5.322812e-001, 1.613053e-001, 3.018161e+000, 5.274090e-001, // albedo 0, turbidity 3 -1.129483e+000, -1.890619e-001, -9.065101e+000, 9.659923e+000, -3.607819e-002, 8.314359e-001, 8.181661e-002, 4.768868e+000, 6.339777e-001, -1.146420e+000, -1.883579e-001, 3.309173e+000, -3.127882e+000, -6.938176e-002, 3.987113e-001, 1.400581e-001, 6.283042e+000, 5.267076e-001, -1.128348e+000, -2.641305e-001, 1.223176e+000, 5.514952e-002, -3.490649e-001, 1.997784e+000, -4.123709e-002, -2.251251e+000, 9.483466e-001, -1.025820e+000, 1.404690e-002, -1.187406e+000, 2.729900e+000, 5.877588e-001, -2.761140e-001, 4.602633e-001, 8.305125e+000, 3.945001e-001, -1.083957e+000, -2.606679e-001, 2.207108e+000, -7.202803e+000, -5.968103e+000, 2.129455e+000, -7.789512e-002, -1.137688e+000, 8.871769e-001, -1.062465e+000, -1.512189e-001, 1.042881e+000, 1.427839e+001, -4.242214e+000, 4.038100e-001, 1.997780e-001, 2.814449e+000, 5.803196e-001, // albedo 0, turbidity 4 -1.175099e+000, -2.410789e-001, -1.108587e+001, 1.133404e+001, -1.819300e-002, 6.772942e-001, 9.605043e-002, 4.231166e+000, 6.239972e-001, -1.224207e+000, -2.883527e-001, 3.002206e+000, -2.649612e+000, -4.795418e-002, 4.984398e-001, 3.251434e-002, 4.851611e+000, 6.551019e-001, -1.136955e+000, -2.423048e-001, 1.058823e+000, -2.489236e-001, -2.462179e-001, 1.933140e+000, 9.106828e-002, -1.905869e-001, 8.171065e-001, -1.014535e+000, -8.262500e-003, -1.448017e+000, 2.295788e+000, 3.510334e-001, -1.477418e+000, 5.432449e-001, 5.762796e+000, 4.908751e-001, -1.070666e+000, -2.379780e-001, 1.844589e+000, -5.442448e+000, -4.012768e+000, 2.945275e+000, 9.854725e-003, 8.455959e-002, 8.145030e-001, -1.071525e+000, -1.777132e-001, 8.076590e-001, 9.925865e+000, -3.324623e+000, -6.367437e-001, 2.844581e-001, 2.248384e+000, 6.544022e-001, // albedo 0, turbidity 5 -1.218818e+000, -2.952382e-001, -1.345975e+001, 1.347153e+001, -6.814585e-003, 5.079068e-001, 1.197230e-001, 3.776949e+000, 5.836961e-001, -1.409868e+000, -5.114330e-001, 2.776539e+000, -2.039001e+000, -2.673769e-002, 4.145288e-001, 7.829342e-004, 2.275883e+000, 6.629691e-001, -1.069151e+000, -9.434247e-002, 7.293972e-001, -1.222473e+000, -1.533461e-001, 2.160357e+000, 4.626837e-002, 3.852415e+000, 8.593570e-001, -1.021306e+000, -1.149551e-001, -1.108414e+000, 4.178343e+000, 4.013665e-001, -2.222814e+000, 6.929462e-001, 1.392652e+000, 4.401662e-001, -1.074251e+000, -2.224002e-001, 1.372356e+000, -8.858704e+000, -3.922660e+000, 3.020018e+000, -1.458724e-002, 1.511186e+000, 8.288064e-001, -1.062048e+000, -1.526582e-001, 4.921067e-001, 1.485522e+001, -3.229936e+000, -8.426604e-001, 3.916243e-001, 2.678994e+000, 6.689264e-001, // albedo 0, turbidity 6 -1.257023e+000, -3.364700e-001, -1.527795e+001, 1.504223e+001, 2.717715e-003, 3.029910e-001, 1.636851e-001, 3.561663e+000, 5.283161e-001, -1.635124e+000, -7.329993e-001, 3.523939e+000, -2.566337e+000, -1.902543e-002, 5.505483e-001, -6.242176e-002, 1.065992e+000, 6.654236e-001, -9.295823e-001, 4.845834e-002, -2.992990e-001, -2.001327e-001, -8.019339e-002, 1.807806e+000, 9.020277e-002, 5.095372e+000, 8.639936e-001, -1.093740e+000, -2.148608e-001, -5.216240e-001, 2.119777e+000, 9.506454e-002, -1.831439e+000, 6.961204e-001, 1.102084e-001, 4.384319e-001, -1.044181e+000, -1.849257e-001, 9.071246e-001, -4.648901e+000, -2.279385e+000, 2.356502e+000, -4.169147e-002, 1.932557e+000, 8.296550e-001, -1.061451e+000, -1.458745e-001, 2.952267e-001, 8.967214e+000, -3.726228e+000, -5.022316e-001, 5.684877e-001, 3.102347e+000, 6.658443e-001, // albedo 0, turbidity 7 -1.332391e+000, -4.127769e-001, -9.328643e+000, 9.046194e+000, 3.457775e-003, 3.377425e-001, 1.530909e-001, 3.301209e+000, 4.997917e-001, -1.932002e+000, -9.947777e-001, -2.042329e+000, 3.586940e+000, -5.642182e-002, 8.130478e-001, -8.195988e-002, 1.118294e-001, 5.617231e-001, -8.707374e-001, 1.286999e-001, 1.820054e+000, -4.674706e+000, 3.317471e-003, 5.919018e-001, 1.975278e-001, 6.686519e+000, 9.631727e-001, -1.070378e+000, -3.030579e-001, -9.041938e-001, 6.200201e+000, 1.232207e-001, -3.650628e-001, 5.029403e-001, -2.903162e+000, 3.811408e-001, -1.063035e+000, -1.637545e-001, 5.853072e-001, -7.889906e+000, -1.200641e+000, 1.035018e+000, 1.192093e-001, 3.267054e+000, 8.416151e-001, -1.053655e+000, -1.562286e-001, 2.423683e-001, 1.128575e+001, -4.363262e+000, -7.314160e-002, 5.642088e-001, 2.514023e+000, 6.670457e-001, // albedo 0, turbidity 8 -1.366112e+000, -4.718287e-001, -7.876222e+000, 7.746900e+000, -9.182309e-003, 4.716076e-001, 8.320252e-002, 3.165603e+000, 5.392334e-001, -2.468204e+000, -1.336340e+000, -5.386723e+000, 7.072672e+000, -8.329266e-002, 8.636876e-001, -1.978177e-002, -1.326218e-001, 2.979222e-001, -9.653522e-001, -2.373416e-002, 1.810250e+000, -6.467262e+000, 1.410706e-001, -4.753717e-001, 3.003095e-001, 6.551163e+000, 1.151083e+000, -8.943186e-001, -2.487152e-001, -2.308960e-001, 8.512648e+000, 1.298402e-001, 1.034705e+000, 2.303509e-001, -3.924095e+000, 2.982717e-001, -1.146999e+000, -2.318784e-001, 8.992419e-002, -9.933614e+000, -8.860920e-001, -3.071656e-002, 2.852012e-001, 3.046199e+000, 8.599001e-001, -1.032399e+000, -1.645145e-001, 2.683599e-001, 1.327701e+001, -4.407670e+000, 7.709869e-002, 4.951727e-001, 1.957277e+000, 6.630943e-001, // albedo 0, turbidity 9 -1.469070e+000, -6.135092e-001, -6.506263e+000, 6.661315e+000, -3.835383e-002, 7.150413e-001, 7.784318e-003, 2.820577e+000, 6.756784e-001, -2.501583e+000, -1.247404e+000, -1.523462e+001, 1.633191e+001, -1.204803e-002, 5.896471e-001, -2.002023e-002, 1.144647e+000, 6.177874e-002, -2.438672e+000, -1.127291e+000, 5.731172e+000, -1.021350e+001, 6.165610e-002, -7.752641e-001, 4.708254e-001, 4.176847e+000, 1.200881e+000, -1.513427e-001, 9.792731e-002, -1.612349e+000, 9.814289e+000, 5.188921e-002, 1.716403e+000, -7.039255e-002, -2.815115e+000, 3.291874e-001, -1.318511e+000, -3.650554e-001, 4.221268e-001, -9.294529e+000, -4.397520e-002, -8.100625e-001, 3.742719e-001, 1.834166e+000, 8.223450e-001, -1.016009e+000, -1.820264e-001, 1.278426e-001, 1.182696e+001, -4.801528e+000, 4.947899e-001, 4.660378e-001, 1.601254e+000, 6.702359e-001, // albedo 0, turbidity 10 -1.841310e+000, -9.781779e-001, -4.610903e+000, 4.824662e+000, -5.100806e-002, 6.463776e-001, -6.377724e-006, 2.216875e+000, 8.618530e-001, -2.376373e+000, -1.108657e+000, -1.489799e+001, 1.546458e+001, 4.091025e-002, 9.761780e-002, -1.048958e-002, 2.165834e+000, -1.609171e-001, -4.710318e+000, -2.261963e+000, 6.947327e+000, -1.034828e+001, -1.325542e-001, 7.508674e-001, 2.247553e-001, 2.873142e+000, 1.297100e+000, 2.163750e-001, -1.944345e-001, -2.437860e+000, 1.011314e+001, 4.450500e-001, 3.111492e-001, 2.751323e-001, -1.627906e+000, 2.531213e-001, -1.258794e+000, -3.524641e-001, 8.425444e-001, -1.085313e+001, -1.154381e+000, -4.638014e-001, -2.781115e-003, 4.344498e-001, 8.507091e-001, -1.018938e+000, -1.804153e-001, -6.354054e-002, 1.573150e+001, -4.386999e+000, 6.211115e-001, 5.294648e-001, 1.580749e+000, 6.586655e-001, // albedo 1, turbidity 1 -1.116416e+000, -1.917524e-001, -1.068233e+001, 1.222221e+001, -3.668978e-002, 1.054022e+000, 1.592132e-002, 3.180583e+000, 5.627370e-001, -1.132341e+000, -1.671286e-001, 5.976499e+000, -4.227366e+000, -9.542489e-002, 8.664938e-001, 8.351793e-003, 4.876068e+000, 4.492779e-001, -1.087635e+000, -3.173679e-001, 4.314407e-001, 1.100555e+000, -4.410057e-001, 1.677253e+000, -3.005925e-002, -4.201249e+000, 1.070902e+000, -1.083031e+000, -8.847705e-002, 1.291773e+000, 4.546776e-001, 3.091894e-001, 7.261760e-001, 4.203659e-002, 5.990615e+000, 3.704756e-001, -1.057899e+000, -2.246706e-001, 2.329563e+000, -1.219656e+000, -5.335260e+000, 8.545378e-001, -3.906209e-002, -9.025499e-001, 7.797348e-001, -1.073305e+000, -1.522553e-001, 1.767063e+000, 1.904280e+000, -3.101673e+000, 3.995856e-001, 2.905192e-002, 2.563977e+000, 5.753067e-001, // albedo 1, turbidity 2 -1.113674e+000, -1.759694e-001, -9.754125e+000, 1.087391e+001, -3.841093e-002, 9.524272e-001, 5.680219e-002, 4.227034e+000, 6.029571e-001, -1.126496e+000, -1.680281e-001, 5.332352e+000, -4.575579e+000, -6.761755e-002, 3.295335e-001, 1.194896e-001, 5.570901e+000, 4.536185e-001, -1.103074e+000, -2.681801e-001, 6.571479e-002, 2.396522e+000, -4.551280e-001, 2.466331e+000, -1.232022e-001, -3.023201e+000, 1.086379e+000, -1.053299e+000, -2.697173e-002, 8.379121e-001, -9.681458e-001, 5.890692e-001, -4.872027e-001, 2.936929e-001, 7.510139e+000, 3.079122e-001, -1.079553e+000, -2.710448e-001, 2.462379e+000, -3.713554e-001, -8.534512e+000, 1.828242e+000, -1.686398e-001, -1.961340e+000, 8.941077e-001, -1.069741e+000, -1.396394e-001, 1.657868e+000, 3.236313e+000, -2.706344e+000, -2.948122e-001, 1.314816e-001, 2.868457e+000, 5.413403e-001, // albedo 1, turbidity 3 -1.131649e+000, -1.954455e-001, -7.751595e+000, 8.685861e+000, -4.910871e-002, 8.992952e-001, 4.710143e-002, 4.254818e+000, 6.821116e-001, -1.156689e+000, -1.884324e-001, 3.163519e+000, -3.091522e+000, -6.613927e-002, -2.575883e-002, 1.640065e-001, 6.073643e+000, 4.453468e-001, -1.079224e+000, -2.621389e-001, 9.446437e-001, 1.448479e+000, -3.969384e-001, 2.626638e+000, -8.101186e-002, -3.016355e+000, 1.076295e+000, -1.080832e+000, 1.033057e-002, -3.500156e-001, -3.281419e-002, 5.655512e-001, -1.156742e+000, 4.534710e-001, 8.774122e+000, 2.772869e-001, -1.051202e+000, -2.679975e-001, 2.719109e+000, -2.190316e+000, -6.878798e+000, 2.250481e+000, -2.030252e-001, -2.026527e+000, 9.701096e-001, -1.089849e+000, -1.598589e-001, 1.564748e+000, 6.869187e+000, -3.053670e+000, -6.110435e-001, 1.644472e-001, 2.370452e+000, 5.511770e-001, // albedo 1, turbidity 4 -1.171419e+000, -2.429746e-001, -8.991334e+000, 9.571216e+000, -2.772861e-002, 6.688262e-001, 7.683478e-002, 3.785611e+000, 6.347635e-001, -1.228554e+000, -2.917562e-001, 2.753986e+000, -2.491780e+000, -4.663434e-002, 3.118303e-001, 7.546506e-002, 4.463096e+000, 5.955071e-001, -1.093124e+000, -2.447767e-001, 9.097406e-001, 5.448296e-001, -2.957824e-001, 2.024167e+000, -5.152333e-004, -1.069081e+000, 9.369565e-001, -1.056994e+000, 1.569507e-002, -8.217491e-001, 1.870818e+000, 7.061930e-001, -1.483928e+000, 5.978206e-001, 6.864902e+000, 3.673332e-001, -1.054871e+000, -2.758129e-001, 2.712807e+000, -5.950110e+000, -6.554039e+000, 2.447523e+000, -1.895171e-001, -1.454292e+000, 9.131738e-001, -1.100218e+000, -1.746241e-001, 1.438505e+000, 1.115481e+001, -3.266076e+000, -8.837357e-001, 1.970100e-001, 1.991595e+000, 5.907821e-001, // albedo 1, turbidity 5 -1.207267e+000, -2.913610e-001, -1.103767e+001, 1.140724e+001, -1.416800e-002, 5.564047e-001, 8.476262e-002, 3.371255e+000, 6.221335e-001, -1.429698e+000, -5.374218e-001, 2.837524e+000, -2.221936e+000, -2.422337e-002, 9.313758e-002, 7.190250e-002, 1.869022e+000, 5.609035e-001, -1.002274e+000, -6.972810e-002, 4.031308e-001, -3.932997e-001, -1.521923e-001, 2.390646e+000, -6.893990e-002, 2.999661e+000, 1.017843e+000, -1.081168e+000, -1.178666e-001, -4.968080e-001, 3.919299e+000, 6.046866e-001, -2.440615e+000, 7.891538e-001, 2.140835e+000, 2.740470e-001, -1.050727e+000, -2.307688e-001, 2.276396e+000, -9.454407e+000, -5.505176e+000, 2.992620e+000, -2.450942e-001, 6.078372e-001, 9.606765e-001, -1.103752e+000, -1.810202e-001, 1.375044e+000, 1.589095e+001, -3.438954e+000, -1.265669e+000, 2.475172e-001, 1.680768e+000, 5.978056e-001, // albedo 1, turbidity 6 -1.244324e+000, -3.378542e-001, -1.111001e+001, 1.137784e+001, -7.896794e-003, 4.808023e-001, 9.249904e-002, 3.025816e+000, 5.880239e-001, -1.593165e+000, -7.027621e-001, 2.220896e+000, -1.437709e+000, -1.534738e-002, 6.286958e-002, 6.644555e-002, 1.091727e+000, 5.470080e-001, -9.136506e-001, 1.344874e-002, 7.772636e-001, -1.209396e+000, -1.408978e-001, 2.433718e+000, -1.041938e-001, 3.791244e+000, 1.037916e+000, -1.134968e+000, -1.803315e-001, -9.267335e-001, 4.576670e+000, 6.851928e-001, -2.805000e+000, 8.687208e-001, 1.161483e+000, 2.571688e-001, -1.017037e+000, -2.053943e-001, 2.361640e+000, -9.887818e+000, -5.122889e+000, 3.287088e+000, -2.594102e-001, 8.578927e-001, 9.592340e-001, -1.118723e+000, -1.934942e-001, 1.226023e+000, 1.674140e+001, -3.277335e+000, -1.629809e+000, 2.765232e-001, 1.637713e+000, 6.113963e-001, // albedo 1, turbidity 7 -1.314779e+000, -4.119915e-001, -1.241150e+001, 1.241578e+001, 2.344284e-003, 2.980837e-001, 1.414613e-001, 2.781731e+000, 4.998556e-001, -1.926199e+000, -1.020038e+000, 2.569200e+000, -1.081159e+000, -2.266833e-002, 3.588668e-001, 8.750078e-003, -2.452171e-001, 4.796758e-001, -7.780002e-001, 1.850647e-001, 4.445456e-002, -2.409297e+000, -7.816346e-002, 1.546790e+000, -2.807227e-002, 5.998176e+000, 1.132396e+000, -1.179326e+000, -3.578330e-001, -2.392933e-001, 6.467883e+000, 5.904596e-001, -1.869975e+000, 8.045839e-001, -2.498121e+000, 1.610633e-001, -1.009956e+000, -1.311896e-001, 1.726577e+000, -1.219356e+001, -3.466239e+000, 2.343602e+000, -2.252205e-001, 2.573681e+000, 1.027109e+000, -1.112460e+000, -2.063093e-001, 1.233051e+000, 2.058946e+001, -4.578074e+000, -1.145643e+000, 3.160192e-001, 1.420159e+000, 5.860212e-001, // albedo 1, turbidity 8 -1.371689e+000, -4.914196e-001, -1.076610e+001, 1.107405e+001, -1.485077e-002, 5.936218e-001, 3.685482e-002, 2.599968e+000, 6.002204e-001, -2.436997e+000, -1.377939e+000, 2.130141e-002, 1.079593e+000, -1.796232e-002, -3.933248e-002, 1.610711e-001, -6.901181e-001, 1.206416e-001, -8.743368e-001, 7.331370e-002, 8.734259e-001, -3.743126e+000, -3.151167e-002, 1.297596e+000, -7.634926e-002, 6.532873e+000, 1.435737e+000, -9.810197e-001, -3.521634e-001, -2.855205e-001, 7.134674e+000, 6.839748e-001, -1.394841e+000, 6.952036e-001, -4.633104e+000, -2.173401e-002, -1.122958e+000, -1.691536e-001, 1.382360e+000, -1.102913e+001, -2.608171e+000, 1.865111e+000, -1.345154e-001, 3.112342e+000, 1.094134e+000, -1.075586e+000, -2.077415e-001, 1.171477e+000, 1.793270e+001, -4.656858e+000, -1.036839e+000, 3.338295e-001, 1.042793e+000, 5.739374e-001, // albedo 1, turbidity 9 -1.465871e+000, -6.364486e-001, -8.833718e+000, 9.343650e+000, -3.223600e-002, 7.552848e-001, -3.121341e-006, 2.249164e+000, 8.094662e-001, -2.448924e+000, -1.270878e+000, -4.823703e+000, 5.853058e+000, -2.149127e-002, 3.581132e-002, -1.230276e-003, 4.892553e-001, -1.597657e-001, -2.419809e+000, -1.071337e+000, 1.575648e+000, -4.983580e+000, 9.545185e-003, 5.032615e-001, 4.186266e-001, 4.634147e+000, 1.433517e+000, -1.383278e-001, -2.797095e-002, -1.943067e-001, 6.679623e+000, 4.118280e-001, -2.744289e-001, -2.118722e-002, -4.337025e+000, 1.505072e-001, -1.341872e+000, -2.518572e-001, 1.027009e+000, -6.527103e+000, -1.081271e+000, 1.015465e+000, 2.845789e-001, 2.470371e+000, 9.278120e-001, -1.040640e+000, -2.367454e-001, 1.100744e+000, 8.827253e+000, -4.560794e+000, -7.287017e-001, 2.842503e-001, 6.336593e-001, 6.327335e-001, // albedo 1, turbidity 10 -1.877993e+000, -1.025135e+000, -4.311037e+000, 4.715016e+000, -4.711631e-002, 6.335844e-001, -7.665398e-006, 1.788017e+000, 9.001409e-001, -2.281540e+000, -1.137668e+000, -1.036869e+001, 1.136254e+001, 1.961739e-002, -9.836174e-002, -6.734567e-003, 1.320918e+000, -2.400807e-001, -4.904054e+000, -2.315781e+000, 5.735999e+000, -8.626257e+000, -1.255643e-001, 1.545446e+000, 1.396860e-001, 2.972897e+000, 1.429934e+000, 4.077067e-001, -1.833688e-001, -2.450939e+000, 9.119433e+000, 4.505361e-001, -1.340828e+000, 3.973690e-001, -1.785370e+000, 9.628711e-002, -1.296052e+000, -3.250526e-001, 1.813294e+000, -1.031485e+001, -1.388690e+000, 1.239733e+000, -8.989196e-002, -3.389637e-001, 9.639560e-001, -1.062181e+000, -2.423444e-001, 7.577592e-001, 1.566938e+001, -4.462264e+000, -5.742810e-001, 3.262259e-001, 9.461672e-001, 6.232887e-001, }; static float datasetXYZRad1[] = { // albedo 0, turbidity 1 1.560219e+000, 1.417388e+000, 1.206927e+000, 1.091949e+001, 5.931416e+000, 7.304788e+000, // albedo 0, turbidity 2 1.533049e+000, 1.560532e+000, 3.685059e-001, 1.355040e+001, 5.543711e+000, 7.792189e+000, // albedo 0, turbidity 3 1.471043e+000, 1.746088e+000, -9.299697e-001, 1.720362e+001, 5.473384e+000, 8.336416e+000, // albedo 0, turbidity 4 1.355991e+000, 2.109348e+000, -3.295855e+000, 2.264843e+001, 5.454607e+000, 9.304656e+000, // albedo 0, turbidity 5 1.244963e+000, 2.547533e+000, -5.841485e+000, 2.756879e+001, 5.576104e+000, 1.043287e+001, // albedo 0, turbidity 6 1.175532e+000, 2.784634e+000, -7.212225e+000, 2.975347e+001, 6.472980e+000, 1.092331e+001, // albedo 0, turbidity 7 1.082973e+000, 3.118094e+000, -8.934293e+000, 3.186879e+001, 8.473885e+000, 1.174019e+001, // albedo 0, turbidity 8 9.692500e-001, 3.349574e+000, -1.003810e+001, 3.147654e+001, 1.338931e+001, 1.272547e+001, // albedo 0, turbidity 9 8.547044e-001, 3.151538e+000, -9.095567e+000, 2.554995e+001, 2.273219e+001, 1.410398e+001, // albedo 0, turbidity 10 7.580340e-001, 2.311153e+000, -5.170814e+000, 1.229669e+001, 3.686529e+001, 1.598882e+001, // albedo 1, turbidity 1 1.664273e+000, 1.574468e+000, 1.422078e+000, 9.768247e+000, 1.447338e+001, 1.644988e+001, // albedo 1, turbidity 2 1.638295e+000, 1.719586e+000, 5.786675e-001, 1.239846e+001, 1.415419e+001, 1.728605e+001, // albedo 1, turbidity 3 1.572623e+000, 1.921559e+000, -7.714802e-001, 1.609246e+001, 1.420954e+001, 1.825908e+001, // albedo 1, turbidity 4 1.468395e+000, 2.211970e+000, -2.845869e+000, 2.075027e+001, 1.524822e+001, 1.937622e+001, // albedo 1, turbidity 5 1.355047e+000, 2.556469e+000, -4.960920e+000, 2.460237e+001, 1.648360e+001, 2.065648e+001, // albedo 1, turbidity 6 1.291642e+000, 2.742036e+000, -6.061967e+000, 2.602002e+001, 1.819144e+001, 2.116712e+001, // albedo 1, turbidity 7 1.194565e+000, 2.972120e+000, -7.295779e+000, 2.691805e+001, 2.124880e+001, 2.201819e+001, // albedo 1, turbidity 8 1.083631e+000, 3.047021e+000, -7.766096e+000, 2.496261e+001, 2.744264e+001, 2.291875e+001, // albedo 1, turbidity 9 9.707994e-001, 2.736459e+000, -6.308284e+000, 1.760860e+001, 3.776291e+001, 2.392150e+001, // albedo 1, turbidity 10 8.574294e-001, 1.865155e+000, -2.364707e+000, 4.337793e+000, 5.092831e+001, 2.523432e+001, }; static float datasetXYZ2[] = { // albedo 0, turbidity 1 -1.127942e+000, -1.905548e-001, -1.252356e+001, 1.375799e+001, -3.624732e-002, 1.055453e+000, 1.385036e-002, 4.176970e+000, 5.928345e-001, -1.155260e+000, -1.778135e-001, 6.216056e+000, -5.254116e+000, -8.787445e-002, 8.434621e-001, 4.025734e-002, 6.195322e+000, 3.111856e-001, -1.125624e+000, -3.217593e-001, 5.043919e-001, 1.686284e+000, -3.536071e-001, 1.476321e+000, -7.899019e-002, -4.522531e+000, 1.271691e+000, -1.081801e+000, -1.033234e-001, 9.995550e-001, 7.482946e-003, -6.776018e-002, 1.463141e+000, 9.492021e-002, 5.612723e+000, 1.298846e-001, -1.075320e+000, -2.402711e-001, 2.141284e+000, -1.203359e+000, -4.945188e+000, 1.437221e+000, -8.096750e-002, -1.028378e+000, 1.004164e+000, -1.073337e+000, -1.516517e-001, 1.639379e+000, 2.304669e+000, -3.214244e+000, 1.286245e+000, 5.613957e-002, 2.480902e+000, 4.999363e-001, // albedo 0, turbidity 2 -1.128399e+000, -1.857793e-001, -1.089863e+001, 1.172984e+001, -3.768099e-002, 9.439285e-001, 4.869335e-002, 4.845114e+000, 6.119211e-001, -1.114002e+000, -1.399280e-001, 4.963800e+000, -4.685500e+000, -7.780879e-002, 4.049736e-001, 1.586297e-001, 7.770264e+000, 3.449006e-001, -1.185472e+000, -3.403543e-001, 6.588322e-001, 1.133713e+000, -4.118674e-001, 2.061191e+000, -1.882768e-001, -4.372586e+000, 1.223530e+000, -1.002272e+000, 2.000703e-002, 7.073269e-002, 1.485075e+000, 5.005589e-001, 4.301494e-001, 3.626541e-001, 7.921098e+000, 1.574766e-001, -1.121006e+000, -3.007777e-001, 2.242051e+000, -4.571561e+000, -7.761071e+000, 2.053404e+000, -1.524018e-001, -1.886162e+000, 1.018208e+000, -1.058864e+000, -1.358673e-001, 1.389667e+000, 8.633409e+000, -3.437249e+000, 7.295429e-001, 1.514700e-001, 2.842513e+000, 5.014325e-001, // albedo 0, turbidity 3 -1.144464e+000, -2.043799e-001, -1.020188e+001, 1.071247e+001, -3.256693e-002, 7.860205e-001, 6.872719e-002, 4.824771e+000, 6.259836e-001, -1.170104e+000, -2.118626e-001, 4.391405e+000, -4.198900e+000, -7.111559e-002, 3.890442e-001, 1.024831e-001, 6.282535e+000, 5.365688e-001, -1.129171e+000, -2.552880e-001, 2.238298e-001, 7.314295e-001, -3.562730e-001, 1.881931e+000, -3.078716e-002, -1.039120e+000, 9.096301e-001, -1.042294e+000, 4.450203e-003, -5.116033e-001, 2.627589e+000, 6.098996e-001, -1.264638e-001, 4.325281e-001, 7.080503e+000, 4.583646e-001, -1.082293e+000, -2.723056e-001, 2.065076e+000, -8.143133e+000, -7.892212e+000, 2.142231e+000, -7.106240e-002, -1.122398e+000, 8.338505e-001, -1.071715e+000, -1.426568e-001, 1.095351e+000, 1.729783e+001, -3.851931e+000, 4.360514e-001, 2.114440e-001, 2.970832e+000, 5.944389e-001, // albedo 0, turbidity 4 -1.195909e+000, -2.590449e-001, -1.191037e+001, 1.207947e+001, -1.589842e-002, 6.297846e-001, 9.054772e-002, 4.285959e+000, 5.933752e-001, -1.245763e+000, -3.316637e-001, 4.293660e+000, -3.694011e+000, -4.699947e-002, 4.843684e-001, 2.130425e-002, 4.097549e+000, 6.530809e-001, -1.148742e+000, -1.902509e-001, -2.393233e-001, -2.441254e-001, -2.610918e-001, 1.846988e+000, 3.532866e-002, 2.660106e+000, 8.358294e-001, -1.016080e+000, -7.444960e-002, -5.053436e-001, 4.388855e+000, 6.054987e-001, -1.208300e+000, 5.817215e-001, 2.543570e+000, 4.726568e-001, -1.072027e+000, -2.101440e-001, 1.518378e+000, -1.060119e+001, -6.016546e+000, 2.649475e+000, -5.166992e-002, 1.571269e+000, 8.344622e-001, -1.072365e+000, -1.511201e-001, 7.478010e-001, 1.900732e+001, -3.950387e+000, -3.473907e-001, 3.797211e-001, 2.782949e+000, 6.296808e-001, // albedo 0, turbidity 5 -1.239423e+000, -3.136289e-001, -1.351100e+001, 1.349468e+001, -7.070423e-003, 5.012315e-001, 1.106008e-001, 3.803619e+000, 5.577948e-001, -1.452524e+000, -5.676944e-001, 2.993153e+000, -2.277288e+000, -2.168954e-002, 3.056720e-001, 1.152338e-002, 1.852697e+000, 6.427228e-001, -1.061421e+000, -4.590521e-002, 6.057022e-001, -1.096835e+000, -1.504952e-001, 2.344921e+000, -5.491832e-002, 5.268322e+000, 9.082253e-001, -1.042373e+000, -1.769498e-001, -1.075388e+000, 3.831712e+000, 3.154140e-001, -2.416458e+000, 7.909032e-001, -1.492892e-002, 3.854049e-001, -1.064159e+000, -1.892684e-001, 1.438685e+000, -8.166362e+000, -3.616364e+000, 3.275206e+000, -1.203825e-001, 2.039491e+000, 8.688057e-001, -1.070120e+000, -1.569508e-001, 4.124760e-001, 1.399683e+001, -3.547085e+000, -1.046326e+000, 4.973825e-001, 2.791231e+000, 6.503286e-001, // albedo 0, turbidity 6 -1.283579e+000, -3.609518e-001, -1.335397e+001, 1.315248e+001, -4.431938e-004, 3.769526e-001, 1.429824e-001, 3.573613e+000, 4.998696e-001, -1.657952e+000, -7.627948e-001, 1.958222e+000, -7.949816e-001, -2.882837e-002, 5.356149e-001, -5.191946e-002, 8.869955e-001, 6.263320e-001, -9.527600e-001, 6.494189e-002, 5.361303e-001, -2.129590e+000, -9.258630e-002, 1.604776e+000, 5.067770e-002, 6.376055e+000, 9.138052e-001, -1.080827e+000, -2.523120e-001, -7.154262e-001, 4.120085e+000, 1.878228e-001, -1.492158e+000, 6.881655e-001, -1.446611e+000, 4.040631e-001, -1.054075e+000, -1.665498e-001, 9.191052e-001, -6.636943e+000, -1.894826e+000, 2.107810e+000, -3.680499e-002, 2.655452e+000, 8.413840e-001, -1.061127e+000, -1.448849e-001, 2.667493e-001, 1.034103e+001, -4.285769e+000, -3.874504e-001, 5.998752e-001, 3.132426e+000, 6.652753e-001, // albedo 0, turbidity 7 -1.347345e+000, -4.287832e-001, -9.305553e+000, 9.133813e+000, -3.173527e-003, 3.977564e-001, 1.151420e-001, 3.320564e+000, 4.998134e-001, -1.927296e+000, -9.901372e-001, -2.593499e+000, 4.087421e+000, -5.833993e-002, 8.158929e-001, -4.681279e-002, 2.423716e-001, 4.938052e-001, -9.470092e-001, 7.325237e-002, 2.064735e+000, -5.167540e+000, -1.313751e-002, 4.832169e-001, 1.126295e-001, 6.970522e+000, 1.035022e+000, -1.022557e+000, -2.762616e-001, -9.375748e-001, 6.696739e+000, 2.200765e-001, -1.133253e-001, 5.492505e-001, -3.109391e+000, 3.321914e-001, -1.087444e+000, -1.836263e-001, 6.225024e-001, -8.576765e+000, -1.107637e+000, 7.859427e-001, 9.910909e-002, 3.112938e+000, 8.596261e-001, -1.051544e+000, -1.546262e-001, 2.371731e-001, 1.200502e+001, -4.527291e+000, 7.268862e-002, 5.571478e-001, 2.532873e+000, 6.662000e-001, // albedo 0, turbidity 8 -1.375576e+000, -4.840019e-001, -8.121290e+000, 8.058140e+000, -1.445661e-002, 5.123314e-001, 5.813321e-002, 3.203219e+000, 5.442318e-001, -2.325221e+000, -1.241463e+000, -7.063430e+000, 8.741369e+000, -7.829950e-002, 8.844273e-001, -3.471106e-002, 1.740583e-001, 2.814079e-001, -1.228700e+000, -2.013412e-001, 2.949042e+000, -7.371945e+000, 1.071753e-001, -2.491970e-001, 2.265223e-001, 6.391504e+000, 1.172389e+000, -7.601786e-001, -1.680631e-001, -7.584444e-001, 8.541356e+000, 8.222291e-002, 6.729633e-001, 3.206615e-001, -3.700940e+000, 2.710054e-001, -1.191166e+000, -2.672347e-001, 2.927498e-001, -9.713613e+000, -4.783721e-001, 2.352803e-001, 2.161949e-001, 2.691481e+000, 8.745447e-001, -1.030135e+000, -1.653301e-001, 2.263443e-001, 1.296157e+001, -4.650644e+000, 7.055709e-003, 5.091975e-001, 2.000370e+000, 6.603839e-001, // albedo 0, turbidity 9 -1.508018e+000, -6.460933e-001, -6.402745e+000, 6.545995e+000, -3.750320e-002, 6.921803e-001, 3.309819e-003, 2.797527e+000, 6.978446e-001, -2.333308e+000, -1.167837e+000, -1.746787e+001, 1.868630e+001, -8.948229e-003, 5.621946e-001, -3.402626e-002, 1.217943e+000, 1.149865e-002, -2.665953e+000, -1.226307e+000, 7.169725e+000, -1.159434e+001, 3.583420e-002, -3.074378e-001, 3.412248e-001, 4.422122e+000, 1.283791e+000, -9.705116e-002, 8.312991e-002, -2.160462e+000, 1.028235e+001, 3.543357e-002, 1.032049e+000, 1.058310e-001, -2.972898e+000, 2.418628e-001, -1.329617e+000, -3.699557e-001, 5.560117e-001, -9.730113e+000, 9.938865e-002, -3.071488e-001, 2.510691e-001, 1.777111e+000, 8.705142e-001, -1.019387e+000, -1.893247e-001, 1.194079e-001, 1.239436e+001, -4.799224e+000, 2.940213e-001, 4.841268e-001, 1.529724e+000, 6.582615e-001, // albedo 0, turbidity 10 -1.896737e+000, -1.005442e+000, -6.411032e+000, 6.548220e+000, -3.227596e-002, 5.717262e-001, -8.115192e-006, 2.296704e+000, 9.000749e-001, -2.411116e+000, -1.225587e+000, -1.753629e+001, 1.829393e+001, 1.247555e-002, 2.364616e-001, -5.114637e-003, 1.603778e+000, -2.224156e-001, -4.707121e+000, -2.074977e+000, 7.942300e+000, -1.132407e+001, -5.415654e-002, 5.446811e-001, 1.032493e-001, 4.010235e+000, 1.369802e+000, 1.010482e-001, -4.013305e-001, -2.674579e+000, 9.779409e+000, 1.782506e-001, 7.053045e-001, 4.200002e-001, -2.400671e+000, 1.953165e-001, -1.243526e+000, -3.391255e-001, 8.848882e-001, -9.789025e+000, -3.997324e-001, -9.546227e-001, -1.044017e-001, 6.010593e-001, 8.714462e-001, -1.014633e+000, -1.730009e-001, -7.738934e-002, 1.390903e+001, -4.847307e+000, 1.076059e+000, 5.685743e-001, 1.572992e+000, 6.561432e-001, // albedo 1, turbidity 1 -1.122998e+000, -1.881183e-001, -1.030709e+001, 1.158932e+001, -4.079495e-002, 9.603774e-001, 3.079436e-002, 4.009235e+000, 5.060745e-001, -1.134790e+000, -1.539688e-001, 5.478405e+000, -4.217270e+000, -1.043858e-001, 7.165008e-001, 1.524765e-002, 6.473623e+000, 4.207882e-001, -1.134957e+000, -3.513318e-001, 7.393837e-001, 1.354415e+000, -4.764078e-001, 1.690441e+000, -5.492640e-002, -5.563523e+000, 1.145743e+000, -1.058344e+000, -5.758503e-002, 1.168230e+000, 3.269824e-001, 1.795193e-001, 7.849011e-001, 7.441853e-002, 6.904804e+000, 2.818790e-001, -1.075194e+000, -2.355813e-001, 2.463685e+000, -1.536505e+000, -7.505771e+000, 9.619712e-001, -6.465851e-002, -1.355492e+000, 8.489847e-001, -1.079030e+000, -1.465328e-001, 1.773838e+000, 2.310131e+000, -3.136065e+000, 3.507952e-001, 4.435014e-002, 2.819225e+000, 5.689008e-001, // albedo 1, turbidity 2 -1.125833e+000, -1.870849e-001, -9.555833e+000, 1.059713e+001, -4.225402e-002, 9.164663e-001, 4.338796e-002, 4.400980e+000, 6.056119e-001, -1.127440e+000, -1.551891e-001, 4.755621e+000, -4.408806e+000, -7.851763e-002, 2.268284e-001, 1.460070e-001, 7.048003e+000, 3.525997e-001, -1.143788e+000, -3.170178e-001, 5.480669e-001, 2.041830e+000, -4.532139e-001, 2.302233e+000, -1.887419e-001, -4.489221e+000, 1.250967e+000, -1.032849e+000, 7.376031e-003, 5.666073e-001, -2.312203e-001, 4.862894e-001, -1.748294e-001, 3.572870e-001, 8.380522e+000, 1.302333e-001, -1.093728e+000, -2.786977e-001, 2.641272e+000, -1.507494e+000, -8.731243e+000, 1.684055e+000, -2.023377e-001, -2.176398e+000, 1.013249e+000, -1.076578e+000, -1.456205e-001, 1.693935e+000, 2.945003e+000, -2.822673e+000, -2.520033e-001, 1.517034e-001, 2.649109e+000, 5.179094e-001, // albedo 1, turbidity 3 -1.146417e+000, -2.119353e-001, -7.187525e+000, 8.058599e+000, -5.256438e-002, 8.375733e-001, 3.887093e-002, 4.222111e+000, 6.695347e-001, -1.173674e+000, -2.067025e-001, 2.899359e+000, -2.804918e+000, -8.473899e-002, 3.944225e-003, 1.340641e-001, 6.160887e+000, 4.527141e-001, -1.090098e+000, -2.599633e-001, 9.180856e-001, 1.092710e+000, -4.215019e-001, 2.427660e+000, -9.277667e-002, -2.123523e+000, 1.058159e+000, -1.084460e+000, 8.056181e-003, -2.453510e-001, 6.619567e-001, 4.668118e-001, -9.526719e-001, 4.648454e-001, 8.001572e+000, 3.054194e-001, -1.053728e+000, -2.765784e-001, 2.792388e+000, -3.489517e+000, -8.150535e+000, 2.195757e+000, -2.017234e-001, -2.128017e+000, 9.326589e-001, -1.099348e+000, -1.593939e-001, 1.568292e+000, 7.247853e+000, -2.933000e+000, -5.890481e-001, 1.724440e-001, 2.433484e+000, 5.736558e-001, // albedo 1, turbidity 4 -1.185983e+000, -2.581184e-001, -7.761056e+000, 8.317053e+000, -3.351773e-002, 6.676667e-001, 5.941733e-002, 3.820727e+000, 6.324032e-001, -1.268591e+000, -3.398067e-001, 2.348503e+000, -2.023779e+000, -5.368458e-002, 1.083282e-001, 8.402858e-002, 3.910254e+000, 5.577481e-001, -1.071353e+000, -1.992459e-001, 7.878387e-001, 1.974702e-001, -3.033058e-001, 2.335298e+000, -8.205259e-002, 7.954454e-001, 9.972312e-001, -1.089513e+000, -3.104364e-002, -5.995746e-001, 2.330281e+000, 6.581939e-001, -1.821467e+000, 6.679973e-001, 5.090195e+000, 3.125161e-001, -1.040214e+000, -2.570934e-001, 2.660489e+000, -6.506045e+000, -7.053586e+000, 2.763153e+000, -2.433632e-001, -7.648176e-001, 9.452937e-001, -1.116052e+000, -1.831993e-001, 1.457694e+000, 1.163608e+001, -3.216426e+000, -1.045594e+000, 2.285002e-001, 1.817407e+000, 5.810396e-001, // albedo 1, turbidity 5 -1.230134e+000, -3.136264e-001, -8.909301e+000, 9.145006e+000, -1.055387e-002, 4.467317e-001, 1.016826e-001, 3.342964e+000, 5.633840e-001, -1.442907e+000, -5.593147e-001, 2.156447e+000, -1.241657e+000, -3.512130e-002, 3.050274e-001, 1.797175e-002, 1.742358e+000, 5.977153e-001, -1.027627e+000, -6.481539e-002, 4.351975e-001, -1.051677e+000, -2.030672e-001, 1.942684e+000, -3.615993e-002, 4.050266e+000, 9.801624e-001, -1.082110e+000, -1.578209e-001, -3.397511e-001, 4.163851e+000, 6.650368e-001, -1.841730e+000, 7.062544e-001, 6.789881e-001, 3.172623e-001, -1.047447e+000, -1.977560e-001, 2.183364e+000, -8.805249e+000, -5.483962e+000, 2.551309e+000, -1.779640e-001, 1.519501e+000, 9.212536e-001, -1.111853e+000, -1.935736e-001, 1.394408e+000, 1.392405e+001, -3.465430e+000, -1.068432e+000, 2.388671e-001, 1.455336e+000, 6.233425e-001, // albedo 1, turbidity 6 -1.262238e+000, -3.546341e-001, -1.008703e+001, 1.020084e+001, -1.852187e-003, 3.537580e-001, 1.239199e-001, 3.056093e+000, 5.132052e-001, -1.613810e+000, -7.355585e-001, 2.760123e+000, -1.685253e+000, -2.517552e-002, 2.914258e-001, 4.743448e-003, 8.689596e-001, 5.674192e-001, -9.462336e-001, 2.950767e-002, -2.613816e-001, -7.398653e-001, -1.315558e-001, 1.901042e+000, -6.447844e-002, 4.969341e+000, 1.027342e+000, -1.111481e+000, -2.194054e-001, -9.004538e-002, 3.983442e+000, 4.871278e-001, -1.965315e+000, 7.956121e-001, -2.363225e-001, 2.718037e-001, -1.036397e+000, -1.827106e-001, 1.964747e+000, -8.870759e+000, -4.208011e+000, 2.461215e+000, -2.158905e-001, 1.561676e+000, 9.436866e-001, -1.113769e+000, -1.947819e-001, 1.300720e+000, 1.516476e+001, -4.088732e+000, -1.069384e+000, 2.836434e-001, 1.671451e+000, 6.229612e-001, // albedo 1, turbidity 7 -1.328069e+000, -4.244047e-001, -8.417040e+000, 8.552244e+000, -6.813504e-003, 4.127422e-001, 9.619897e-002, 2.854227e+000, 5.059880e-001, -1.927552e+000, -1.025290e+000, 9.529576e-001, 4.255950e-001, -3.738779e-002, 2.584586e-001, 4.911004e-002, -2.640913e-001, 4.138626e-001, -8.488094e-001, 1.435988e-001, 6.356807e-001, -2.895732e+000, -8.473961e-002, 1.701305e+000, -1.323908e-001, 6.499338e+000, 1.210928e+000, -1.128313e+000, -3.397048e-001, -4.043140e-001, 6.265097e+000, 5.482395e-001, -2.057614e+000, 8.884087e-001, -2.943879e+000, 9.760301e-002, -1.039764e+000, -1.494772e-001, 1.781915e+000, -1.153012e+001, -3.379232e+000, 2.517231e+000, -2.764393e-001, 2.588849e+000, 1.052120e+000, -1.108447e+000, -2.012251e-001, 1.198640e+000, 1.925331e+001, -4.423892e+000, -1.257122e+000, 3.395690e-001, 1.481220e+000, 5.880175e-001, // albedo 1, turbidity 8 -1.374185e+000, -4.967434e-001, -7.401318e+000, 7.724021e+000, -2.345723e-002, 5.979653e-001, 2.436346e-002, 2.658970e+000, 6.014891e-001, -2.310933e+000, -1.290290e+000, -1.301909e+000, 2.557806e+000, -3.744449e-002, 8.982861e-002, 1.090613e-001, -4.398363e-001, 1.184329e-001, -1.124730e+000, -9.921830e-002, 1.366902e+000, -4.172489e+000, -5.078016e-002, 1.393597e+000, -9.323843e-002, 6.452721e+000, 1.435913e+000, -8.468477e-001, -2.744819e-001, -4.347200e-001, 6.713362e+000, 6.127133e-001, -1.685634e+000, 7.360941e-001, -4.535502e+000, -2.920866e-002, -1.165242e+000, -2.008697e-001, 1.438778e+000, -1.008936e+001, -2.214771e+000, 2.102909e+000, -1.763085e-001, 2.859075e+000, 1.093470e+000, -1.074614e+000, -2.066374e-001, 1.131891e+000, 1.630063e+001, -4.801441e+000, -1.112590e+000, 3.595785e-001, 1.122227e+000, 5.794610e-001, // albedo 1, turbidity 9 -1.521515e+000, -6.835604e-001, -5.571044e+000, 6.028774e+000, -4.253715e-002, 6.875746e-001, -5.279456e-006, 2.180150e+000, 8.487705e-001, -2.240415e+000, -1.171166e+000, -7.182771e+000, 8.417068e+000, -1.932866e-002, 1.101887e-001, -1.098862e-002, 6.242195e-001, -2.393875e-001, -2.712354e+000, -1.198830e+000, 3.180200e+000, -6.768130e+000, -2.563386e-003, 7.984607e-001, 2.764376e-001, 4.695358e+000, 1.557045e+000, -3.655172e-002, -2.142321e-002, -9.138120e-001, 7.932786e+000, 3.516542e-001, -7.994343e-001, 1.786761e-001, -4.208399e+000, 1.820576e-002, -1.368610e+000, -2.656212e-001, 1.249397e+000, -8.317818e+000, -8.962772e-001, 1.423249e+000, 1.478381e-001, 2.191660e+000, 1.007748e+000, -1.041753e+000, -2.453366e-001, 1.061102e+000, 1.130172e+001, -4.739312e+000, -9.223334e-001, 2.982776e-001, 6.162931e-001, 6.080302e-001, // albedo 1, turbidity 10 -1.989159e+000, -1.095160e+000, -2.915550e+000, 3.275339e+000, -5.735765e-002, 5.742174e-001, -7.683288e-006, 1.763400e+000, 9.001342e-001, -2.070020e+000, -1.086338e+000, -1.095898e+001, 1.206960e+001, 3.780123e-002, -1.774699e-002, -5.881348e-004, 1.333819e+000, -2.605423e-001, -5.249653e+000, -2.383040e+000, 6.160406e+000, -9.097138e+000, -1.955319e-001, 1.651785e+000, 6.016463e-004, 3.021824e+000, 1.493574e+000, 4.685432e-001, -2.358662e-001, -2.666433e+000, 9.685763e+000, 5.804928e-001, -1.521875e+000, 5.668989e-001, -1.548136e+000, 1.688642e-002, -1.296891e+000, -3.449031e-001, 1.928548e+000, -1.167560e+001, -1.627615e+000, 1.355603e+000, -1.929074e-001, -6.568952e-001, 1.009774e+000, -1.067288e+000, -2.410392e-001, 7.147961e-001, 1.783840e+001, -4.374399e+000, -6.588777e-001, 3.329831e-001, 1.012066e+000, 6.118645e-001, }; static float datasetXYZRad2[] = { // albedo 0, turbidity 1 1.632341e+000, 1.395230e+000, 1.375634e+000, 1.238193e+001, 5.921102e+000, 7.766508e+000, // albedo 0, turbidity 2 1.597115e+000, 1.554617e+000, 3.932382e-001, 1.505284e+001, 5.725234e+000, 8.158155e+000, // albedo 0, turbidity 3 1.522034e+000, 1.844545e+000, -1.322862e+000, 1.918382e+001, 5.440769e+000, 8.837119e+000, // albedo 0, turbidity 4 1.403048e+000, 2.290852e+000, -4.013792e+000, 2.485100e+001, 5.521888e+000, 9.845547e+000, // albedo 0, turbidity 5 1.286364e+000, 2.774498e+000, -6.648221e+000, 2.964151e+001, 5.923777e+000, 1.097075e+001, // albedo 0, turbidity 6 1.213544e+000, 3.040195e+000, -8.092676e+000, 3.186082e+001, 6.789782e+000, 1.158899e+001, // albedo 0, turbidity 7 1.122622e+000, 3.347465e+000, -9.649016e+000, 3.343824e+001, 9.347715e+000, 1.231374e+001, // albedo 0, turbidity 8 1.007356e+000, 3.543858e+000, -1.053520e+001, 3.239842e+001, 1.483962e+001, 1.331718e+001, // albedo 0, turbidity 9 8.956642e-001, 3.278700e+000, -9.254933e+000, 2.557923e+001, 2.489677e+001, 1.476166e+001, // albedo 0, turbidity 10 7.985143e-001, 2.340404e+000, -4.928274e+000, 1.141787e+001, 3.961501e+001, 1.682448e+001, // albedo 1, turbidity 1 1.745162e+000, 1.639467e+000, 1.342721e+000, 1.166033e+001, 1.490124e+001, 1.774031e+001, // albedo 1, turbidity 2 1.708439e+000, 1.819144e+000, 2.834399e-001, 1.448066e+001, 1.459214e+001, 1.858679e+001, // albedo 1, turbidity 3 1.631720e+000, 2.094799e+000, -1.378825e+000, 1.843198e+001, 1.463173e+001, 1.962881e+001, // albedo 1, turbidity 4 1.516536e+000, 2.438729e+000, -3.624121e+000, 2.298621e+001, 1.599782e+001, 2.070027e+001, // albedo 1, turbidity 5 1.405863e+000, 2.785191e+000, -5.705236e+000, 2.645121e+001, 1.768330e+001, 2.191903e+001, // albedo 1, turbidity 6 1.344052e+000, 2.951807e+000, -6.683851e+000, 2.744271e+001, 1.985706e+001, 2.229452e+001, // albedo 1, turbidity 7 1.245827e+000, 3.182923e+000, -7.822960e+000, 2.791395e+001, 2.327254e+001, 2.315910e+001, // albedo 1, turbidity 8 1.132305e+000, 3.202593e+000, -8.008429e+000, 2.521093e+001, 3.000014e+001, 2.405306e+001, // albedo 1, turbidity 9 1.020330e+000, 2.820556e+000, -6.238704e+000, 1.709276e+001, 4.077916e+001, 2.509949e+001, // albedo 1, turbidity 10 9.031570e-001, 1.863917e+000, -1.955738e+000, 3.032665e+000, 5.434290e+001, 2.641780e+001, }; static float datasetXYZ3[] = { // albedo 0, turbidity 1 -1.310023e+000, -4.407658e-001, -3.640340e+001, 3.683292e+001, -8.124762e-003, 5.297961e-001, 1.188633e-002, 3.138320e+000, 5.134778e-001, -1.424100e+000, -5.501606e-001, -1.753510e+001, 1.822769e+001, -1.539272e-002, 6.366826e-001, 2.661996e-003, 2.659915e+000, 4.071138e-001, -1.103436e+000, -1.884105e-001, 6.425322e+000, -6.910579e+000, -2.019861e-002, 3.553271e-001, -1.589061e-002, 5.345985e+000, 8.790218e-001, -1.186200e+000, -4.307514e-001, -3.957947e+000, 5.979352e+000, -5.348869e-002, 1.736117e+000, 3.491346e-002, -2.692261e+000, 5.610506e-001, -1.006038e+000, -1.305995e-001, 4.473513e+000, -3.806719e+000, 1.419407e-001, -2.148238e-002, -5.081185e-002, 3.735362e+000, 5.358280e-001, -1.078507e+000, -1.633754e-001, -3.812368e+000, 4.381700e+000, 2.988122e-002, 1.754224e+000, 1.472376e-001, 3.722798e+000, 4.999157e-001, // albedo 0, turbidity 2 -1.333582e+000, -4.649908e-001, -3.359528e+001, 3.404375e+001, -9.384242e-003, 5.587511e-001, 5.726310e-003, 3.073145e+000, 5.425529e-001, -1.562624e+000, -7.107068e-001, -1.478170e+001, 1.559839e+001, -1.462375e-002, 5.050133e-001, 2.516017e-002, 1.604696e+000, 2.902403e-001, -8.930158e-001, 4.068077e-002, 1.373481e+000, -2.342752e+000, -2.098058e-002, 6.248686e-001, -5.258363e-002, 7.058214e+000, 1.150373e+000, -1.262823e+000, -4.818353e-001, 8.892610e-004, 1.923120e+000, -4.979718e-002, 1.040693e+000, 1.558103e-001, -2.852480e+000, 2.420691e-001, -9.968383e-001, -1.200648e-001, 1.324342e+000, -9.430889e-001, 1.931098e-001, 4.436916e-001, -7.320456e-002, 4.215931e+000, 7.898019e-001, -1.078185e+000, -1.718192e-001, -1.720191e+000, 2.358918e+000, 2.765637e-002, 1.260245e+000, 2.021941e-001, 3.395483e+000, 5.173628e-001, // albedo 0, turbidity 3 -1.353023e+000, -4.813523e-001, -3.104920e+001, 3.140156e+001, -9.510741e-003, 5.542030e-001, 8.135471e-003, 3.136646e+000, 5.215989e-001, -1.624704e+000, -7.990201e-001, -2.167125e+001, 2.246341e+001, -1.163533e-002, 5.415746e-001, 2.618378e-002, 1.139214e+000, 3.444357e-001, -7.983610e-001, 1.417476e-001, 9.914841e+000, -1.081503e+001, -1.218845e-002, 3.411392e-001, -6.137698e-002, 7.445848e+000, 1.180080e+000, -1.266679e+000, -4.288977e-001, -5.818701e+000, 6.986437e+000, -8.180711e-002, 1.397403e+000, 2.016916e-001, -1.275731e+000, 2.592773e-001, -1.009707e+000, -1.537754e-001, 3.496378e+000, -3.013726e+000, 2.421150e-001, -2.831925e-001, 3.003395e-002, 3.702862e+000, 7.746320e-001, -1.075646e+000, -1.768747e-001, -1.347762e+000, 1.989004e+000, 1.375836e-002, 1.764810e+000, 1.330018e-001, 3.230864e+000, 6.626210e-001, // albedo 0, turbidity 4 -1.375269e+000, -5.103569e-001, -3.442661e+001, 3.478703e+001, -8.460009e-003, 5.408643e-001, 4.813323e-003, 3.016078e+000, 5.062069e-001, -1.821679e+000, -9.766461e-001, -1.926488e+001, 1.997912e+001, -9.822567e-003, 3.649556e-001, 4.316092e-002, 8.930190e-001, 4.166527e-001, -6.633542e-001, 1.997841e-001, 2.395592e+000, -3.117175e+000, -1.080884e-002, 8.983814e-001, -1.375825e-001, 6.673463e+000, 1.115663e+000, -1.303240e+000, -3.612712e-001, 8.292959e-002, 3.381364e-001, -6.078648e-002, 3.229247e-001, 3.680987e-001, 7.046755e-001, 3.144924e-001, -9.952598e-001, -2.039076e-001, 4.026851e-001, 2.686684e-001, 1.640712e-001, 5.186341e-001, -1.205520e-002, 2.659613e+000, 8.030394e-001, -1.098579e+000, -2.151992e-001, 6.558198e-001, -7.436900e-004, -1.421817e-003, 1.073701e+000, 1.886875e-001, 2.536857e+000, 6.673923e-001, // albedo 0, turbidity 5 -1.457986e+000, -5.906842e-001, -3.812464e+001, 3.838539e+001, -6.024357e-003, 4.741484e-001, 1.209223e-002, 2.818432e+000, 5.012433e-001, -1.835728e+000, -1.003405e+000, -6.848129e+000, 7.601943e+000, -1.277375e-002, 4.785598e-001, 3.366853e-002, 1.097701e+000, 4.636635e-001, -8.491348e-001, 9.466365e-003, -2.685226e+000, 2.004060e+000, -1.168708e-002, 6.752316e-001, -1.543371e-001, 5.674759e+000, 1.039534e+000, -1.083379e+000, -1.506790e-001, 7.328236e-001, -5.095568e-001, -8.609153e-002, 4.448820e-001, 4.174662e-001, 1.481556e+000, 3.942551e-001, -1.117089e+000, -3.337605e-001, 2.502281e-001, 4.036323e-001, 2.673899e-001, 2.829817e-001, 2.242450e-002, 2.043207e+000, 7.706902e-001, -1.071648e+000, -2.126200e-001, 6.069466e-001, -1.456290e-003, -5.515960e-001, 1.046755e+000, 1.985021e-001, 2.290245e+000, 6.876058e-001, // albedo 0, turbidity 6 -1.483903e+000, -6.309647e-001, -4.380213e+001, 4.410537e+001, -5.712161e-003, 5.195992e-001, 2.028428e-003, 2.687114e+000, 5.098321e-001, -2.053976e+000, -1.141473e+000, 5.109183e-001, 8.060391e-002, -1.033983e-002, 4.066532e-001, 4.869627e-002, 1.161722e+000, 4.039525e-001, -6.348185e-001, 7.651292e-002, -1.031327e+001, 1.007598e+001, -2.083688e-002, 7.359516e-001, -2.029459e-001, 5.013257e+000, 1.077649e+000, -1.228630e+000, -1.650496e-001, 4.077157e-002, -7.189167e-001, -5.092220e-002, 2.959814e-001, 5.111496e-001, 2.540433e+000, 3.615330e-001, -1.041883e+000, -3.278413e-001, -6.691911e-002, 1.307364e+000, 2.166663e-001, 3.000595e-001, -3.157136e-003, 1.389208e+000, 7.999026e-001, -1.103556e+000, -2.443602e-001, 4.705347e-001, -9.296482e-004, -5.309920e-001, 9.654511e-001, 2.142587e-001, 2.244723e+000, 6.839976e-001, // albedo 0, turbidity 7 -1.555684e+000, -6.962113e-001, -4.647983e+001, 4.674270e+001, -5.034895e-003, 4.755090e-001, -9.502561e-007, 2.626569e+000, 5.056194e-001, -1.998288e+000, -1.124720e+000, -1.629586e+000, 2.187993e+000, -8.284384e-003, 3.845258e-001, 5.726240e-002, 1.185644e+000, 4.255812e-001, -1.032570e+000, -2.513850e-001, -3.721112e+000, 3.506967e+000, -2.186561e-002, 9.436049e-001, -2.451412e-001, 4.725724e+000, 1.039256e+000, -8.597532e-001, 9.073332e-002, -2.553741e+000, 1.993237e+000, -4.390891e-002, -2.046928e-001, 5.515623e-001, 1.909127e+000, 3.948212e-001, -1.210482e+000, -4.477622e-001, -2.267805e-001, 1.219488e+000, 1.336186e-001, 6.866897e-001, 2.808997e-002, 1.600403e+000, 7.816409e-001, -1.078168e+000, -2.699261e-001, 2.537282e-001, 3.820684e-001, -4.425103e-001, 5.298235e-001, 2.185217e-001, 1.728679e+000, 6.882743e-001, // albedo 0, turbidity 8 -1.697968e+000, -8.391488e-001, -5.790105e+001, 5.814120e+001, -3.404760e-003, 4.265140e-001, -1.796301e-006, 2.368442e+000, 5.324429e-001, -2.141552e+000, -1.172230e+000, 1.677872e+001, -1.641470e+001, -5.732425e-003, 2.002199e-001, 6.841834e-002, 1.485338e+000, 3.215763e-001, -1.442946e+000, -7.264245e-001, -9.503706e+000, 9.650462e+000, -2.120995e-002, 1.419263e+000, -2.893098e-001, 3.860731e+000, 1.120857e+000, -5.696752e-001, 3.411279e-001, -2.931035e-001, -6.512552e-001, -1.068437e-001, -1.085661e+000, 6.107549e-001, 1.459503e+000, 3.210336e-001, -1.313839e+000, -5.921371e-001, -2.332222e-001, 1.648196e+000, 2.492787e-001, 1.381033e+000, -1.993392e-002, 9.812560e-001, 8.316329e-001, -1.087464e+000, -3.195534e-001, 2.902095e-001, 3.383709e-001, -8.798482e-001, 1.494668e-002, 2.529703e-001, 1.452644e+000, 6.693870e-001, // albedo 0, turbidity 9 -2.068582e+000, -1.118605e+000, -5.081598e+001, 5.097486e+001, -3.280669e-003, 4.067371e-001, -2.544951e-006, 2.179497e+000, 5.778017e-001, -1.744693e+000, -8.537207e-001, 2.234361e+001, -2.208318e+001, -5.932616e-003, 1.035049e-001, 5.742772e-002, 1.977880e+000, 2.124846e-001, -3.287515e+000, -2.140268e+000, -1.249566e+001, 1.240091e+001, -2.409349e-002, 1.397821e+000, -2.371627e-001, 2.771192e+000, 1.170496e+000, 5.502311e-001, 1.046630e+000, 2.193517e+000, -2.220400e+000, -1.064394e-001, -1.017926e+000, 4.795457e-001, 1.030644e+000, 3.177516e-001, -1.719734e+000, -9.536198e-001, -6.586821e-001, 1.386361e+000, -2.513065e-002, 1.187011e+000, 6.542539e-002, 5.296055e-001, 8.082660e-001, -1.005700e+000, -3.028096e-001, 4.470957e-002, 1.007760e+000, -8.119016e-001, 3.153338e-002, 2.311321e-001, 1.182208e+000, 6.824758e-001, // albedo 0, turbidity 10 -2.728867e+000, -1.580388e+000, -3.079627e+001, 3.092586e+001, -4.197673e-003, 3.154759e-001, -3.897675e-006, 1.920567e+000, 6.664791e-001, -1.322495e+000, -7.249275e-001, 1.477660e+001, -1.468154e+001, -9.044857e-003, 5.624314e-002, 6.498392e-002, 2.047389e+000, 6.367540e-002, -6.102376e+000, -3.473018e+000, -9.926071e+000, 9.637797e+000, -1.097909e-002, 1.103498e+000, -2.424521e-001, 2.520748e+000, 1.240260e+000, 1.351796e+000, 1.018588e+000, 2.009081e+000, -1.333394e+000, -1.979125e-001, -3.318292e-001, 4.476624e-001, 9.095235e-001, 2.955611e-001, -1.774467e+000, -1.079880e+000, -8.084680e-002, 2.577697e-001, -1.149295e-001, 4.975303e-001, 2.931611e-003, -3.803171e-001, 8.002794e-001, -9.898401e-001, -2.542513e-001, -7.530911e-002, 1.870355e+000, -1.521918e+000, 2.405164e-001, 2.964615e-001, 1.334800e+000, 6.789053e-001, // albedo 1, turbidity 1 -1.279730e+000, -4.290674e-001, -4.277972e+001, 4.343305e+001, -6.541826e-003, 4.945086e-001, 1.425338e-002, 2.685244e+000, 5.011313e-001, -1.449506e+000, -5.766374e-001, -1.688496e+001, 1.781118e+001, -1.121649e-002, 3.545020e-001, 2.287338e-002, 1.904281e+000, 4.936998e-001, -1.021980e+000, -1.897574e-001, 2.482462e+000, -2.941725e+000, -1.570448e-002, 7.532578e-001, -4.256800e-002, 5.239660e+000, 4.983116e-001, -1.162608e+000, -3.428049e-001, 3.974358e+000, -1.527935e+000, -3.919201e-002, 8.758593e-001, 7.291363e-002, -3.455257e+000, 8.007426e-001, -9.929985e-001, -8.712006e-002, -7.397313e-001, 1.348372e+000, 9.511685e-002, 3.233584e-001, -7.549148e-002, 5.806452e+000, 4.990042e-001, -1.084996e+000, -1.739767e-001, 1.580475e-001, 9.088180e-001, 6.871433e-002, 5.933079e-001, 1.188921e-001, 3.074079e+000, 4.999327e-001, // albedo 1, turbidity 2 -1.317009e+000, -4.661946e-001, -4.255347e+001, 4.312782e+001, -5.727235e-003, 4.285447e-001, 2.189854e-002, 2.608310e+000, 5.190700e-001, -1.469236e+000, -6.282139e-001, -1.241404e+001, 1.348765e+001, -1.204770e-002, 5.070285e-001, -7.280216e-004, 1.491533e+000, 3.635064e-001, -9.713808e-001, -8.138038e-002, 3.709854e-001, -1.041174e+000, -1.814075e-002, 5.060860e-001, -2.053756e-002, 6.161431e+000, 1.093736e+000, -1.159057e+000, -3.698074e-001, 2.711209e+000, -6.006479e-001, -4.896926e-002, 9.273957e-001, 1.137712e-001, -3.496828e+000, 2.867109e-001, -1.011601e+000, -8.201890e-002, 2.105725e-001, 4.597520e-001, 1.478925e-001, 2.138940e-001, -5.660670e-002, 6.057755e+000, 7.859121e-001, -1.078020e+000, -1.811580e-001, 1.646622e-001, 8.348426e-001, 1.149064e-001, 4.985738e-001, 1.376605e-001, 2.746607e+000, 4.999626e-001, // albedo 1, turbidity 3 -1.325672e+000, -4.769313e-001, -4.111215e+001, 4.168293e+001, -6.274997e-003, 4.649469e-001, 1.119411e-002, 2.631267e+000, 5.234546e-001, -1.619391e+000, -8.000253e-001, -1.534098e+001, 1.632706e+001, -1.012023e-002, 4.242255e-001, 2.931597e-002, 8.925807e-001, 3.314765e-001, -7.356979e-001, 1.368406e-001, 2.972579e+000, -3.535359e+000, -1.318948e-002, 4.607620e-001, -7.182778e-002, 6.254100e+000, 1.236299e+000, -1.316217e+000, -4.194427e-001, 3.489902e-002, 1.289849e+000, -4.755960e-002, 1.138222e+000, 1.975992e-001, -8.991542e-001, 2.290572e-001, -9.502188e-001, -1.172703e-001, 1.405202e+000, -3.061919e-001, 1.058772e-001, -3.760592e-001, -1.983179e-002, 3.562353e+000, 7.895959e-001, -1.100117e+000, -1.900567e-001, 4.925030e-001, 5.250225e-001, 1.576804e-001, 1.042701e+000, 7.330743e-002, 2.796064e+000, 6.749783e-001, // albedo 1, turbidity 4 -1.354183e+000, -5.130625e-001, -4.219268e+001, 4.271772e+001, -5.365373e-003, 4.136743e-001, 1.235172e-002, 2.520122e+000, 5.187269e-001, -1.741434e+000, -9.589761e-001, -8.230339e+000, 9.296799e+000, -9.600162e-003, 4.994969e-001, 2.955452e-002, 3.667099e-001, 3.526999e-001, -6.917347e-001, 2.154887e-001, -8.760264e-001, 2.334121e-001, -1.909621e-002, 4.748033e-001, -1.138514e-001, 6.515360e+000, 1.225097e+000, -1.293189e+000, -4.218700e-001, 1.620952e+000, -7.858597e-001, -3.769410e-002, 6.636786e-001, 3.364945e-001, -5.341017e-001, 2.128347e-001, -9.735521e-001, -1.325495e-001, 1.007517e+000, 2.598258e-001, 6.762169e-002, 1.421018e-003, -6.915987e-002, 3.185897e+000, 8.641956e-001, -1.094800e+000, -1.962062e-001, 5.755591e-001, 2.906259e-001, 2.625748e-001, 7.644049e-001, 1.347492e-001, 2.677126e+000, 6.465460e-001, // albedo 1, turbidity 5 -1.393063e+000, -5.578338e-001, -4.185249e+001, 4.233504e+001, -5.435640e-003, 4.743765e-001, 7.422477e-003, 2.442801e+000, 5.211707e-001, -1.939487e+000, -1.128509e+000, -8.974257e+000, 9.978383e+000, -7.965597e-003, 2.948830e-001, 4.436763e-002, 2.839868e-001, 3.440424e-001, -6.011562e-001, 2.354877e-001, -3.079820e+000, 2.585094e+000, -2.002701e-002, 7.793909e-001, -1.598414e-001, 5.834678e+000, 1.202856e+000, -1.315676e+000, -3.903446e-001, 1.701900e+000, -1.304609e+000, -1.045121e-002, 2.747707e-001, 4.143967e-001, 3.197102e-001, 2.637580e-001, -9.618628e-001, -1.625841e-001, 1.187138e+000, 1.497802e-001, -5.590954e-006, 3.178475e-002, -4.153145e-002, 2.496096e+000, 8.195082e-001, -1.111554e+000, -2.365546e-001, 7.831875e-001, 2.018684e-001, 2.074369e-001, 7.395978e-001, 1.225730e-001, 1.876478e+000, 6.821167e-001, // albedo 1, turbidity 6 -1.427879e+000, -5.994879e-001, -3.531016e+001, 3.581581e+001, -6.431497e-003, 4.554192e-001, 7.348731e-004, 2.334619e+000, 5.233377e-001, -1.998177e+000, -1.206633e+000, -2.146510e+001, 2.242237e+001, -5.857596e-003, 2.755663e-001, 6.384795e-002, 1.358244e-001, 3.328437e-001, -6.440630e-001, 2.058571e-001, 2.155499e+000, -2.587968e+000, -1.840023e-002, 8.826555e-001, -2.222452e-001, 5.847073e+000, 1.228387e+000, -1.229071e+000, -3.360441e-001, -3.429599e-001, 6.179469e-001, 2.029610e-003, 8.899319e-002, 5.041624e-001, 1.882964e-001, 2.252040e-001, -1.022905e+000, -2.101621e-001, 1.915689e+000, -6.498794e-001, -3.463651e-002, 8.954605e-002, -6.797854e-002, 2.417705e+000, 8.568618e-001, -1.082538e+000, -2.007723e-001, 4.731009e-001, 4.077267e-001, 1.324289e-001, 6.514880e-001, 1.702912e-001, 2.309383e+000, 6.600895e-001, // albedo 1, turbidity 7 -1.472139e+000, -6.499815e-001, -3.428465e+001, 3.469659e+001, -5.747023e-003, 4.174167e-001, 1.688597e-003, 2.323046e+000, 5.395191e-001, -2.161176e+000, -1.353089e+000, -2.226827e+001, 2.329138e+001, -5.583808e-003, 2.364793e-001, 6.096656e-002, 1.944666e-003, 2.861624e-001, -6.593044e-001, 1.393558e-001, 4.698373e+000, -5.193883e+000, -1.998390e-002, 1.095635e+000, -2.391254e-001, 5.598103e+000, 1.236193e+000, -1.195717e+000, -2.972715e-001, 4.648953e-002, 3.024588e-001, 5.003313e-003, -3.754741e-001, 5.247265e-001, -1.381312e-001, 2.493896e-001, -1.020139e+000, -2.253524e-001, 3.548437e-001, 7.030485e-001, -2.107076e-002, 4.581395e-001, -3.243757e-002, 2.453259e+000, 8.323623e-001, -1.098770e+000, -2.435780e-001, 8.761614e-001, 1.941613e-001, -1.990692e-001, 3.761139e-001, 1.657412e-001, 1.590503e+000, 6.741417e-001, // albedo 1, turbidity 8 -1.648007e+000, -8.205121e-001, -4.435106e+001, 4.479801e+001, -4.181353e-003, 3.854830e-001, -1.842385e-006, 2.000281e+000, 5.518363e-001, -2.140986e+000, -1.282239e+000, -3.979213e+000, 4.672459e+000, -5.008582e-003, 2.421920e-001, 6.253602e-002, 6.612713e-001, 2.555851e-001, -1.300502e+000, -5.137898e-001, 5.179821e-001, -4.032341e-001, -2.066785e-002, 1.087929e+000, -2.615309e-001, 4.225887e+000, 1.229237e+000, -6.963340e-001, 9.241060e-002, 6.936356e-002, -3.588571e-001, -5.461843e-002, -5.616643e-001, 5.484166e-001, -4.776267e-002, 2.414935e-001, -1.233179e+000, -4.325498e-001, 6.479813e-001, 8.368356e-001, 2.458875e-001, 6.464752e-001, -2.897097e-002, 1.561773e+000, 8.518598e-001, -1.051023e+000, -2.533690e-001, 1.004294e+000, 3.028083e-001, -1.520108e+000, 1.607013e-001, 1.619975e-001, 1.131094e+000, 6.706655e-001, // albedo 1, turbidity 9 -1.948249e+000, -1.097383e+000, -4.453697e+001, 4.494902e+001, -3.579939e-003, 3.491605e-001, -2.500253e-006, 1.740442e+000, 6.188022e-001, -2.154253e+000, -1.209559e+000, 4.144894e+000, -3.562411e+000, -5.638843e-003, 1.067169e-001, 7.594858e-002, 1.005280e+000, 1.072543e-001, -2.513259e+000, -1.507208e+000, -1.602979e+000, 1.404154e+000, -5.560750e-003, 1.240490e+000, -2.852117e-001, 3.485252e+000, 1.349321e+000, -7.832214e-002, 3.655626e-001, 3.856288e-001, 6.867894e-001, -1.609523e-001, -6.704306e-001, 5.357301e-001, -6.457935e-001, 1.479503e-001, -1.354784e+000, -5.454375e-001, 8.797469e-001, -1.466514e+000, 7.134420e-001, 5.934903e-001, -2.911178e-002, 8.643737e-001, 9.030724e-001, -1.048324e+000, -2.738736e-001, 8.783074e-001, 3.246188e+000, -4.435369e+000, 1.251791e-001, 1.783486e-001, 1.064657e+000, 6.522878e-001, // albedo 1, turbidity 10 -2.770408e+000, -1.618911e+000, -2.504031e+001, 2.531674e+001, -4.239279e-003, 3.241013e-001, -3.764484e-006, 1.586843e+000, 7.035906e-001, -1.913500e+000, -1.144014e+000, -1.080587e+001, 1.153677e+001, -1.003197e-002, 1.577515e-001, 5.217789e-002, 1.225278e+000, 5.172771e-003, -5.293208e+000, -2.876463e+000, 2.087053e+000, -3.201552e+000, 3.892964e-003, 5.323930e-001, -2.034512e-001, 2.617760e+000, 1.273597e+000, 9.060340e-001, 3.773409e-001, -6.399945e-001, 3.213979e+000, -9.112172e-002, 6.494055e-001, 3.953280e-001, 5.047796e-001, 2.998695e-001, -1.482179e+000, -6.778310e-001, 1.161775e+000, -3.004872e+000, 4.774797e-001, -4.969248e-001, -3.512074e-003, -1.307190e+000, 7.927378e-001, -9.863181e-001, -1.803364e-001, 5.810824e-001, 4.580570e+000, -3.863454e+000, 5.328174e-001, 2.272821e-001, 1.771114e+000, 6.791814e-001, }; static float datasetXYZRad3[] = { // albedo 0, turbidity 1 1.168084e+000, 2.156455e+000, -3.980314e+000, 1.989302e+001, 1.328335e+001, 1.435621e+001, // albedo 0, turbidity 2 1.135488e+000, 2.294701e+000, -4.585886e+000, 2.090208e+001, 1.347840e+001, 1.467658e+001, // albedo 0, turbidity 3 1.107408e+000, 2.382765e+000, -5.112357e+000, 2.147823e+001, 1.493128e+001, 1.460882e+001, // albedo 0, turbidity 4 1.054193e+000, 2.592891e+000, -6.115000e+000, 2.268967e+001, 1.635672e+001, 1.518999e+001, // albedo 0, turbidity 5 1.006946e+000, 2.705420e+000, -6.698930e+000, 2.291830e+001, 1.834324e+001, 1.570651e+001, // albedo 0, turbidity 6 9.794044e-001, 2.742440e+000, -6.805283e+000, 2.225271e+001, 2.050797e+001, 1.563130e+001, // albedo 0, turbidity 7 9.413577e-001, 2.722009e+000, -6.760707e+000, 2.098242e+001, 2.342588e+001, 1.605011e+001, // albedo 0, turbidity 8 8.917923e-001, 2.592780e+000, -6.152635e+000, 1.774141e+001, 2.858324e+001, 1.657910e+001, // albedo 0, turbidity 9 8.288391e-001, 2.153434e+000, -4.118327e+000, 1.078118e+001, 3.681710e+001, 1.738139e+001, // albedo 0, turbidity 10 7.623528e-001, 1.418187e+000, -8.845235e-001, 7.590129e-001, 4.629859e+001, 1.921657e+001, // albedo 1, turbidity 1 1.352858e+000, 2.048862e+000, -2.053393e+000, 1.405874e+001, 3.045344e+001, 3.044430e+001, // albedo 1, turbidity 2 1.330497e+000, 2.126497e+000, -2.466296e+000, 1.467559e+001, 3.090738e+001, 3.069707e+001, // albedo 1, turbidity 3 1.286344e+000, 2.200436e+000, -2.877228e+000, 1.492701e+001, 3.236288e+001, 3.077223e+001, // albedo 1, turbidity 4 1.234428e+000, 2.289628e+000, -3.404699e+000, 1.499436e+001, 3.468390e+001, 3.084842e+001, // albedo 1, turbidity 5 1.178660e+000, 2.306071e+000, -3.549159e+000, 1.411006e+001, 3.754188e+001, 3.079730e+001, // albedo 1, turbidity 6 1.151366e+000, 2.333005e+000, -3.728627e+000, 1.363374e+001, 3.905894e+001, 3.092599e+001, // albedo 1, turbidity 7 1.101593e+000, 2.299422e+000, -3.565787e+000, 1.196745e+001, 4.188472e+001, 3.102755e+001, // albedo 1, turbidity 8 1.038322e+000, 2.083539e+000, -2.649585e+000, 8.037389e+000, 4.700869e+001, 3.065948e+001, // albedo 1, turbidity 9 9.596146e-001, 1.671470e+000, -8.751538e-001, 1.679772e+000, 5.345784e+001, 3.054520e+001, // albedo 1, turbidity 10 8.640731e-001, 9.858301e-001, 1.854956e+000, -6.798097e+000, 5.936468e+001, 3.110255e+001, }; static float *datasetsXYZ[] = {datasetXYZ1, datasetXYZ2, datasetXYZ3}; static float *datasetsXYZRad[] = {datasetXYZRad1, datasetXYZRad2, datasetXYZRad3}; RenderKit-ospray-85af292/modules/cpu/lights/sky_model/sky_model_data_rgb.h000066400000000000000000002303631464752671100270030ustar00rootroot00000000000000/* This source is published under the following 3-clause BSD license. Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * None of the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // with slight modifications // Copyright 2020 Intel Corporation /* ============================================================================ This file is part of a sample implementation of the analytical skylight and solar radiance models presented in the SIGGRAPH 2012 paper "An Analytic Model for Full Spectral Sky-Dome Radiance" and the 2013 IEEE CG&A paper "Adding a Solar Radiance Function to the Hosek Skylight Model" both by Lukas Hosek and Alexander Wilkie Charles University in Prague, Czech Republic Version: 1.4a, February 22nd, 2013 Version history: 1.4a February 22nd, 2013 Removed unnecessary and counter-intuitive solar radius parameters from the interface of the colourspace sky dome initialisation functions. 1.4 February 11th, 2013 Fixed a bug which caused the relative brightness of the solar disc and the sky dome to be off by a factor of about 6. The sun was too bright: this affected both normal and alien sun scenarios. The coefficients of the solar radiance function were changed to fix this. 1.3 January 21st, 2013 (not released to the public) Added support for solar discs that are not exactly the same size as the terrestrial sun. Also added support for suns with a different emission spectrum ("Alien World" functionality). 1.2a December 18th, 2012 Fixed a mistake and some inaccuracies in the solar radiance function explanations found in ArHosekSkyModel.h. The actual source code is unchanged compared to version 1.2. 1.2 December 17th, 2012 Native RGB data and a solar radiance function that matches the turbidity conditions were added. 1.1 September 2012 The coefficients of the spectral model are now scaled so that the output is given in physical units: W / (m^-2 * sr * nm). Also, the output of the XYZ model is now no longer scaled to the range [0...1]. Instead, it is the result of a simple conversion from spectral data via the CIE 2 degree standard observer matching functions. Therefore, after multiplication with 683 lm / W, the Y channel now corresponds to luminance in lm. 1.0 May 11th, 2012 Initial release. Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if an updated version of this code has been published! ============================================================================ */ /* This file contains the coefficient data for the RGB colour space version of the model. */ // uses Aug 23 dataset static float datasetRGB1[] = { // albedo 0, turbidity 1 -1.099459e+000, -1.335146e-001, -4.083223e+000, 5.919603e+000, -1.104166e-001, 1.600158e+000, -1.326538e-006, 4.917807e+000, 5.127716e-001, -1.169858e+000, -1.832793e-001, 9.694744e-001, 9.495762e-002, -4.738918e-002, 2.194171e-001, 1.095749e-001, 3.603604e+000, 3.815119e-001, -9.665225e-001, -1.403888e-001, 5.194457e+000, -1.107607e+000, -8.135181e-001, 4.969661e+000, -2.300508e-001, -2.489350e+000, 1.279158e+000, -1.292508e+000, -1.299552e-001, -2.071404e+000, -4.752482e-002, 1.215598e+000, -1.904179e+000, 3.027985e-001, 8.707768e+000, 6.332446e-002, -9.264666e-001, -1.696780e-001, 4.574070e+000, -4.232936e-001, -7.575833e+000, 5.079755e+000, -2.576343e-001, -4.506805e+000, 6.908129e-001, -1.139072e+000, -1.796056e-001, 1.923311e+000, 6.788529e+000, -2.364389e+000, -1.064041e+000, 1.717010e-001, 1.534681e+000, 5.015810e-001, // albedo 0, turbidity 2 -1.107257e+000, -1.384411e-001, -4.285744e+000, 5.713157e+000, -1.015992e-001, 1.372638e+000, 6.555893e-002, 5.127514e+000, 6.550471e-001, -1.187337e+000, -1.969013e-001, 8.551048e-001, 5.289708e-002, -7.626406e-002, 1.733153e-002, 1.779454e-001, 3.801038e+000, 4.742709e-001, -9.685321e-001, -1.553308e-001, 4.732492e+000, -1.178935e+000, -7.852791e-001, 4.604492e+000, -2.666518e-001, -2.367663e+000, 1.177527e+000, -1.252817e+000, -5.129949e-002, -2.800433e+000, -1.295992e-002, 1.308964e+000, -2.204331e+000, 7.276011e-001, 8.699265e+000, 1.188388e-001, -9.459509e-001, -2.322133e-001, 4.375041e+000, -1.712018e-001, -7.451681e+000, 5.078019e+000, -4.223538e-001, -4.595561e+000, 1.074719e+000, -1.125092e+000, -1.796750e-001, 1.626399e+000, 6.989743e+000, -2.406382e+000, -9.060383e-001, 2.961611e-001, 1.337715e+000, 5.438140e-001, // albedo 0, turbidity 3 -1.135338e+000, -1.716160e-001, -1.499253e+000, 2.373491e+000, -1.654023e-001, 9.566404e-001, 1.113453e-001, 4.528473e+000, 6.579439e-001, -1.132780e+000, -1.456214e-001, -1.736672e+000, 1.756589e+000, -1.087003e-001, 3.757927e-001, 2.525070e-001, 7.178513e+000, 5.003814e-001, -1.167176e+000, -2.927225e-001, 5.727667e+000, -3.139244e+000, -6.425204e-001, 2.822634e+000, -1.457812e-001, -6.787080e+000, 1.017072e+000, -1.042529e+000, 4.110823e-002, -4.000629e+000, 4.362364e+000, 1.090540e+000, -1.338674e+000, 8.246964e-001, 1.095249e+001, 2.912211e-001, -1.061598e+000, -2.096143e-001, 3.803155e+000, -7.977069e+000, -3.637880e+000, 3.707671e+000, -1.903128e-001, -3.397953e+000, 9.971500e-001, -1.073560e+000, -2.077964e-001, 1.492052e+000, 1.626322e+001, -5.015304e+000, -4.059889e-001, 2.659782e-001, 6.395380e-001, 5.634436e-001, // albedo 0, turbidity 4 -1.172794e+000, -2.111186e-001, -1.360013e+000, 1.604080e+000, -8.473723e-002, 7.217312e-001, 1.548030e-001, 4.257010e+000, 6.328974e-001, -1.238374e+000, -2.670827e-001, 3.247678e-001, 5.466311e-001, -7.425952e-001, 5.276440e-001, 2.678026e-002, 5.484169e+000, 6.814734e-001, -1.176923e+000, -2.574586e-001, 2.304045e+000, -2.797678e+000, 1.464405e+000, 1.998552e+000, 2.550559e-001, -4.199772e+000, 7.544892e-001, -1.003284e+000, 1.943984e-002, -2.145066e+000, 1.030924e+001, -1.525413e+001, -2.023010e+000, 5.448699e-001, 8.159497e+000, 5.539148e-001, -1.060017e+000, -2.037206e-001, 2.483018e+000, -4.595459e+000, 6.526991e+000, 4.031804e+000, 1.206513e-001, -2.586527e+000, 7.875752e-001, -1.081141e+000, -2.123302e-001, 1.092275e+000, 2.683841e+000, -4.166938e+000, -1.396582e+000, 4.371205e-001, 1.030233e+000, 6.664862e-001, // albedo 0, turbidity 5 -1.222392e+000, -2.651924e-001, -4.625037e-001, 3.521964e-001, 2.148855e-002, 5.078494e-001, 1.791590e-001, 3.852516e+000, 5.998216e-001, -1.424610e+000, -4.710155e-001, -1.826815e-001, 1.786277e+000, -1.952442e+000, 5.277612e-001, -1.773629e-002, 2.415874e+000, 6.701272e-001, -1.130655e+000, -1.358609e-001, 9.171203e-001, -4.660394e+000, 6.251162e+000, 1.904529e+000, 2.639668e-001, 1.856130e+000, 8.228440e-001, -9.739015e-001, -6.674749e-002, -4.768897e-001, 1.248589e+001, -1.994688e+001, -2.353043e+000, 5.885575e-001, 1.287251e+000, 4.830135e-001, -1.082178e+000, -1.974495e-001, 1.050245e+000, -4.792855e+000, 8.663406e+000, 3.246969e+000, 1.556731e-001, 8.117442e-001, 8.050376e-001, -1.063354e+000, -1.727108e-001, 9.681592e-001, 2.736077e+000, -4.969269e+000, -8.360570e-001, 5.994612e-001, 1.024039e+000, 6.786935e-001, // albedo 0, turbidity 6 -1.261936e+000, -3.053676e-001, -4.262222e-001, 4.000196e-001, -2.059388e-002, 4.721802e-001, 1.480028e-001, 3.505343e+000, 6.121337e-001, -1.681088e+000, -6.971919e-001, -1.105652e-001, 7.437426e-001, -6.594399e-001, 2.254221e-001, 8.710195e-002, 1.263913e+000, 5.681865e-001, -9.453001e-001, 3.460388e-002, 6.067038e-001, -1.985128e+000, 3.457236e+000, 2.655483e+000, -1.162354e-002, 3.304716e+000, 1.001950e+000, -1.086609e+000, -2.029011e-001, -6.399170e-001, 6.926885e+000, -1.512189e+001, -3.793051e+000, 9.456120e-001, 2.222222e-001, 2.893725e-001, -1.041259e+000, -1.388790e-001, 1.147331e+000, 6.282086e+000, 3.679836e+000, 4.398314e+000, -1.355232e-001, 1.031134e+000, 9.273509e-001, -1.063473e+000, -1.916051e-001, 6.556979e-001, -3.371891e-003, -3.699664e+000, -1.926783e+000, 7.371154e-001, 1.179975e+000, 6.367068e-001, // albedo 0, turbidity 7 -1.336390e+000, -3.778927e-001, -7.259477e-001, 2.270247e-001, 4.627513e-001, 1.366459e-001, 2.637347e-001, 3.292059e+000, 4.998211e-001, -2.119878e+000, -1.055472e+000, 5.422052e-001, 7.826648e-001, -1.286065e+000, 9.517905e-001, -1.432358e-001, -2.379816e-001, 5.910513e-001, -7.761432e-001, 2.124336e-001, -6.845184e-001, -9.812342e-001, 4.347257e+000, 9.671980e-001, 3.773150e-001, 5.789529e+000, 9.646598e-001, -1.118734e+000, -3.513815e-001, 5.500918e-001, 9.449627e-001, -1.262070e+001, -1.825280e+000, 4.731260e-001, -3.326892e+000, 3.568768e-001, -1.026437e+000, -8.257946e-002, 3.221701e-001, 1.198372e+001, 1.555130e+000, 2.560304e+000, 1.406465e-001, 2.912858e+000, 8.643181e-001, -1.069949e+000, -2.029607e-001, 5.825042e-001, -2.398595e-003, -3.278335e+000, -1.349882e+000, 7.208433e-001, 8.505164e-001, 6.625391e-001, // albedo 0, turbidity 8 -1.392309e+000, -4.454945e-001, -5.664000e-001, 6.283393e-001, -3.761727e-001, 6.949802e-001, 7.748178e-002, 3.192797e+000, 5.968661e-001, -2.713405e+000, -1.395112e+000, 2.029230e-001, 1.877272e-001, -3.715859e-001, -1.652929e-001, 2.385861e-001, -4.150768e-001, 1.375467e-001, -9.588644e-001, 2.433900e-002, -1.527493e+000, -9.632874e-001, 5.496269e+000, 1.094931e+000, 2.004044e-001, 6.084554e+000, 1.369604e+000, -8.028546e-001, -2.473563e-001, 1.617898e+000, 2.073591e+000, -1.149446e+001, -8.394131e-001, 2.726847e-001, -4.634538e+000, 1.367293e-001, -1.198326e+000, -1.804865e-001, -3.565414e-001, 4.073200e+000, 1.662086e+000, 1.239770e+000, 3.367978e-001, 2.997402e+000, 9.360383e-001, -1.013531e+000, -1.859060e-001, 5.799857e-001, 1.331883e+001, -4.346873e+000, -1.113820e+000, 5.275714e-001, 8.045177e-001, 6.496373e-001, // albedo 0, turbidity 9 -1.530103e+000, -6.107468e-001, -3.841771e-001, 1.881508e+000, -1.464807e+000, 6.654690e-001, -5.950797e-006, 2.738912e+000, 8.101012e-001, -2.415469e+000, -1.057499e+000, -4.161968e-001, -2.357548e+000, 6.300296e-001, 6.224915e-001, 1.545048e-002, 2.038561e+000, -1.339415e-001, -3.096796e+000, -1.465688e+000, -1.199232e+000, 4.567061e+000, 3.260980e+000, -9.794907e-001, 8.950491e-001, 2.049235e+000, 1.331015e+000, 2.713904e-001, 2.852852e-001, 1.202090e+000, -8.206784e+000, -5.805762e+000, 1.804431e+000, -6.090648e-001, -1.990902e+000, 3.288858e-001, -1.456580e+000, -3.455960e-001, -6.409257e-002, 1.667697e+001, -2.311094e+000, -9.771104e-001, 6.759863e-001, 1.245136e+000, 7.911932e-001, -9.860389e-001, -2.099564e-001, 2.946650e-001, -3.547800e-003, -2.268313e+000, -6.205647e-002, 4.705185e-001, 8.657995e-001, 6.856284e-001, // albedo 0, turbidity 10 -1.971736e+000, -9.414047e-001, -3.400557e-001, 1.468763e+000, -1.474284e+000, 5.501062e-001, -1.109750e-005, 2.356370e+000, 9.001702e-001, -1.589845e+000, -7.797079e-001, -5.582240e-001, -8.137376e-001, 5.846617e-001, 1.129459e-001, -2.658005e-002, 2.707248e+000, -2.112486e-001, -6.940173e+000, -2.823963e+000, -1.620848e+000, 1.090696e+000, 2.391730e+000, 1.370047e+000, 5.890462e-001, 1.728400e+000, 1.331253e+000, 1.293144e+000, -1.919778e-003, 1.644206e+000, -8.666967e-001, -7.161953e+000, -1.385018e+000, -1.505374e-001, -1.388643e+000, 2.530122e-001, -1.488880e+000, -2.495496e-001, -2.377137e-001, 1.167714e+001, -8.617124e-001, 1.053828e+000, 1.992744e-001, 3.633564e-001, 8.553304e-001, -1.060891e+000, -4.035829e-001, 2.823207e-001, -2.369798e-003, -1.876577e+000, -5.950265e-001, 4.241017e-001, 3.140802e-001, 6.631669e-001, // albedo 1, turbidity 1 -1.101204e+000, -1.351353e-001, -4.030882e+000, 6.096353e+000, -1.148599e-001, 1.606507e+000, -1.555474e-006, 4.436084e+000, 5.973715e-001, -1.154597e+000, -1.923378e-001, 8.512132e-001, 2.934895e-001, -6.522777e-002, 1.389077e-001, 9.091469e-002, 3.133307e+000, 2.108541e-001, -1.031588e+000, -1.546804e-001, 5.266214e+000, -9.491390e-001, -7.184867e-001, 4.875626e+000, -1.911907e-001, -2.865642e+000, 1.087895e+000, -1.159454e+000, -9.546699e-002, -1.508146e+000, -2.031411e-002, 1.040653e+000, -2.333508e+000, 2.540592e-001, 8.594981e+000, 9.316770e-002, -1.035940e+000, -2.021151e-001, 4.719343e+000, -9.019318e-001, -7.858046e+000, 3.901234e+000, -2.233137e-001, -4.344739e+000, 6.550733e-001, -1.096669e+000, -1.558196e-001, 2.057553e+000, 6.274495e+000, -2.678352e+000, -1.814927e+000, 1.550676e-001, 1.903276e+000, 4.998989e-001, // albedo 1, turbidity 2 -1.114209e+000, -1.473531e-001, -7.602914e+000, 8.973685e+000, -4.980074e-002, 1.289198e+000, 8.366906e-002, 4.557987e+000, 6.118757e-001, -1.149397e+000, -1.981628e-001, 4.914096e+000, -3.498986e+000, -6.257090e-002, 1.667401e-001, 1.048980e-001, 2.284689e+000, 5.935965e-001, -1.056121e+000, -1.456172e-001, 4.272656e-001, 2.912649e+000, -5.501745e-001, 4.406542e+000, -1.387680e-001, 1.245555e+000, 9.733011e-001, -1.125047e+000, -4.003662e-002, 1.058457e+000, -3.462236e+000, 4.395278e-001, -2.395805e+000, 5.177589e-001, 4.866247e+000, 4.253189e-001, -1.051444e+000, -2.804541e-001, 3.364668e+000, 3.293787e+000, -1.015741e+001, 3.807407e+000, -3.592377e-001, -3.367415e+000, 7.900825e-001, -1.093847e+000, -1.436965e-001, 2.384780e+000, 5.787070e+000, -2.445987e+000, -1.311171e+000, 2.326563e-001, 1.158439e+000, 5.555416e-001, // albedo 1, turbidity 3 -1.134824e+000, -1.680468e-001, -3.325620e+000, 4.458596e+000, -1.135063e-001, 1.104500e+000, 7.794544e-002, 4.609952e+000, 6.854854e-001, -1.143017e+000, -1.565926e-001, 3.014687e-001, -1.763027e-001, -3.557925e-002, -2.342406e-001, 2.528705e-001, 5.884085e+000, 4.750602e-001, -1.136801e+000, -2.907502e-001, 3.682423e+000, -4.061202e-001, -8.728159e-001, 4.001510e+000, -1.522202e-001, -5.528713e+000, 1.044847e+000, -1.063652e+000, 7.808107e-002, -1.983678e+000, 3.648078e-001, 2.102276e+000, -3.065050e+000, 8.431951e-001, 1.038830e+001, 2.662834e-001, -1.061015e+000, -2.859814e-001, 4.223615e+000, -2.290138e+000, -8.314010e+000, 4.405718e+000, -4.613627e-001, -4.502910e+000, 1.008383e+000, -1.106302e+000, -1.697123e-001, 2.087196e+000, 8.238929e+000, -2.992416e+000, -1.821776e+000, 3.434859e-001, 7.755179e-001, 5.341190e-001, // albedo 1, turbidity 4 -1.171110e+000, -2.106304e-001, -1.614361e+000, 2.378103e+000, -1.625969e-001, 8.504483e-001, 1.059312e-001, 4.046256e+000, 6.618227e-001, -1.200480e+000, -2.235733e-001, 1.014390e+000, -1.174074e+000, -4.440180e-001, 2.262406e-001, 1.665868e-001, 5.461829e+000, 5.676310e-001, -1.223587e+000, -3.502622e-001, 1.699106e+000, 6.724266e-001, 1.268567e+000, 2.135102e+000, 8.039374e-004, -5.221111e+000, 9.445690e-001, -9.452673e-001, 1.468459e-001, -1.335034e+000, 4.346628e+000, -1.285652e+001, -1.807046e+000, 8.175243e-001, 9.301065e+000, 3.656798e-001, -1.134681e+000, -3.310951e-001, 3.571244e+000, -2.208948e+000, 6.041580e+000, 3.107577e+000, -3.112127e-001, -4.186351e+000, 9.188333e-001, -1.083237e+000, -1.831394e-001, 2.062654e+000, 1.385424e+000, -5.004950e+000, -1.332669e+000, 3.627352e-001, 3.323150e-001, 6.191181e-001, // albedo 1, turbidity 5 -1.211527e+000, -2.590617e-001, -1.660874e-001, 3.627905e-001, -1.039258e-001, 4.697924e-001, 1.671653e-001, 3.507497e+000, 6.022506e-001, -1.433017e+000, -4.733592e-001, 1.724445e-001, 9.953236e-001, -1.874457e+000, 4.432099e-001, 1.715810e-002, 2.339272e+000, 6.441470e-001, -1.084920e+000, -1.587903e-001, 8.999585e-001, -2.537516e+000, 5.877859e+000, 2.014554e+000, 9.689141e-002, 3.177242e-001, 9.030399e-001, -1.008242e+000, 2.793030e-003, -3.507469e-001, 1.028300e+001, -2.080454e+001, -2.781026e+000, 8.995090e-001, 3.366951e+000, 3.473867e-001, -1.103151e+000, -2.799598e-001, 2.525791e+000, -4.255704e+000, 9.903388e+000, 3.722668e+000, -3.603941e-001, -1.303292e+000, 9.369454e-001, -1.102235e+000, -2.025061e-001, 2.085660e+000, 1.686787e+000, -5.010957e+000, -1.656458e+000, 4.584029e-001, -2.751759e-001, 6.184162e-001, // albedo 1, turbidity 6 -1.256130e+000, -3.104904e-001, 1.639350e-001, 1.315502e-001, -7.297583e-001, 4.778480e-001, 1.259265e-001, 3.012108e+000, 6.202728e-001, -1.620114e+000, -6.552670e-001, -2.877157e-001, 1.094371e+000, 2.818914e-001, 3.696830e-001, 9.428521e-002, 1.450951e+000, 5.681308e-001, -9.686204e-001, -3.755647e-002, 1.469980e+000, -3.103414e+000, 2.856583e+000, 1.883209e+000, -5.746099e-002, 1.286383e+000, 1.001751e+000, -1.089377e+000, -1.023062e-001, -1.498891e+000, 1.066455e+001, -1.720184e+001, -2.759314e+000, 1.061258e+000, 2.910211e+000, 2.624701e-001, -1.044681e+000, -2.156857e-001, 3.230136e+000, -5.863862e-001, 6.096640e+000, 3.550019e+000, -4.255773e-001, -1.500033e+000, 9.687696e-001, -1.133658e+000, -2.505101e-001, 1.717840e+000, 8.480428e-003, -5.011789e+000, -1.740989e+000, 4.983430e-001, -2.081829e-001, 6.088641e-001, // albedo 1, turbidity 7 -1.335366e+000, -3.863319e-001, -5.279971e-001, 3.638324e-001, 3.230699e-001, 8.339707e-002, 2.483293e-001, 2.678646e+000, 4.998346e-001, -2.004511e+000, -9.957121e-001, 1.250807e+000, 1.625025e-002, -3.410754e-001, 7.858244e-001, -9.506757e-002, 2.651876e-002, 5.788643e-001, -8.714157e-001, 1.192051e-001, -8.486879e-001, -3.702497e-001, 1.818277e+000, 1.103427e+000, 2.454866e-001, 3.841575e+000, 9.847350e-001, -1.042618e+000, -2.285793e-001, 3.620175e-001, 2.983368e+000, -9.776844e+000, -1.971587e+000, 6.691674e-001, -7.901947e-001, 3.213200e-001, -1.099112e+000, -1.869868e-001, 2.044065e+000, 2.062964e+000, 1.265668e+000, 2.710130e+000, -1.099443e-001, 2.179353e-001, 9.024108e-001, -1.106985e+000, -2.396881e-001, 1.809807e+000, 8.523319e+000, -5.011788e+000, -1.590086e+000, 3.248449e-001, -1.003187e-001, 6.550606e-001, // albedo 1, turbidity 8 -1.421285e+000, -4.767024e-001, -3.885004e-001, 8.274590e-001, -3.644229e-001, 6.999513e-001, 5.196710e-002, 2.578431e+000, 6.246310e-001, -2.611217e+000, -1.398846e+000, 4.527425e-001, -5.932142e-001, 2.224617e-001, -5.593581e-001, 3.389633e-001, -7.767112e-001, 6.536004e-002, -9.881543e-001, 4.684782e-002, -8.616613e-001, 8.799807e-001, 4.003130e+000, 1.739543e+000, -8.098378e-002, 5.524802e+000, 1.499673e+000, -7.544759e-001, -2.314808e-001, 8.125770e-001, -7.724135e-001, -9.577645e+000, -1.629433e+000, 6.790832e-001, -4.193895e+000, -2.526624e-002, -1.273719e+000, -2.187030e-001, 1.401798e+000, 5.231832e+000, 7.405093e-001, 1.775166e+000, -7.269476e-002, 1.996087e+000, 1.057450e+000, -1.046864e+000, -2.247559e-001, 1.679449e+000, 1.140057e+001, -4.948829e+000, -1.182664e+000, 3.241038e-001, -2.470012e-001, 6.115900e-001, // albedo 1, turbidity 9 -1.514607e+000, -5.985430e-001, -1.877610e-001, 1.756930e+000, -1.314206e+000, 6.115810e-001, -5.970460e-006, 2.412975e+000, 8.124304e-001, -2.308414e+000, -1.083797e+000, -1.179959e-001, -1.728246e+000, 7.784742e-001, 5.494505e-001, 6.203168e-003, 9.326251e-001, -1.419518e-001, -3.230837e+000, -1.438670e+000, -9.868286e-001, 2.974393e+000, 1.949339e+000, -6.337857e-001, 8.160271e-001, 3.278606e+000, 1.354373e+000, 5.149378e-001, 2.754789e-001, 1.040965e+000, -4.501186e+000, -3.399057e+000, 9.661861e-001, -4.736173e-001, -4.037574e+000, 2.794847e-001, -1.621870e+000, -3.192763e-001, 8.786242e-001, 9.785565e+000, -2.727652e+000, 1.903691e-002, 5.521261e-001, 2.138764e+000, 8.419871e-001, -9.951701e-001, -2.550607e-001, 1.498952e+000, -2.737197e-003, -3.101832e+000, -5.921329e-001, 2.864422e-001, -4.405218e-001, 6.631410e-001, // albedo 1, turbidity 10 -1.902954e+000, -9.056918e-001, -2.069570e-001, 1.191499e+000, -1.092577e+000, 5.849556e-001, -9.649602e-006, 2.048407e+000, 9.001527e-001, -1.271627e+000, -7.193923e-001, -1.136606e-002, -1.167951e-001, 3.286175e-003, -5.262827e-002, -2.473874e-002, 1.716125e+000, -2.187133e-001, -7.647175e+000, -3.114129e+000, -1.490128e+000, -5.266488e-001, 3.063090e+000, 1.474262e+000, 5.481458e-001, 2.052174e+000, 1.353089e+000, 2.191403e+000, 3.421120e-001, 1.446510e+000, 2.170943e+000, -7.768187e+000, -1.471207e+000, -1.456708e-001, -1.753574e+000, 2.310576e-001, -1.932296e+000, -3.814739e-001, 6.245422e-001, 6.748294e+000, -3.060171e-001, 1.067747e+000, 2.500671e-001, -1.252596e-001, 8.614611e-001, -9.471101e-001, -4.052640e-001, 1.300174e+000, -3.951536e-003, -1.908284e+000, -5.385721e-001, 2.133578e-001, -6.250292e-001, 6.658012e-001, }; static float datasetRGBRad1[] = { // albedo 0, turbidity 1 1.962684e+000, 1.159831e+000, 4.450588e+000, 5.079633e+000, 4.437388e+000, 4.324573e+000, // albedo 0, turbidity 2 1.946487e+000, 1.287515e+000, 3.703696e+000, 8.782833e+000, 3.440437e+000, 5.160333e+000, // albedo 0, turbidity 3 1.882170e+000, 1.335878e+000, 2.648641e+000, 1.358368e+001, 3.105473e+000, 5.907387e+000, // albedo 0, turbidity 4 1.738159e+000, 1.624289e+000, -8.786695e-003, 2.118253e+001, 2.770255e+000, 7.055672e+000, // albedo 0, turbidity 5 1.571896e+000, 2.301786e+000, -4.028545e+000, 2.966806e+001, 1.630876e+000, 8.711031e+000, // albedo 0, turbidity 6 1.475048e+000, 2.679086e+000, -6.311315e+000, 3.377896e+001, 2.140975e+000, 9.385283e+000, // albedo 0, turbidity 7 1.326174e+000, 3.378759e+000, -9.831444e+000, 3.942061e+001, 2.852702e+000, 1.082542e+001, // albedo 0, turbidity 8 1.153344e+000, 3.967771e+000, -1.265181e+001, 4.195016e+001, 7.468239e+000, 1.221350e+001, // albedo 0, turbidity 9 9.746081e-001, 4.051626e+000, -1.298454e+001, 3.754964e+001, 1.749232e+001, 1.420619e+001, // albedo 0, turbidity 10 8.448016e-001, 3.181809e+000, -8.757338e+000, 2.197962e+001, 3.524033e+001, 1.639549e+001, // albedo 1, turbidity 1 2.029623e+000, 1.364434e+000, 4.201529e+000, 5.415099e+000, 9.825839e+000, 1.063328e+001, // albedo 1, turbidity 2 2.023126e+000, 1.494728e+000, 3.420413e+000, 9.072178e+000, 9.205157e+000, 1.186639e+001, // albedo 1, turbidity 3 1.956307e+000, 1.648665e+000, 2.039712e+000, 1.430239e+001, 9.039526e+000, 1.330453e+001, // albedo 1, turbidity 4 1.825053e+000, 1.985022e+000, -8.036307e-001, 2.202493e+001, 9.415361e+000, 1.517659e+001, // albedo 1, turbidity 5 1.650367e+000, 2.593201e+000, -4.469328e+000, 2.969817e+001, 9.410977e+000, 1.744850e+001, // albedo 1, turbidity 6 1.555202e+000, 2.962925e+000, -6.608170e+000, 3.329887e+001, 1.064559e+001, 1.850816e+001, // albedo 1, turbidity 7 1.412478e+000, 3.439403e+000, -9.196616e+000, 3.685077e+001, 1.345341e+001, 2.003128e+001, // albedo 1, turbidity 8 1.252990e+000, 3.820805e+000, -1.115338e+001, 3.721593e+001, 2.014916e+001, 2.182320e+001, // albedo 1, turbidity 9 1.091952e+000, 3.663027e+000, -1.031330e+001, 2.978985e+001, 3.296835e+001, 2.375450e+001, // albedo 1, turbidity 10 9.501691e-001, 2.664579e+000, -5.545167e+000, 1.281159e+001, 5.154768e+001, 2.574284e+001, }; static float datasetRGB2[] = { // albedo 0, turbidity 1 -1.140530e+000, -1.982747e-001, -7.512730e+000, 8.403899e+000, -5.699038e-002, 9.015907e-001, 3.392161e-002, 4.772522e+000, 5.111184e-001, -1.165117e+000, -1.852955e-001, 2.963684e+000, -2.262274e+000, -1.571683e-001, 6.339974e-001, 4.977879e-002, 7.243307e+000, 4.220053e-001, -1.169936e+000, -3.357429e-001, 1.911291e+000, -2.391074e-001, -4.791643e-001, 1.446113e+000, -9.178108e-002, -4.700239e+000, 8.096219e-001, -1.060246e+000, -1.051633e-001, 5.013829e-001, 2.832309e+000, -3.707855e-001, 1.523131e+000, 9.163749e-002, 5.604183e+000, 7.208566e-001, -1.089753e+000, -2.382167e-001, 2.360312e+000, -5.902562e+000, -8.799894e+000, 1.377692e+000, -6.131633e-002, -1.415472e+000, 6.124057e-001, -1.075481e+000, -1.242391e-001, 1.425781e+000, 8.810319e+000, -2.922646e+000, 1.486520e+000, 3.270580e-002, 3.889783e+000, 4.999482e-001, // albedo 0, turbidity 2 -1.149342e+000, -2.076337e-001, -7.446587e+000, 8.014559e+000, -4.866227e-002, 8.203043e-001, 6.386483e-002, 4.894198e+000, 5.452051e-001, -1.120531e+000, -1.513311e-001, 2.735504e+000, -2.417591e+000, -1.361114e-001, 4.296342e-001, 9.427488e-002, 8.171403e+000, 4.102448e-001, -1.226964e+000, -3.516378e-001, 1.308298e+000, -5.097487e-002, -4.846783e-001, 1.654619e+000, -1.134940e-001, -3.347854e+000, 1.131147e+000, -9.664377e-001, 2.767589e-002, 1.658235e-001, 2.407439e+000, -1.300304e-001, 9.170958e-001, 2.742895e-001, 6.642633e+000, 2.550064e-001, -1.153358e+000, -3.126223e-001, 2.078934e+000, -5.857733e+000, -8.659848e+000, 1.758505e+000, -9.616094e-002, -1.230863e+000, 9.663832e-001, -1.053850e+000, -1.330743e-001, 1.481738e+000, 1.049485e+001, -3.528854e+000, 9.142363e-001, 1.244880e-001, 2.644615e+000, 5.001048e-001, // albedo 0, turbidity 3 -1.173687e+000, -2.360362e-001, -3.741454e+000, 4.088507e+000, -7.528205e-002, 6.645237e-001, 7.718265e-002, 4.651220e+000, 5.586318e-001, -1.213757e+000, -2.589561e-001, 7.132551e-001, -4.259327e-001, -1.980821e-001, 3.627815e-001, 4.666560e-002, 5.807984e+000, 5.847377e-001, -1.108794e+000, -2.259870e-001, 1.574179e+000, -3.753731e-001, -5.984743e-001, 1.659414e+000, -1.681021e-002, 6.785219e-001, 8.647325e-001, -1.060896e+000, -1.346690e-002, -7.529656e-001, 1.711319e+000, -9.792435e-001, 2.022433e-001, 3.826487e-001, 5.725157e+000, 5.290714e-001, -1.085145e+000, -2.840715e-001, 2.088029e+000, -4.935097e+000, -9.056542e+000, 1.976149e+000, -3.912485e-002, -8.636064e-001, 7.452125e-001, -1.077983e+000, -1.416633e-001, 1.100848e+000, 1.015875e+001, -2.943712e+000, 5.255135e-001, 2.164224e-001, 2.941143e+000, 6.699937e-001, // albedo 0, turbidity 4 -1.223293e+000, -2.867444e-001, -1.624136e+000, 1.668299e+000, -9.537589e-002, 5.015947e-001, 1.130741e-001, 4.244812e+000, 5.082152e-001, -1.325342e+000, -4.280991e-001, 4.705490e-001, 6.926592e-002, -4.572587e-001, 5.344144e-001, -2.554192e-002, 3.093939e+000, 6.639401e-001, -1.113581e+000, -1.192133e-001, 4.011536e-001, 7.011889e-001, 2.052842e-001, 9.880724e-001, 1.807533e-002, 4.690160e+000, 8.576240e-001, -1.016063e+000, -1.038138e-001, -2.280391e-001, 7.898918e-001, -1.127333e+001, 2.074545e-001, 5.388182e-001, 1.364263e+000, 4.660455e-001, -1.099582e+000, -2.228607e-001, 1.332648e+000, 5.135188e+000, 1.653152e+000, 1.417020e+000, -1.087532e-001, 1.809275e+000, 8.080874e-001, -1.064357e+000, -1.520775e-001, 8.207368e-001, -1.323565e-003, -5.009523e+000, 3.946298e-001, 4.337902e-001, 2.593198e+000, 6.719172e-001, // albedo 0, turbidity 5 -1.278702e+000, -3.512866e-001, -4.511055e-001, 3.895760e-001, -2.429672e-001, 4.270577e-001, 1.135348e-001, 3.719130e+000, 4.998867e-001, -1.580069e+000, -7.095475e-001, -3.198904e-001, 1.715748e+000, -1.185915e+000, 4.523161e-001, -1.026159e-002, 7.927188e-001, 5.538350e-001, -9.474023e-001, 1.173703e-001, 4.881381e-001, -2.618684e+000, 3.251661e+000, 1.213931e+000, -1.736274e-002, 8.000768e+000, 1.025998e+000, -1.129091e+000, -3.287694e-001, -3.524077e-001, 3.352892e+000, -1.416073e+001, -8.485617e-001, 6.560766e-001, -2.820937e+000, 3.111303e-001, -1.030884e+000, -1.137581e-001, 1.109855e+000, 8.082276e+000, 1.519214e+000, 2.112433e+000, -1.592299e-001, 3.675905e+000, 8.703367e-001, -1.075192e+000, -1.627166e-001, 3.514910e-001, 1.168164e+000, -4.255822e+000, -6.015348e-001, 6.265776e-001, 2.884818e+000, 6.548384e-001, // albedo 0, turbidity 6 -1.316017e+000, -3.889652e-001, -5.030854e-001, 4.488704e-001, -3.186800e-001, 4.570763e-001, 8.909201e-002, 3.659274e+000, 5.011746e-001, -1.731876e+000, -8.493806e-001, 1.194871e-001, 2.002781e+000, -2.006547e+000, 4.872233e-001, -2.854606e-002, 2.662137e-001, 4.611629e-001, -9.273680e-001, 1.380954e-001, -3.302179e-001, -3.553265e+000, 4.633345e+000, 9.696729e-001, 8.799775e-002, 8.291129e+000, 1.094451e+000, -1.099377e+000, -3.325392e-001, 2.501063e-001, 2.613712e+000, -1.328142e+001, -5.579527e-001, 4.992081e-001, -3.504402e+000, 3.022924e-001, -1.048420e+000, -1.227773e-001, 5.845373e-001, 1.105869e+001, 3.813151e-002, 1.330409e+000, 1.978131e-002, 3.959430e+000, 8.396439e-001, -1.063233e+000, -1.560639e-001, 2.840033e-001, 8.751565e-001, -3.411820e+000, -1.436564e-001, 5.846580e-001, 2.899292e+000, 6.799095e-001, // albedo 0, turbidity 7 -1.376715e+000, -4.541567e-001, -1.445491e+000, 1.569898e+000, -1.390627e-001, 5.558270e-001, 4.109877e-002, 3.349451e+000, 5.516123e-001, -1.953391e+000, -1.035869e+000, 1.690563e+000, -1.964690e-001, -7.787096e-001, 5.799605e-001, 2.945626e-002, 4.217906e-002, 2.451373e-001, -1.012422e+000, 7.136451e-002, -1.862534e+000, -7.228653e-001, 1.947997e-001, 2.091805e-001, 6.399233e-002, 7.928994e+000, 1.290733e+000, -9.706708e-001, -2.880950e-001, 1.107797e+000, -2.731734e+000, -8.445995e+000, 4.296774e-001, 5.117648e-001, -3.824277e+000, 1.761207e-001, -1.110611e+000, -1.789409e-001, 2.108488e-001, 2.071430e+001, -1.763174e+000, 9.554695e-002, -2.943103e-002, 3.422079e+000, 8.815496e-001, -1.048334e+000, -1.614087e-001, 2.475184e-001, 2.146938e-002, -2.983901e+000, 2.538224e-001, 5.601370e-001, 2.461925e+000, 6.777394e-001, // albedo 0, turbidity 8 -1.393719e+000, -5.002724e-001, -2.408940e+000, 2.680983e+000, -1.362825e-001, 7.395067e-001, -3.300343e-006, 3.260889e+000, 8.132057e-001, -2.128663e+000, -1.151182e+000, 2.923026e+000, -1.931838e+000, -4.426170e-001, 2.309983e-001, -5.485890e-003, 3.279529e-001, -2.229467e-001, -1.618022e+000, -3.766490e-001, -3.163544e+000, 1.611608e+000, -3.967476e-001, 3.933680e-001, 3.006742e-001, 6.835177e+000, 1.613765e+000, -5.669064e-001, -1.481749e-001, 2.071817e+000, -8.157422e+000, -5.988088e+000, 2.387202e-001, 1.447191e-001, -4.296385e+000, 5.011258e-002, -1.241724e+000, -2.519348e-001, -1.908609e-001, 2.952235e+001, -3.333660e+000, -1.837651e-002, 1.022249e-001, 2.929320e+000, 8.867262e-001, -1.021670e+000, -1.667327e-001, 1.789771e-001, -2.178108e-003, -2.641572e+000, -5.641484e-002, 5.303758e-001, 2.138196e+000, 6.780350e-001, // albedo 0, turbidity 9 -1.669332e+000, -7.588708e-001, -2.993557e+000, 3.178760e+000, -8.066442e-002, 6.544672e-001, -8.089880e-006, 2.628924e+000, 9.001272e-001, -1.755806e+000, -8.735348e-001, 3.258881e+000, -2.504785e+000, -3.300791e-001, 1.180565e-001, -9.315982e-003, 1.785154e+000, -3.205824e-001, -3.720277e+000, -1.733350e+000, -3.332272e+000, 1.515869e+000, 1.734218e-001, 8.011956e-001, 1.995440e-001, 3.817666e+000, 1.638502e+000, 4.724641e-001, 3.209828e-001, 2.051443e+000, -5.105574e+000, -6.509139e+000, -4.232041e-001, 2.598931e-001, -2.151756e+000, -3.493910e-003, -1.525600e+000, -4.897606e-001, -9.891121e-002, 2.346818e+001, -2.278152e+000, 1.681219e-001, -4.469389e-002, 1.051000e+000, 9.294666e-001, -9.908649e-001, -2.008182e-001, 1.605143e-001, -2.463113e-003, -2.477349e+000, -1.218647e-001, 4.750121e-001, 1.460813e+000, 6.661364e-001, // albedo 0, turbidity 10 -2.122119e+000, -1.125475e+000, -3.066599e+000, 3.145078e+000, -5.411593e-002, 5.133628e-001, -7.823408e-006, 2.268448e+000, 9.001416e-001, -1.528158e+000, -9.370249e-001, 2.567559e+000, -1.591439e+000, -3.634460e-001, 1.763256e-001, 1.119624e-003, 1.811848e+000, -2.637929e-001, -6.524387e+000, -2.673507e+000, -2.940472e+000, -6.025609e-001, 7.852067e-001, 1.073499e+000, -3.540435e-002, 3.517416e+000, 1.490466e+000, 8.886026e-001, -9.681828e-002, 1.430554e+000, 4.993717e+000, -6.071355e+000, -6.053986e-001, 5.092997e-001, -1.273010e+000, 7.491329e-002, -1.481997e+000, -5.897282e-001, 2.659264e-001, 1.267239e+000, -5.741291e-001, 5.983011e-002, -2.217312e-001, -3.016452e-001, 9.260830e-001, -1.010943e+000, -2.075134e-001, 5.066749e-002, 1.470708e+001, -3.780501e+000, 7.253223e-002, 4.045458e-001, 1.320164e+000, 6.559925e-001, // albedo 1, turbidity 1 -1.129907e+000, -1.884011e-001, -8.047670e+000, 9.035776e+000, -5.539419e-002, 8.823349e-001, 3.197135e-002, 4.839388e+000, 5.042822e-001, -1.133821e+000, -1.510781e-001, 3.362822e+000, -2.453381e+000, -1.463925e-001, 4.728708e-001, 5.958140e-002, 7.636300e+000, 4.805162e-001, -1.176518e+000, -3.549902e-001, 1.729044e+000, -2.160966e-001, -5.075865e-001, 1.675584e+000, -8.906902e-002, -5.386842e+000, 5.452218e-001, -1.043563e+000, -7.520975e-002, 8.750644e-001, 2.510518e+000, 7.584882e-003, 9.361250e-001, 7.889083e-002, 6.066644e+000, 5.813108e-001, -1.081304e+000, -2.222253e-001, 2.517638e+000, -4.453820e+000, -8.663691e+000, 8.662558e-001, -4.802657e-002, -8.965449e-001, 4.886656e-001, -1.083774e+000, -1.375469e-001, 1.685818e+000, 5.631120e+000, -3.100752e+000, 4.045941e-001, 2.346895e-002, 3.390321e+000, 5.008309e-001, // albedo 1, turbidity 2 -1.143158e+000, -2.058334e-001, -9.660198e+000, 1.062394e+001, -4.434119e-002, 8.607615e-001, 3.177325e-002, 4.416481e+000, 5.918162e-001, -1.146773e+000, -1.727385e-001, 4.626048e+000, -4.684602e+000, -8.307137e-002, 1.619616e-001, 1.484866e-001, 7.572868e+000, 2.681126e-001, -1.151324e+000, -3.099303e-001, 4.125596e-001, 2.340752e+000, -4.214444e-001, 1.987375e+000, -1.913410e-001, -3.845978e+000, 1.337311e+000, -1.034258e+000, -7.778759e-003, 7.050094e-001, -8.036369e-001, 3.138570e-001, 2.469452e-001, 3.559970e-001, 7.485917e+000, 4.790329e-002, -1.096568e+000, -2.673169e-001, 2.575654e+000, -8.057121e-001, -8.884928e+000, 1.416170e+000, -2.091315e-001, -1.543494e+000, 1.065445e+000, -1.083304e+000, -1.528265e-001, 1.697727e+000, 2.503702e+000, -2.885296e+000, -1.298500e-001, 1.548870e-001, 2.479652e+000, 5.066496e-001, // albedo 1, turbidity 3 -1.165736e+000, -2.329945e-001, -5.967964e+000, 6.705959e+000, -5.931355e-002, 7.485638e-001, 3.913878e-002, 4.221591e+000, 6.183926e-001, -1.212422e+000, -2.545910e-001, 2.418626e+000, -2.266104e+000, -1.102014e-001, 1.363887e-002, 1.055411e-001, 5.648062e+000, 4.557412e-001, -1.070436e+000, -2.163341e-001, 7.098718e-001, 7.843075e-001, -4.323930e-001, 2.109823e+000, -9.589700e-002, -1.985193e-001, 1.060428e+000, -1.104879e+000, -3.013622e-002, 2.976276e-002, 1.069707e+000, 1.410000e-001, -4.880020e-001, 4.452288e-001, 6.418590e+000, 3.195986e-001, -1.048969e+000, -2.655317e-001, 2.689426e+000, -3.941038e+000, -9.506461e+000, 1.837119e+000, -1.892124e-001, -1.562146e+000, 9.043414e-001, -1.106145e+000, -1.601642e-001, 1.544544e+000, 7.388492e+000, -2.924600e+000, -4.328453e-001, 1.763161e-001, 2.523111e+000, 5.851902e-001, // albedo 1, turbidity 4 -1.203666e+000, -2.776587e-001, -2.084286e+000, 2.450840e+000, -8.746613e-002, 5.258507e-001, 7.983316e-002, 3.860055e+000, 5.486167e-001, -1.340448e+000, -4.230590e-001, 3.462849e-001, 4.707607e-001, -2.512626e-001, 1.530746e-001, 2.724218e-002, 3.035216e+000, 5.876133e-001, -1.014554e+000, -1.168790e-001, 9.477794e-001, -1.061218e+000, -4.196730e-001, 2.058832e+000, -5.989624e-002, 3.058168e+000, 9.763861e-001, -1.137388e+000, -9.854030e-002, -2.984893e-001, 3.647820e+000, -6.585571e-001, -1.479180e+000, 6.102932e-001, 3.265914e+000, 3.480333e-001, -1.021816e+000, -2.344957e-001, 2.463671e+000, -7.240685e+000, -8.862697e+000, 2.514058e+000, -2.122768e-001, -3.313968e-002, 9.028136e-001, -1.126581e+000, -1.874347e-001, 1.454154e+000, 1.034398e+001, -3.237393e+000, -8.654927e-001, 2.457248e-001, 1.845769e+000, 6.002482e-001, // albedo 1, turbidity 5 -1.263727e+000, -3.439354e-001, -1.786388e-001, 3.980166e-001, -3.349517e-001, 3.825166e-001, 1.029225e-001, 3.331096e+000, 4.998955e-001, -1.530010e+000, -6.879698e-001, 2.380415e-001, 1.608216e+000, -1.682679e+000, 3.546360e-001, -3.915220e-003, 4.517655e-001, 5.128605e-001, -9.685659e-001, 9.480403e-002, 6.076844e-002, -3.217561e+000, 4.568074e+000, 1.069299e+000, 2.083638e-002, 7.301088e+000, 1.072165e+000, -1.113925e+000, -3.112382e-001, 3.954133e-001, 5.105907e+000, -1.456866e+001, -4.917378e-001, 5.289909e-001, -2.678374e+000, 3.014709e-001, -1.046864e+000, -1.215754e-001, 1.778308e+000, 4.661489e+000, 2.565583e-001, 1.353680e+000, -1.175767e-001, 3.415972e+000, 8.457746e-001, -1.104480e+000, -1.940913e-001, 1.343668e+000, -1.759206e-003, -5.009204e+000, -4.186951e-001, 3.125710e-001, 1.628183e+000, 6.720408e-001, // albedo 1, turbidity 6 -1.286902e+000, -3.781238e-001, -8.977253e-002, 3.545393e-001, -4.866515e-001, 3.843664e-001, 8.281675e-002, 3.122231e+000, 5.046991e-001, -1.712597e+000, -8.549112e-001, 4.809286e-001, 1.515398e+000, -2.212211e+000, 2.539029e-001, 2.335997e-002, -6.089466e-002, 4.268444e-001, -8.807283e-001, 1.646097e-001, -4.437898e-001, -3.188247e+000, 5.984417e+000, 1.334779e+000, -4.026975e-002, 7.546431e+000, 1.175751e+000, -1.147253e+000, -3.538199e-001, 6.101836e-001, 4.437780e+000, -1.559813e+001, -1.103222e+000, 6.242039e-001, -3.091472e+000, 2.174290e-001, -1.038230e+000, -1.213475e-001, 1.547505e+000, 5.893176e+000, 1.368738e+000, 1.663127e+000, -1.377130e-001, 3.185279e+000, 8.736453e-001, -1.101026e+000, -1.874907e-001, 1.272667e+000, 3.596524e+000, -5.007243e+000, -6.352483e-001, 3.048985e-001, 1.931613e+000, 6.788844e-001, // albedo 1, turbidity 7 -1.342753e+000, -4.384971e-001, -1.213491e+000, 1.621399e+000, -1.551441e-001, 5.614218e-001, 2.591739e-002, 2.958967e+000, 5.782132e-001, -1.937684e+000, -1.066019e+000, 1.913336e+000, -7.347719e-001, -5.916167e-001, 1.587590e-001, 1.092568e-001, -6.275002e-001, 1.599071e-001, -9.302391e-001, 1.486187e-001, -1.603835e+000, 1.783713e-001, 1.100461e+000, 1.174181e+000, -1.602361e-001, 7.868331e+000, 1.468971e+000, -1.053631e+000, -3.727050e-001, 1.114117e+000, -9.603286e-001, -1.062469e+001, -1.162140e+000, 7.952797e-001, -4.478765e+000, -4.440862e-002, -1.083629e+000, -1.261405e-001, 1.229344e+000, 1.127825e+001, 1.319010e-001, 1.624729e+000, -2.825898e-001, 3.661082e+000, 1.036911e+000, -1.093950e+000, -2.067455e-001, 1.258035e+000, 7.548645e+000, -4.598387e+000, -8.944932e-001, 3.292634e-001, 1.311304e+000, 6.291871e-001, // albedo 1, turbidity 8 -1.385867e+000, -5.068139e-001, -1.486490e+000, 1.969049e+000, -1.698025e-001, 6.629167e-001, -5.289365e-006, 2.760315e+000, 8.644368e-001, -2.107367e+000, -1.175639e+000, 2.313241e+000, -1.001653e+000, -4.843139e-001, 1.124485e-001, 3.901494e-005, -3.502469e-001, -3.204780e-001, -1.475244e+000, -2.833055e-001, -2.085824e+000, 1.192563e+000, -7.645200e-001, 8.380081e-001, 2.203580e-001, 7.157885e+000, 1.753702e+000, -6.644372e-001, -2.549735e-001, 1.600273e+000, -8.589034e+000, -6.144718e+000, -7.599731e-001, 2.898370e-001, -5.770923e+000, -9.656242e-002, -1.211687e+000, -1.653494e-001, 8.393400e-001, 2.792988e+001, -3.395461e+000, 9.933752e-001, -3.976877e-002, 3.776659e+000, 9.546526e-001, -1.063757e+000, -2.037563e-001, 1.117207e+000, -1.252806e-003, -3.332330e+000, -6.971409e-001, 3.388719e-001, 1.311398e+000, 6.635171e-001, // albedo 1, turbidity 9 -1.678889e+000, -7.992295e-001, -2.421687e+000, 2.871029e+000, -7.662842e-002, 6.046208e-001, -7.598099e-006, 2.002314e+000, 9.001307e-001, -1.692144e+000, -8.804250e-001, 3.060895e+000, -2.000009e+000, -3.183563e-001, 8.385862e-002, -6.326713e-003, 1.206639e+000, -3.369967e-001, -3.676795e+000, -1.719207e+000, -2.534697e+000, 1.005285e+000, 1.550407e-001, 1.072910e+000, 1.318094e-001, 3.717018e+000, 1.689191e+000, 5.424542e-001, 3.263528e-001, 1.551055e+000, -3.841058e+000, -6.598996e+000, -1.201779e+000, 3.530669e-001, -2.542945e+000, -6.482523e-002, -1.553849e+000, -4.576860e-001, 9.324676e-001, 1.950982e+001, -2.344516e+000, 1.121020e+000, -1.221537e-001, 7.285496e-001, 9.582816e-001, -1.020650e+000, -2.215797e-001, 1.009774e+000, -2.056855e-003, -2.740338e+000, -8.122355e-001, 3.328967e-001, 8.982766e-001, 6.594676e-001, // albedo 1, turbidity 10 -2.247360e+000, -1.221267e+000, -3.072346e+000, 3.385139e+000, -4.387559e-002, 5.084887e-001, -7.418833e-006, 1.750107e+000, 9.001401e-001, -1.248499e+000, -8.442718e-001, 3.062611e+000, -2.020314e+000, -2.815341e-001, 5.254745e-002, 3.345008e-003, 1.433225e+000, -2.835911e-001, -7.004119e+000, -2.927978e+000, -2.649852e+000, 7.971894e-001, 5.466893e-001, 1.442667e+000, -6.063912e-002, 2.806194e+000, 1.547429e+000, 1.434882e+000, 9.114639e-002, 1.170089e+000, 3.512808e-002, -5.861915e+000, -1.411843e+000, 5.400486e-001, -7.746522e-001, 2.386984e-002, -1.559053e+000, -5.502302e-001, 1.200396e+000, 1.347741e+001, -2.344397e+000, 8.868907e-001, -3.292661e-001, -1.362105e+000, 9.217826e-001, -1.044436e+000, -2.360719e-001, 7.054471e-001, -2.904518e-003, -2.092829e+000, -5.119668e-001, 4.174861e-001, 9.687435e-001, 6.588427e-001, }; static float datasetRGBRad2[] = { // albedo 0, turbidity 1 1.590330e+000, 1.355401e+000, 1.151412e+000, 1.359116e+001, 5.857714e+000, 8.090833e+000, // albedo 0, turbidity 2 1.552540e+000, 1.510040e+000, 1.276413e-001, 1.604643e+001, 5.912162e+000, 8.350009e+000, // albedo 0, turbidity 3 1.470871e+000, 1.880464e+000, -1.865398e+000, 2.030808e+001, 5.471461e+000, 9.109834e+000, // albedo 0, turbidity 4 1.356563e+000, 2.373866e+000, -4.653245e+000, 2.570922e+001, 5.686009e+000, 1.009480e+001, // albedo 0, turbidity 5 1.244232e+000, 2.851519e+000, -7.130942e+000, 2.993449e+001, 6.382120e+000, 1.114578e+001, // albedo 0, turbidity 6 1.173693e+000, 3.120604e+000, -8.491886e+000, 3.187393e+001, 7.290615e+000, 1.180066e+001, // albedo 0, turbidity 7 1.091845e+000, 3.368888e+000, -9.722083e+000, 3.268508e+001, 1.032424e+001, 1.236508e+001, // albedo 0, turbidity 8 9.858985e-001, 3.500541e+000, -1.026328e+001, 3.092956e+001, 1.610881e+001, 1.331222e+001, // albedo 0, turbidity 9 8.864993e-001, 3.172888e+000, -8.687550e+000, 2.362161e+001, 2.621851e+001, 1.474967e+001, // albedo 0, turbidity 10 7.946973e-001, 2.189355e+000, -4.207953e+000, 9.399091e+000, 4.062849e+001, 1.681753e+001, // albedo 1, turbidity 1 1.711696e+000, 1.657311e+000, 9.328021e-001, 1.317880e+001, 1.506751e+001, 1.863556e+001, // albedo 1, turbidity 2 1.666968e+000, 1.849993e+000, -2.088601e-001, 1.586653e+001, 1.486880e+001, 1.940719e+001, // albedo 1, turbidity 3 1.584846e+000, 2.170022e+000, -2.019597e+000, 1.970826e+001, 1.490684e+001, 2.045055e+001, // albedo 1, turbidity 4 1.469412e+000, 2.524017e+000, -4.197267e+000, 2.365249e+001, 1.664588e+001, 2.134477e+001, // albedo 1, turbidity 5 1.369714e+000, 2.843548e+000, -6.059031e+000, 2.634993e+001, 1.881361e+001, 2.232186e+001, // albedo 1, turbidity 6 1.310477e+000, 2.984444e+000, -6.831686e+000, 2.682340e+001, 2.123267e+001, 2.259755e+001, // albedo 1, turbidity 7 1.222552e+000, 3.176523e+000, -7.731496e+000, 2.671760e+001, 2.484358e+001, 2.336863e+001, // albedo 1, turbidity 8 1.115781e+000, 3.130635e+000, -7.581744e+000, 2.336531e+001, 3.171048e+001, 2.413859e+001, // albedo 1, turbidity 9 1.013181e+000, 2.699342e+000, -5.602709e+000, 1.500158e+001, 4.217613e+001, 2.515957e+001, // albedo 1, turbidity 10 8.976323e-001, 1.726948e+000, -1.296120e+000, 1.183675e+000, 5.503215e+001, 2.643066e+001, }; static float datasetRGB3[] = { // albedo 0, turbidity 1 -1.372629e+000, -4.905585e-001, -4.100789e+001, 4.122169e+001, -7.389360e-003, 4.839359e-001, 6.474757e-003, 3.471755e+000, 5.092936e-001, -1.523025e+000, -6.497084e-001, 6.249857e+000, -5.662543e+000, -1.908402e-002, 5.512810e-001, -2.181049e-005, 2.507663e+000, 4.339598e-001, -1.035567e+000, -7.478740e-002, 9.221030e-001, -2.140047e+000, -2.374146e-002, 3.795517e-001, -1.769134e-002, 7.479831e+000, 7.729303e-001, -1.271086e+000, -5.588190e-001, 6.908023e-001, 2.096832e+000, -2.453967e-001, 1.410648e+000, 4.475036e-002, -4.719115e+000, 5.741186e-001, -9.712598e-001, -7.033926e-002, 9.167274e-001, -9.502097e-001, 3.004684e-001, 4.547054e-001, -5.929017e-002, 5.266196e+000, 7.204135e-001, -1.087457e+000, -1.888896e-001, 8.156686e-001, 3.101712e-001, -2.155419e+000, 1.422205e+000, 9.692261e-002, 3.122404e+000, 4.999430e-001, // albedo 0, turbidity 2 -1.425280e+000, -5.413508e-001, -3.454883e+001, 3.481142e+001, -8.686975e-003, 4.914268e-001, -2.479243e-006, 3.239879e+000, 6.094201e-001, -1.688557e+000, -8.070865e-001, 7.018459e+000, -6.244574e+000, -2.149341e-002, 3.993971e-001, 1.252502e-002, 1.630662e+000, 1.097860e-001, -8.664152e-001, 7.869125e-002, -5.236535e-001, -1.218960e+000, -2.059093e-002, 6.684898e-001, -5.584112e-002, 8.602299e+000, 1.410496e+000, -1.319763e+000, -5.985323e-001, 1.253918e+000, 1.914706e+000, -3.216739e-001, 9.011213e-001, 1.324845e-001, -5.252749e+000, 6.231252e-002, -9.706008e-001, -5.914059e-002, 5.693150e-001, -1.175362e+000, 5.221644e-001, 7.518213e-001, -8.247655e-002, 5.875635e+000, 9.850863e-001, -1.085330e+000, -1.956105e-001, 8.019605e-001, 5.338101e-001, -3.423464e+000, 1.110444e+000, 1.507923e-001, 2.864942e+000, 4.999481e-001, // albedo 0, turbidity 3 -1.431967e+000, -5.478935e-001, -3.286288e+001, 3.305288e+001, -8.380797e-003, 4.772050e-001, -3.044274e-006, 3.289973e+000, 5.976303e-001, -1.801361e+000, -9.315889e-001, 5.391756e+000, -4.588592e+000, -2.040076e-002, 4.144684e-001, 1.814534e-002, 1.051795e+000, 1.145651e-001, -7.905357e-001, 1.451332e-001, -1.605661e-001, -1.592174e+000, 4.561348e-004, 3.380323e-001, -7.770275e-002, 8.775384e+000, 1.489512e+000, -1.308575e+000, -5.539232e-001, 9.184133e-001, 2.011479e+000, -3.842472e-001, 1.432274e+000, 1.637153e-001, -4.408856e+000, 5.272957e-002, -9.829872e-001, -8.183048e-002, 4.464556e-001, -1.442716e+000, 1.029641e+000, -6.991617e-002, 8.702356e-003, 5.706417e+000, 9.116452e-001, -1.087130e+000, -2.038013e-001, 7.260801e-001, 9.164376e-001, -5.006183e+000, 1.511271e+000, 1.257134e-001, 2.715439e+000, 6.201652e-001, // albedo 0, turbidity 4 -1.448662e+000, -5.799075e-001, -2.833268e+001, 2.858023e+001, -9.134061e-003, 4.404783e-001, -2.709026e-006, 3.029357e+000, 5.540071e-001, -2.061772e+000, -1.145190e+000, 7.918478e+000, -7.212525e+000, -2.020760e-002, 2.962715e-001, 4.689670e-002, 8.517209e-001, 2.334587e-001, -6.413755e-001, 1.780425e-001, -2.412919e+000, 1.064484e+000, -1.949986e-002, 6.769741e-001, -1.752760e-001, 7.262714e+000, 1.325869e+000, -1.304871e+000, -3.975581e-001, 1.219002e+000, 7.285178e-001, -2.710105e-001, 7.779727e-001, 3.247139e-001, -8.818168e-001, 1.839517e-001, -1.001104e+000, -1.994801e-001, 3.676742e-001, -1.409737e+000, 2.901555e-001, 2.506940e-001, 2.468899e-003, 3.398923e+000, 8.584645e-001, -1.111552e+000, -2.487204e-001, 7.410842e-001, 1.703749e+000, -5.007855e+000, 1.057763e+000, 1.354511e-001, 2.088715e+000, 6.600013e-001, // albedo 0, turbidity 5 -1.547227e+000, -6.679466e-001, -1.861465e+001, 1.884045e+001, -1.242210e-002, 4.157339e-001, -2.432805e-006, 2.812423e+000, 5.446957e-001, -2.043890e+000, -1.149081e+000, 2.304118e+000, -1.715757e+000, -2.433628e-002, 2.816836e-001, 7.185458e-002, 1.064860e+000, 2.706789e-001, -9.040720e-001, -8.274472e-002, -2.555676e-001, -6.326215e-001, -2.770880e-002, 6.676024e-001, -2.513532e-001, 5.903839e+000, 1.241452e+000, -1.000013e+000, -1.010774e-001, 3.699166e-001, 8.774526e-001, -3.042007e-001, 6.951053e-001, 4.361813e-001, 6.793421e-001, 2.573892e-001, -1.171332e+000, -3.768188e-001, 3.701377e-001, -1.470757e+000, 5.525942e-001, 2.991456e-002, 1.581823e-002, 2.365233e+000, 8.214514e-001, -1.068667e+000, -2.326330e-001, 6.725059e-001, 2.243733e+000, -4.614370e+000, 1.033677e+000, 1.376291e-001, 2.013334e+000, 6.865304e-001, // albedo 0, turbidity 6 -1.592991e+000, -7.246948e-001, -2.598204e+001, 2.621960e+001, -8.365176e-003, 4.207571e-001, -2.742772e-006, 2.623735e+000, 5.873190e-001, -2.271349e+000, -1.280884e+000, 6.308739e+000, -5.758350e+000, -1.977049e-002, 3.671835e-001, 6.698038e-002, 1.150597e+000, 1.759218e-001, -6.368620e-001, -7.436052e-003, -2.230026e+000, 1.640997e+000, -1.548497e-002, 3.145331e-001, -2.492644e-001, 5.083843e+000, 1.260215e+000, -1.177925e+000, -9.628114e-002, 3.051152e-001, -3.749544e-002, -2.713209e-001, 1.164226e+000, 4.559969e-001, 2.175429e+000, 2.874284e-001, -1.078500e+000, -3.801779e-001, 4.788906e-001, -4.795969e-001, 5.977621e-001, -4.488535e-001, 3.386874e-002, 1.538143e+000, 8.062054e-001, -1.108028e+000, -2.596892e-001, 5.162202e-001, 1.557081e+000, -4.265039e+000, 1.182535e+000, 1.563762e-001, 2.095084e+000, 6.883383e-001, // albedo 0, turbidity 7 -1.668427e+000, -7.908511e-001, -2.779690e+001, 2.799746e+001, -7.186935e-003, 3.757766e-001, -3.326858e-006, 2.563421e+000, 5.439687e-001, -2.156175e+000, -1.220004e+000, 3.585732e+000, -3.235988e+000, -1.086239e-002, 1.846143e-001, 1.046017e-001, 1.234427e+000, 2.842191e-001, -1.117051e+000, -4.101627e-001, -8.463730e-001, 7.671472e-001, -2.226609e-002, 8.574943e-001, -3.434124e-001, 4.475715e+000, 1.154824e+000, -7.444840e-001, 2.312078e-001, -5.393724e-001, 1.574213e-001, -1.763914e-001, 2.751692e-001, 5.564200e-001, 2.217672e+000, 3.483932e-001, -1.273036e+000, -5.275562e-001, 4.902512e-001, -4.498436e-002, 4.339366e-001, 2.386682e-001, 2.380879e-002, 1.413444e+000, 7.855923e-001, -1.084192e+000, -2.936753e-001, 4.719432e-001, 1.384436e+000, -3.257789e+000, 6.119543e-001, 1.681884e-001, 1.650441e+000, 6.936631e-001, // albedo 0, turbidity 8 -1.848490e+000, -9.512670e-001, -3.005251e+001, 3.024315e+001, -5.635304e-003, 3.447780e-001, -2.782999e-006, 2.309422e+000, 5.643559e-001, -2.300008e+000, -1.252335e+000, -1.218876e+000, 1.493730e+000, -6.107100e-003, 7.974860e-002, 1.023449e-001, 1.505934e+000, 2.360948e-001, -1.483705e+000, -8.547575e-001, -7.797146e-001, 6.447971e-001, -2.678052e-002, 1.091263e+000, -3.344889e-001, 3.830416e+000, 1.189425e+000, -5.348005e-001, 3.982733e-001, -4.071573e-001, 3.265569e-001, -8.658789e-002, -2.370892e-001, 5.369097e-001, 1.478279e+000, 3.143303e-001, -1.320401e+000, -6.043247e-001, 3.019196e-001, -7.732911e-002, 4.768381e-001, 6.745764e-001, 3.694098e-002, 1.158234e+000, 8.169056e-001, -1.101040e+000, -3.420019e-001, 3.775661e-001, 1.769338e+000, -2.990515e+000, 1.649529e-001, 1.970125e-001, 1.453355e+000, 6.759757e-001, // albedo 0, turbidity 9 -2.251946e+000, -1.229349e+000, -3.271808e+001, 3.283114e+001, -4.252027e-003, 3.372289e-001, -3.001937e-006, 2.154046e+000, 5.842674e-001, -1.867834e+000, -9.531252e-001, -1.229365e+001, 1.269149e+001, -6.844772e-003, 1.185107e-001, 7.539587e-002, 1.846381e+000, 1.899412e-001, -3.398629e+000, -2.180862e+000, 2.335213e+000, -3.382823e+000, -8.613985e-003, 8.431602e-001, -2.393567e-001, 3.112460e+000, 1.218556e+000, 5.708381e-001, 9.406030e-001, -6.890113e-001, 2.746233e+000, -5.772068e-002, 1.096005e-001, 3.491978e-001, 7.281453e-001, 3.212049e-001, -1.705909e+000, -8.517224e-001, 1.131160e-001, -2.141434e+000, 4.274043e-001, 3.397600e-001, 1.786490e-001, 9.026101e-001, 7.882800e-001, -1.012865e+000, -3.495551e-001, 3.369038e-001, 3.724205e+000, -3.089586e+000, 1.266964e-001, 1.461790e-001, 1.170199e+000, 6.931052e-001, // albedo 0, turbidity 10 -2.890318e+000, -1.665573e+000, -3.493756e+001, 3.500369e+001, -2.984251e-003, 2.622419e-001, -4.259360e-006, 1.947681e+000, 6.905752e-001, -1.956022e+000, -1.062900e+000, -1.919714e+001, 1.975164e+001, -8.865396e-003, 2.165540e-001, 5.475637e-002, 1.761134e+000, 3.164249e-003, -5.612198e+000, -3.101371e+000, 4.098034e+000, -6.144001e+000, 9.944958e-003, 2.905472e-001, -1.707110e-001, 3.199107e+000, 1.337660e+000, 8.353756e-001, 4.855943e-001, -1.243589e+000, 5.147385e+000, -7.013963e-002, 9.380410e-001, 2.335714e-001, 1.727744e-001, 2.802696e-001, -1.524329e+000, -7.388547e-001, 3.259025e-001, -4.050634e+000, 4.058549e-001, -2.591384e-001, 1.898299e-001, 3.556071e-001, 7.884126e-001, -1.070371e+000, -4.207858e-001, 1.739862e-001, 5.293410e+000, -3.136757e+000, 2.323856e-001, 1.673706e-001, 1.007227e+000, 6.844287e-001, // albedo 1, turbidity 1 -1.341720e+000, -4.834889e-001, -4.633447e+001, 4.682148e+001, -6.137296e-003, 4.599216e-001, 7.047323e-003, 2.895798e+000, 4.999398e-001, -1.529104e+000, -6.498631e-001, 1.534103e+001, -1.450675e+001, -1.531439e-002, 3.280082e-001, 1.682926e-002, 1.901587e+000, 5.013227e-001, -1.014776e+000, -1.454495e-001, -4.071085e+000, 2.954982e+000, -2.630348e-002, 5.681531e-001, -3.016505e-002, 6.773854e+000, 5.003504e-001, -1.172413e+000, -4.026320e-001, 2.960428e+000, 2.020710e-001, -2.004947e-001, 9.375572e-001, 5.998168e-002, -4.945934e+000, 4.502898e-001, -9.898161e-001, -5.772814e-002, 4.470024e-001, -5.786656e-001, 1.158168e-001, 3.468040e-001, -5.043360e-002, 6.867947e+000, 8.012363e-001, -1.085111e+000, -1.882675e-001, 1.223748e+000, 3.565495e-001, -3.688357e+000, 5.653723e-001, 6.727646e-002, 2.690130e+000, 4.999400e-001, // albedo 1, turbidity 2 -1.389119e+000, -5.290250e-001, -4.055774e+001, 4.105972e+001, -7.062577e-003, 4.560060e-001, -1.736334e-006, 2.775512e+000, 6.671455e-001, -1.584641e+000, -7.200619e-001, 1.248067e+001, -1.156028e+001, -1.659568e-002, 3.050029e-001, 1.099895e-002, 1.438927e+000, -2.138015e-002, -9.826068e-001, -8.887254e-002, -2.960031e+000, 1.808816e+000, -2.478159e-002, 6.035733e-001, -4.868441e-002, 7.347705e+000, 1.584739e+000, -1.150423e+000, -4.073793e-001, 2.412991e+000, 4.870840e-001, -2.337902e-001, 8.295114e-001, 1.129914e-001, -5.150045e+000, -9.016643e-002, -1.016933e+000, -6.311501e-002, 5.218937e-001, -5.716430e-001, 1.250993e-001, 3.601524e-001, -5.497586e-002, 7.060139e+000, 1.018333e+000, -1.073151e+000, -1.845444e-001, 1.155394e+000, 3.004486e-001, -3.431711e+000, 4.657031e-001, 9.401223e-002, 2.688620e+000, 4.999544e-001, // albedo 1, turbidity 3 -1.391257e+000, -5.365815e-001, -4.255881e+001, 4.299132e+001, -5.838466e-003, 4.229134e-001, -2.760038e-006, 2.775531e+000, 6.234597e-001, -1.780062e+000, -9.228880e-001, 1.376172e+001, -1.260946e+001, -1.507526e-002, 3.117435e-001, 2.205045e-002, 6.093731e-001, 3.463446e-002, -7.388169e-001, 1.275670e-001, -3.999528e+000, 2.223993e+000, -1.856853e-002, 5.439310e-001, -8.834054e-002, 8.037139e+000, 1.645951e+000, -1.322387e+000, -5.320143e-001, 2.659359e+000, 1.086712e+000, -2.129712e-001, 8.704649e-001, 1.800315e-001, -4.967241e+000, -1.383720e-001, -9.378288e-001, -1.599895e-002, 3.607555e-001, -1.980561e+000, 3.791456e-001, 1.212268e-001, -2.845992e-002, 6.825542e+000, 1.059139e+000, -1.100832e+000, -2.172313e-001, 1.211561e+000, 2.002721e+000, -5.010011e+000, 5.717583e-001, 6.777702e-002, 2.160006e+000, 5.676392e-001, // albedo 1, turbidity 4 -1.409373e+000, -5.708751e-001, -3.034974e+001, 3.079809e+001, -7.280715e-003, 3.723304e-001, -2.436279e-006, 2.577348e+000, 5.913377e-001, -1.954312e+000, -1.116510e+000, 5.399148e+000, -4.299553e+000, -1.724739e-002, 3.742824e-001, 4.187077e-002, 1.044883e-001, 1.232727e-001, -6.772215e-001, 2.001396e-001, -3.670523e-001, -1.014628e+000, -3.497152e-003, 4.099858e-001, -1.584633e-001, 7.750400e+000, 1.514559e+000, -1.291600e+000, -4.977437e-001, 9.641914e-001, 1.562420e+000, -3.227782e-001, 9.055427e-001, 3.046444e-001, -3.385619e+000, 9.546291e-003, -9.750857e-001, -8.770560e-002, 9.054256e-001, -1.429236e+000, 8.974777e-001, -1.217961e-001, -5.194608e-002, 4.909409e+000, 9.589153e-001, -1.088007e+000, -1.959301e-001, 9.745799e-001, 1.260761e+000, -5.008864e+000, 7.271248e-001, 1.096661e-001, 2.717295e+000, 6.340731e-001, // albedo 1, turbidity 5 -1.456050e+000, -6.223072e-001, -2.228088e+001, 2.269604e+001, -9.340812e-003, 4.118308e-001, -2.418083e-006, 2.442117e+000, 5.589638e-001, -2.176449e+000, -1.302416e+000, 2.222836e+000, -1.222730e+000, -1.728051e-002, 1.323513e-001, 7.027731e-002, 4.835745e-002, 2.093351e-001, -5.789641e-001, 2.215407e-001, 2.142291e-001, -1.201725e+000, -1.185728e-002, 8.122982e-001, -2.380420e-001, 6.706841e+000, 1.404146e+000, -1.307463e+000, -4.515174e-001, 6.447827e-001, 1.223841e+000, -2.902391e-001, 4.986588e-001, 4.073652e-001, -1.706696e+000, 1.060885e-001, -9.698678e-001, -1.307094e-001, 9.389347e-001, -1.522852e+000, 7.768797e-001, -1.368595e-001, -3.857426e-002, 3.676935e+000, 8.980966e-001, -1.104349e+000, -2.380323e-001, 1.047043e+000, 1.865421e+000, -5.011664e+000, 7.014954e-001, 9.622701e-002, 1.891360e+000, 6.687354e-001, // albedo 1, turbidity 6 -1.502249e+000, -6.724523e-001, -2.888092e+001, 2.930360e+001, -6.685766e-003, 3.685464e-001, -2.469442e-006, 2.310797e+000, 5.566754e-001, -2.217125e+000, -1.364924e+000, 4.048243e+000, -3.111333e+000, -1.317747e-002, 1.921948e-001, 8.627702e-002, 1.981769e-003, 2.213689e-001, -6.215757e-001, 1.687995e-001, -5.949131e-001, -1.551293e-001, 3.356129e-004, 6.897657e-001, -2.855053e-001, 6.271042e+000, 1.363084e+000, -1.216317e+000, -3.489429e-001, 7.566226e-001, 5.409809e-001, -2.830843e-001, 6.191825e-001, 4.755163e-001, -9.131387e-001, 1.383909e-001, -1.030437e+000, -2.034064e-001, 8.335995e-001, -1.050947e+000, 8.689093e-001, -3.672310e-001, -4.056183e-002, 3.111269e+000, 8.856842e-001, -1.078984e+000, -2.070549e-001, 9.683145e-001, 1.497022e+000, -5.007653e+000, 7.702541e-001, 1.285822e-001, 2.225188e+000, 6.587911e-001, // albedo 1, turbidity 7 -1.559291e+000, -7.374039e-001, -3.596311e+001, 3.634470e+001, -4.667132e-003, 3.277964e-001, -2.487945e-006, 2.215652e+000, 5.764681e-001, -2.356929e+000, -1.444755e+000, 6.244526e+000, -5.540162e+000, -8.794510e-003, 1.792100e-001, 9.578517e-002, 3.737676e-001, 1.922194e-001, -6.589752e-001, -2.926910e-002, -1.831779e+000, 1.869962e+000, -2.030095e-003, 7.552089e-001, -3.168157e-001, 4.632196e+000, 1.294054e+000, -1.161046e+000, -1.472506e-001, 6.494138e-001, -8.327174e-001, -2.320724e-001, 3.391212e-001, 5.269637e-001, 9.376341e-001, 2.458573e-001, -1.034427e+000, -3.062504e-001, 8.975634e-001, 3.203531e-001, 8.565142e-001, -1.250162e-001, -4.094017e-002, 1.861304e+000, 8.223468e-001, -1.109954e+000, -2.740277e-001, 1.063811e+000, 7.077398e-001, -4.695734e+000, 5.621696e-001, 1.248956e-001, 1.297723e+000, 6.789720e-001, // albedo 1, turbidity 8 -1.788293e+000, -9.368751e-001, -4.382980e+001, 4.424963e+001, -3.652530e-003, 3.094331e-001, -2.810503e-006, 1.904402e+000, 5.861599e-001, -2.268206e+000, -1.312676e+000, 2.863082e+000, -2.373727e+000, -5.144980e-003, 1.711072e-001, 9.316041e-002, 9.309598e-001, 1.791683e-001, -1.376966e+000, -7.418582e-001, -1.349589e+000, 1.563419e+000, -3.124219e-003, 6.967139e-001, -3.061887e-001, 3.602731e+000, 1.255669e+000, -6.017540e-001, 2.815928e-001, 5.424052e-001, -6.885450e-001, -1.620001e-001, 2.980046e-001, 4.995571e-001, 7.371203e-001, 2.812466e-001, -1.278853e+000, -5.245326e-001, 7.870520e-001, 3.125067e-001, 7.748105e-001, -7.788581e-002, 3.490956e-003, 1.283748e+000, 8.130190e-001, -1.050930e+000, -2.786331e-001, 1.056344e+000, 1.053002e+000, -4.047789e+000, 4.432174e-001, 1.169077e-001, 9.532621e-001, 6.806764e-001, // albedo 1, turbidity 9 -2.084927e+000, -1.203954e+000, -4.881638e+001, 4.920160e+001, -2.896045e-003, 2.882977e-001, -3.073517e-006, 1.702211e+000, 6.374180e-001, -2.328567e+000, -1.238023e+000, -1.891019e+000, 2.451520e+000, -5.847581e-003, 2.084702e-001, 7.848130e-002, 1.211048e+000, 8.095008e-002, -2.634632e+000, -1.789460e+000, -1.370558e-001, -3.326435e-001, 2.783737e-003, 5.239451e-001, -2.548881e-001, 2.896327e+000, 1.324116e+000, 6.882616e-002, 5.997821e-001, 1.535398e-001, 1.375209e+000, -1.267285e-001, 4.239743e-001, 4.013122e-001, 1.794675e-001, 2.395382e-001, -1.430918e+000, -6.439041e-001, 8.325980e-001, -1.705612e+000, 7.236426e-001, -5.567593e-002, 6.408718e-002, 6.836524e-001, 8.388887e-001, -1.037956e+000, -3.215402e-001, 9.457349e-001, 3.178114e+000, -4.152156e+000, 2.230992e-001, 1.156198e-001, 7.606223e-001, 6.656923e-001, // albedo 1, turbidity 10 -2.967314e+000, -1.728778e+000, -3.730988e+001, 3.755578e+001, -2.588835e-003, 2.927966e-001, -3.935038e-006, 1.592161e+000, 6.868694e-001, -2.123311e+000, -1.175148e+000, -1.314988e+001, 1.386882e+001, -7.828537e-003, 1.852026e-001, 5.481038e-002, 1.294309e+000, 2.428177e-002, -5.443597e+000, -3.156344e+000, 2.110838e+000, -3.421556e+000, 1.181890e-002, 1.196951e-001, -1.742902e-001, 2.404353e+000, 1.272805e+000, 1.029898e+000, 5.912521e-001, -3.983531e-001, 3.286069e+000, -9.252065e-002, 1.331381e+000, 2.560642e-001, 8.001754e-001, 3.624178e-001, -1.547574e+000, -7.881604e-001, 1.020902e+000, -2.897069e+000, 5.213470e-001, -9.242315e-001, 1.185594e-001, -1.150721e+000, 7.317211e-001, -9.621043e-001, -1.991406e-001, 6.531287e-001, 3.925839e+000, -3.596904e+000, 6.317332e-001, 1.531334e-001, 1.457846e+000, 6.966285e-001, }; static float datasetRGBRad3[] = { // albedo 0, turbidity 1 9.926518e-001, 1.999494e+000, -4.136109e+000, 1.856270e+001, 1.351028e+001, 1.390238e+001, // albedo 0, turbidity 2 9.634366e-001, 2.119694e+000, -4.614523e+000, 1.919701e+001, 1.376644e+001, 1.418731e+001, // albedo 0, turbidity 3 9.446537e-001, 2.171610e+000, -4.915556e+000, 1.918240e+001, 1.537135e+001, 1.400530e+001, // albedo 0, turbidity 4 9.073074e-001, 2.330536e+000, -5.577596e+000, 1.961615e+001, 1.688365e+001, 1.446955e+001, // albedo 0, turbidity 5 8.739124e-001, 2.388682e+000, -5.842995e+000, 1.923265e+001, 1.887735e+001, 1.485698e+001, // albedo 0, turbidity 6 8.563688e-001, 2.391534e+000, -5.769133e+000, 1.828709e+001, 2.097209e+001, 1.469587e+001, // albedo 0, turbidity 7 8.270533e-001, 2.342790e+000, -5.558071e+000, 1.684993e+001, 2.356498e+001, 1.505975e+001, // albedo 0, turbidity 8 7.908339e-001, 2.190341e+000, -4.852571e+000, 1.374862e+001, 2.806846e+001, 1.548444e+001, // albedo 0, turbidity 9 7.403619e-001, 1.783998e+000, -2.983854e+000, 7.622563e+000, 3.507610e+001, 1.615805e+001, // albedo 0, turbidity 10 6.840111e-001, 1.154457e+000, -2.393830e-001, -7.896893e-001, 4.282765e+001, 1.779469e+001, // albedo 1, turbidity 1 1.168300e+000, 1.860993e+000, -2.129074e+000, 1.251952e+001, 3.032499e+001, 2.938716e+001, // albedo 1, turbidity 2 1.150338e+000, 1.918813e+000, -2.413527e+000, 1.274862e+001, 3.087134e+001, 2.951432e+001, // albedo 1, turbidity 3 1.114719e+000, 1.964689e+000, -2.625423e+000, 1.247837e+001, 3.237949e+001, 2.943596e+001, // albedo 1, turbidity 4 1.077948e+000, 2.006292e+000, -2.846934e+000, 1.190195e+001, 3.459293e+001, 2.937492e+001, // albedo 1, turbidity 5 1.035143e+000, 1.986681e+000, -2.752584e+000, 1.060972e+001, 3.722185e+001, 2.918594e+001, // albedo 1, turbidity 6 1.015992e+000, 1.992054e+000, -2.812626e+000, 1.001416e+001, 3.847300e+001, 2.924624e+001, // albedo 1, turbidity 7 9.756887e-001, 1.939897e+000, -2.533281e+000, 8.319176e+000, 4.083907e+001, 2.925586e+001, // albedo 1, turbidity 8 9.264164e-001, 1.716454e+000, -1.597044e+000, 4.739725e+000, 4.507683e+001, 2.878915e+001, // albedo 1, turbidity 9 8.595191e-001, 1.346034e+000, -2.801895e-002, -6.582906e-001, 5.017523e+001, 2.852953e+001, // albedo 1, turbidity 10 7.754116e-001, 7.709245e-001, 2.200201e+000, -7.487661e+000, 5.436622e+001, 2.893432e+001, }; static float *datasetsRGB[] = {datasetRGB1, datasetRGB2, datasetRGB3}; static float *datasetsRGBRad[] = {datasetRGBRad1, datasetRGBRad2, datasetRGBRad3}; RenderKit-ospray-85af292/modules/cpu/lights/sky_model/sky_model_data_spectral.h000066400000000000000000022600451464752671100300500ustar00rootroot00000000000000/* This source is published under the following 3-clause BSD license. Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * None of the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // with slight modifications // Copyright 2020 Intel Corporation /* ============================================================================ This file is part of a sample implementation of the analytical skylight and solar radiance models presented in the SIGGRAPH 2012 paper "An Analytic Model for Full Spectral Sky-Dome Radiance" and the 2013 IEEE CG&A paper "Adding a Solar Radiance Function to the Hosek Skylight Model" both by Lukas Hosek and Alexander Wilkie Charles University in Prague, Czech Republic Version: 1.4a, February 22nd, 2013 Version history: 1.4a February 22nd, 2013 Removed unnecessary and counter-intuitive solar radius parameters from the interface of the colourspace sky dome initialisation functions. 1.4 February 11th, 2013 Fixed a bug which caused the relative brightness of the solar disc and the sky dome to be off by a factor of about 6. The sun was too bright: this affected both normal and alien sun scenarios. The coefficients of the solar radiance function were changed to fix this. 1.3 January 21st, 2013 (not released to the public) Added support for solar discs that are not exactly the same size as the terrestrial sun. Also added support for suns with a different emission spectrum ("Alien World" functionality). 1.2a December 18th, 2012 Fixed a mistake and some inaccuracies in the solar radiance function explanations found in ArHosekSkyModel.h. The actual source code is unchanged compared to version 1.2. 1.2 December 17th, 2012 Native RGB data and a solar radiance function that matches the turbidity conditions were added. 1.1 September 2012 The coefficients of the spectral model are now scaled so that the output is given in physical units: W / (m^-2 * sr * nm). Also, the output of the XYZ model is now no longer scaled to the range [0...1]. Instead, it is the result of a simple conversion from spectral data via the CIE 2 degree standard observer matching functions. Therefore, after multiplication with 683 lm / W, the Y channel now corresponds to luminance in lm. 1.0 May 11th, 2012 Initial release. Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if an updated version of this code has been published! ============================================================================ */ /* This file contains the coefficient data for the spectral version of the model. */ // uses Apr 26 dataset static float dataset320[] = { // albedo 0, turbidity 1 -1.341049e+001, -3.742293e+000, -5.229614e+000, 5.307180e+000, -2.182658e-002, 1.497676e-001, -8.561730e-006, 1.733480e+000, 8.826913e-001, -1.426825e+001, -3.550926e+000, 5.719350e-002, 3.165753e-001, -5.870693e-002, 1.333896e-001, 1.779338e-005, 1.504276e+000, 9.750357e-001, -2.239068e+000, -4.290407e+000, -7.494879e-001, 2.864989e-001, -6.017855e-002, 1.325901e-001, -1.661674e-004, 1.732120e+000, 6.513374e-001, -1.336194e+000, -2.467808e-001, 3.961139e-001, -6.723820e-002, -1.817268e-001, 1.017581e-002, 6.096079e-004, 1.986859e+000, 1.415296e+000, -1.554271e+000, -1.811527e+000, 7.309756e-001, 1.766793e-003, 5.779090e-001, 6.186216e-001, -1.755338e-003, -2.701090e-002, 2.699530e-001, -8.449639e-001, -5.665198e-001, 5.525823e-001, -2.838870e-003, -4.555228e+000, 2.824945e-001, 4.002014e-003, 1.114208e+000, 6.637074e-001, // albedo 0, turbidity 2 -1.298333e+001, -3.775577e+000, -5.173531e+000, 5.316518e+000, -2.572615e-002, 1.516601e-001, -8.297168e-006, 1.669649e+000, 9.000495e-001, -1.402639e+001, -3.787558e+000, 7.611941e-002, 2.521881e-001, -5.859973e-002, 1.753711e-001, 4.670097e-005, 1.459275e+000, 8.998629e-001, -2.190256e+000, -3.575495e+000, -4.930996e-001, 4.826321e-002, -6.797145e-002, 3.425922e-002, -3.512550e-004, 1.978419e+000, 8.866517e-001, -2.415991e+000, -1.453294e+000, 2.170671e-001, 1.341284e-001, -1.926330e-001, 1.059103e-001, 1.360739e-003, 1.587725e+000, 9.821154e-001, -5.254592e-001, -8.181026e-001, 7.535702e-001, -3.323364e-002, 4.503149e-001, 5.778285e-001, -4.089673e-003, 3.335089e-001, 6.827164e-001, -1.280108e+000, -1.013716e+000, 5.577676e-001, 9.539205e-004, -4.934956e+000, 2.642883e-001, 1.005169e-002, 9.265844e-001, 4.999698e-001, // albedo 0, turbidity 3 -1.292247e+001, -3.819777e+000, -4.478733e+000, 4.582924e+000, -2.364370e-002, 1.619828e-001, -3.053548e-006, 1.646629e+000, 5.103371e-001, -1.433099e+001, -3.766213e+000, 4.930150e-001, -3.081235e-002, -6.522199e-002, 1.564198e-001, 3.455657e-004, 1.428507e+000, 4.312273e-001, -2.539220e+000, -3.459074e+000, -3.774393e-001, -3.628419e-001, -2.124451e-001, -1.358132e-002, -1.812805e-003, 2.245152e+000, 7.247429e-001, -2.393246e+000, -1.937898e+000, 1.005834e-001, 5.867890e-001, 2.645044e-001, 1.413695e-001, 6.378716e-003, 1.140715e+000, 1.263014e+000, -1.185583e-001, -1.960943e-001, 7.212723e-001, -1.763978e-001, -1.000190e+000, 6.259726e-001, -1.783726e-002, 7.790644e-001, 3.244710e-001, -1.550325e+000, -1.333575e+000, 5.618137e-001, 2.563595e-002, -5.007716e+000, 6.522985e-002, 4.262830e-002, 7.371930e-001, 5.239972e-001, // albedo 0, turbidity 4 -1.234358e+001, -3.851875e+000, -3.911206e+000, 4.011324e+000, -2.734425e-002, 1.272306e-001, -7.628210e-006, 1.661843e+000, 8.993903e-001, -1.349727e+001, -3.592681e+000, 1.335192e+000, -9.426446e-001, -5.741127e-002, 9.765267e-002, 5.518099e-005, 1.428554e+000, -4.278471e-001, -3.399618e+000, -3.818725e+000, -8.698171e-001, 2.723930e-001, -3.644369e-001, 1.238759e-001, -5.189179e-004, 2.279175e+000, 1.841076e+000, -1.925152e+000, -1.539333e+000, 2.757771e-001, -6.435980e-002, 6.466700e-001, 3.084382e-002, 3.114730e-003, 1.259818e+000, 5.121617e-001, -5.706832e-001, -6.696186e-001, 6.798158e-001, 6.920162e-001, -3.898854e+000, 5.954021e-001, -1.196667e-002, 5.714991e-001, 6.528481e-001, -1.371907e+000, -1.142330e+000, 5.207805e-001, -4.480298e-003, -5.008950e+000, 1.251549e-001, 3.531514e-002, 8.776759e-001, 4.999465e-001, // albedo 0, turbidity 5 -1.459738e+001, -3.833562e+000, -4.148717e+000, 4.203270e+000, -2.484405e-002, 1.189704e-001, 4.166397e-004, 1.748850e+000, 4.999721e-001, -1.223022e+001, -3.942049e+000, 1.183072e+000, -9.018678e-001, -4.644071e-002, 1.237476e-001, -2.359994e-003, 1.471013e+000, 5.298845e-001, -4.078262e+000, -3.261096e+000, -5.520001e-001, 2.174261e-001, -3.582576e-001, 2.000597e-002, 9.890182e-003, 2.199274e+000, 2.756320e-001, -2.499065e+000, -2.408391e+000, 3.391663e-002, -6.167543e-002, 7.555424e-001, 2.349252e-001, -2.443140e-002, 1.328540e+000, 1.348906e+000, 5.456648e-002, -9.221401e-002, 7.403428e-001, 5.565324e-001, -5.134970e+000, 3.021763e-001, 3.638500e-002, 5.560149e-001, 1.818210e-001, -1.590269e+000, -1.344330e+000, 4.805789e-001, 5.038509e-001, -3.370644e+000, 3.040357e-001, 2.418483e-003, 8.979818e-001, 7.477974e-001, // albedo 0, turbidity 6 -6.775680e+000, -3.436745e+000, -2.696730e+000, 2.740681e+000, -4.032382e-002, 1.036486e-001, 8.133034e-005, 1.767160e+000, 5.401354e-001, -7.800595e+000, -2.867058e+000, 1.478909e+000, -1.380160e+000, -1.658909e-001, 1.962673e-001, -6.512798e-004, 1.634359e+000, 4.300704e-001, -4.392403e+000, -3.857979e+000, -1.022020e+000, 1.449394e+000, 2.769695e-001, -3.331834e-001, 3.513950e-003, 1.942113e+000, 3.970742e-001, -2.469701e+000, -1.357319e+000, 2.132600e-001, -1.918729e+000, -4.193060e+000, 8.101579e-001, -9.605279e-003, 1.844443e+000, 1.582310e+000, -7.759612e-001, -1.298076e+000, 7.162377e-001, 2.906682e+000, -8.261148e-001, -2.892123e-001, 1.491449e-002, 6.529387e-002, -4.180287e-002, -9.962340e-001, -6.488730e-001, 3.933344e-001, -4.752111e-003, -4.721793e+000, 6.053196e-001, 3.453563e-003, 1.247655e+000, 8.673379e-001, // albedo 0, turbidity 7 -7.552689e+000, -3.219112e+000, -2.730242e+000, 2.755929e+000, -3.925138e-002, 8.394617e-002, 1.514980e-004, 1.844410e+000, 5.389194e-001, -8.494732e+000, -3.138528e+000, 1.424739e+000, -1.269326e+000, -1.561580e-001, 1.767060e-001, -1.175921e-003, 1.659123e+000, 3.746132e-001, -4.672972e+000, -4.049529e+000, -1.027600e+000, 1.072252e+000, 7.908165e-002, -2.243835e-001, 6.190595e-003, 1.988822e+000, 6.684758e-001, -2.256117e+000, -1.258356e+000, 2.198377e-001, -1.296239e+000, -3.200970e+000, 6.407291e-001, -1.527762e-002, 1.735209e+000, 1.170530e+000, -7.790059e-001, -1.269213e+000, 6.315194e-001, 2.368850e+000, -1.199163e+000, -1.504024e-001, 1.733299e-002, 2.544016e-001, 2.756763e-001, -1.046916e+000, -6.991719e-001, 3.620624e-001, 7.364236e-002, -5.012491e+000, 4.240417e-001, 3.580425e-002, 1.202329e+000, 6.255804e-001, // albedo 0, turbidity 8 -1.886851e+001, -4.491136e+000, -3.660440e+000, 3.704226e+000, -3.158478e-002, 1.229909e-001, 9.233613e-004, 1.745459e+000, 5.011929e-001, -1.986322e+001, -3.528401e+000, 1.401749e+000, -1.191377e+000, -7.474944e-002, -2.193835e-002, -5.138968e-003, 1.710181e+000, 5.473672e-001, 5.355660e-001, -5.459304e+000, -8.809226e-001, 5.959028e-001, -3.311339e-001, 3.876731e-001, 2.126070e-002, 1.929868e+000, 1.883429e-001, -3.136053e+000, -2.856938e-001, 1.048390e-001, -7.708877e-001, 2.106630e-001, -1.488471e-001, -5.172733e-002, 1.769302e+000, 1.526253e+000, 1.496752e-001, -9.170428e-001, 5.628226e-001, 1.733601e+000, -4.784033e+000, 3.570330e-001, 7.396580e-002, 3.954993e-001, 1.397727e-003, -1.839740e+000, -1.279260e+000, 3.173503e-001, 1.096266e+000, -4.168649e+000, 2.121881e-001, 2.150917e-002, 1.151497e+000, 7.233585e-001, // albedo 0, turbidity 9 -1.841090e+001, -4.803089e+000, -4.883823e+000, 4.962235e+000, -2.693216e-002, 1.089917e-001, -6.338015e-006, 1.725865e+000, 8.890717e-001, -1.947081e+001, -2.961260e+000, 1.963002e+000, -1.942423e+000, -5.550118e-002, 7.036456e-002, -5.990592e-004, 1.807097e+000, -8.871814e-003, 9.588307e-001, -6.379803e+000, -1.021090e+000, 9.560589e-001, -2.175500e-001, 8.613517e-002, 1.362268e-002, 1.953529e+000, 7.422482e-001, -3.609766e+000, -1.823498e-003, 2.516424e-002, -8.909855e-001, 2.207805e-001, 1.783064e-001, -4.293958e-002, 1.607901e+000, 1.131559e+000, 6.087707e-001, -6.744295e-001, 4.236310e-001, 1.505925e+000, -4.197126e+000, 2.046561e-001, 6.445824e-002, 7.793118e-001, 3.262213e-001, -2.148492e+000, -1.597890e+000, 3.166858e-001, 2.414329e+000, -4.201339e+000, 1.005902e-001, 4.687865e-002, 9.335376e-001, 5.289661e-001, // albedo 0, turbidity 10 -1.787767e+001, -4.873485e+000, -5.861224e+000, 5.866336e+000, -1.564202e-002, 6.967640e-002, 7.574926e-004, 1.768065e+000, 5.856596e-001, -1.932995e+001, -4.092647e+000, 2.679531e+000, -2.555671e+000, -4.181418e-002, 1.023654e-001, -5.964172e-003, 1.625691e+000, 4.036808e-001, 1.788482e+000, -5.652582e+000, -1.517519e+000, 1.251535e+000, -2.225912e-001, -1.084716e-001, 3.272584e-002, 2.139078e+000, 3.876645e-001, -3.363801e+000, -3.266475e-001, 1.313912e-001, -6.889075e-001, 4.356523e-001, 3.120297e-001, -8.700131e-002, 1.750122e+000, 1.223546e+000, 4.668756e-004, -9.612337e-001, 3.082344e-001, 1.298938e+000, -4.371395e+000, 8.845524e-002, 1.303481e-001, 5.843720e-001, 2.718863e-001, -1.759172e+000, -1.386072e+000, 2.349661e-001, 1.592185e+000, -3.063267e+000, 1.529736e-001, 3.429185e-002, 1.030294e+000, 6.917018e-001, // albedo 1, turbidity 1 -1.341051e+001, -3.742047e+000, -5.229556e+000, 5.307222e+000, -2.094796e-002, 1.499787e-001, -7.023116e-006, 1.732898e+000, 8.826861e-001, -1.426829e+001, -3.550660e+000, 5.731266e-002, 3.166575e-001, -5.821080e-002, 1.335860e-001, 2.003178e-004, 1.503788e+000, 9.750310e-001, -2.239143e+000, -4.290084e+000, -7.493158e-001, 2.865753e-001, -5.993923e-002, 1.327393e-001, -5.399344e-004, 1.731677e+000, 6.513329e-001, -1.336350e+000, -2.463606e-001, 3.963632e-001, -6.721398e-002, -1.816244e-001, 1.021503e-002, 8.081470e-004, 1.986453e+000, 1.415292e+000, -1.554584e+000, -1.810948e+000, 7.313475e-001, 1.703307e-003, 5.779436e-001, 6.184790e-001, -6.832621e-004, -2.739619e-002, 2.699443e-001, -8.456234e-001, -5.656772e-001, 5.531782e-001, -2.975361e-003, -4.555221e+000, 2.821035e-001, 4.007713e-004, 1.113850e+000, 6.636719e-001, // albedo 1, turbidity 2 -1.263311e+001, -4.099112e+000, -5.130792e+000, 5.526406e+000, -2.122841e-002, 1.202556e-001, -8.060670e-006, 1.209196e+000, 8.997967e-001, -1.361400e+001, -3.538236e+000, 1.570583e-001, 3.445259e-001, -5.306874e-002, 2.322893e-001, 1.572516e-005, 1.152750e+000, 9.026902e-001, -1.477014e+000, -3.664310e+000, -1.442116e-001, -4.293554e-002, -3.768326e-002, -1.388530e-001, -1.687893e-004, 1.592625e+000, 8.804841e-001, -2.050884e+000, -1.470536e+000, 3.327590e-001, 1.976143e-001, -1.930369e-001, 2.831960e-001, 6.940849e-004, 1.271203e+000, 9.790242e-001, -3.704793e-001, -5.829841e-001, 1.168589e+000, -1.387973e-001, 5.998426e-001, 3.825096e-001, -2.188637e-003, -2.273264e-001, 7.393514e-001, -9.877542e-001, -7.646946e-001, 8.859003e-001, 5.263145e-002, -4.849410e+000, 1.301905e-001, 5.464872e-003, 5.270984e-001, 5.001226e-001, // albedo 1, turbidity 3 -1.294452e+001, -3.858933e+000, -4.362969e+000, 4.657159e+000, -2.281956e-002, 1.371565e-001, 3.552610e-006, 1.354369e+000, 5.222053e-001, -1.425646e+001, -3.745266e+000, 6.901454e-001, -5.345642e-002, -5.238708e-002, 1.157055e-001, -1.961110e-005, 1.030408e+000, 4.036292e-001, -2.236186e+000, -3.560196e+000, -1.053059e-001, -3.002269e-001, -1.702750e-001, 3.290753e-002, -7.253274e-005, 1.846963e+000, 6.828000e-001, -1.991088e+000, -2.028027e+000, 2.747056e-001, 5.076456e-001, 2.056096e-001, 1.537040e-001, 1.010611e-003, 8.439763e-001, 1.286657e+000, -2.733597e-001, -1.938590e-001, 1.108079e+000, -1.668080e-001, -8.136300e-001, 3.962292e-001, -4.757393e-003, 1.536882e-001, 4.595467e-001, -9.782447e-001, -8.452104e-001, 9.149995e-001, 2.750126e-002, -4.996263e+000, 1.226836e-001, 1.533731e-002, 3.686265e-001, 5.004484e-001, // albedo 1, turbidity 4 -1.234416e+001, -3.818503e+000, -3.804408e+000, 4.093838e+000, -2.505623e-002, 1.149315e-001, -7.610563e-006, 1.361584e+000, 8.981571e-001, -1.349621e+001, -3.551853e+000, 1.469377e+000, -8.971164e-001, -5.623731e-002, 1.078524e-001, 1.491378e-003, 1.113040e+000, -4.279059e-001, -3.391950e+000, -3.791028e+000, -6.935352e-001, 2.998175e-001, -3.155309e-001, 1.196041e-001, -4.708048e-003, 2.001973e+000, 1.840166e+000, -1.915114e+000, -1.493080e+000, 4.567342e-001, -7.334296e-002, 6.767060e-001, -4.562689e-003, 1.016838e-002, 1.003272e+000, 5.102018e-001, -5.674128e-001, -5.568719e-001, 9.084369e-001, 6.684870e-001, -3.892720e+000, 5.312866e-001, -1.768715e-002, 3.252051e-001, 6.541029e-001, -1.343751e+000, -9.647458e-001, 7.945561e-001, 5.127485e-004, -5.009873e+000, 6.165389e-002, 2.642926e-002, 6.213595e-001, 5.327376e-001, // albedo 1, turbidity 5 -1.450562e+001, -4.021778e+000, -4.181517e+000, 4.509518e+000, -2.369519e-002, 6.955582e-002, 1.149882e-004, 1.329583e+000, 5.260857e-001, -1.297772e+001, -3.655039e+000, 2.030636e+000, -1.537436e+000, -4.915490e-002, 1.511047e-001, -9.053517e-004, 1.156980e+000, 4.831690e-001, -1.991837e+000, -3.919397e+000, -8.466357e-001, 5.319508e-001, -3.165811e-001, 1.056172e-001, 4.836036e-003, 1.843574e+000, 3.084513e-001, -2.052725e+000, -1.606839e+000, 5.876624e-001, -7.464148e-002, 7.525473e-001, 1.590947e-003, -1.261084e-002, 8.587516e-001, 1.404076e+000, -3.737447e-001, -4.061843e-001, 8.985804e-001, 5.700187e-001, -5.422882e+000, 4.334301e-001, 1.759754e-002, 2.613056e-001, 2.062463e-001, -1.002263e+000, -1.006484e+000, 9.629219e-001, 8.528366e-002, -4.220831e+000, 7.848806e-002, 1.254937e-002, 2.140208e-001, 6.187813e-001, // albedo 1, turbidity 6 -7.175451e+000, -3.313094e+000, -2.396914e+000, 2.657177e+000, -3.936959e-002, 1.123476e-001, 7.315860e-005, 1.431209e+000, 5.107145e-001, -8.058121e+000, -3.119458e+000, 1.729776e+000, -1.435370e+000, -1.414745e-001, 2.338787e-001, -5.865288e-004, 1.247225e+000, 5.037743e-001, -4.387785e+000, -3.851081e+000, -7.774273e-001, 1.405520e+000, 1.743075e-001, -4.108912e-001, 3.058571e-003, 1.519803e+000, 2.636805e-001, -1.807473e+000, -1.498491e+000, 3.237723e-001, -1.626737e+000, -3.741656e+000, 8.444519e-001, -8.297013e-003, 1.624861e+000, 1.753817e+000, -6.242455e-001, -1.063850e+000, 1.166897e+000, 2.283807e+000, -1.150947e+000, -3.242997e-001, 1.279340e-002, -5.448139e-001, -8.653106e-002, -8.143405e-001, -5.251732e-001, 7.822692e-001, -3.764280e-003, -5.011112e+000, 3.985065e-001, 3.652394e-003, 7.140115e-001, 7.004910e-001, // albedo 1, turbidity 7 -7.579673e+000, -3.495594e+000, -2.498830e+000, 2.771470e+000, -3.451351e-002, 8.186886e-002, 1.272079e-004, 1.390420e+000, 5.545117e-001, -8.524117e+000, -3.121778e+000, 1.680395e+000, -1.329455e+000, -1.395912e-001, 1.911589e-001, -1.027988e-003, 1.259267e+000, 3.356989e-001, -4.579718e+000, -4.086739e+000, -8.030175e-001, 1.103390e+000, 1.429699e-001, -2.211841e-001, 5.620349e-003, 1.693702e+000, 7.084432e-001, -1.946704e+000, -1.512415e+000, 3.559506e-001, -1.318829e+000, -3.063409e+000, 6.250046e-001, -1.490672e-002, 1.414520e+000, 1.317647e+000, -7.123367e-001, -1.133848e+000, 1.064800e+000, 2.217543e+000, -1.247373e+000, -2.105594e-001, 2.261048e-002, -3.648618e-001, 1.147223e-001, -7.979833e-001, -5.546030e-001, 7.765850e-001, -4.676928e-003, -5.014372e+000, 3.694816e-001, 2.373221e-003, 6.783145e-001, 7.862971e-001, // albedo 1, turbidity 8 -1.886599e+001, -4.523457e+000, -3.559445e+000, 3.748747e+000, -2.082711e-002, 1.120505e-001, 4.908827e-005, 1.430333e+000, 4.999603e-001, -1.985552e+001, -3.530040e+000, 1.578922e+000, -1.170838e+000, -6.347814e-002, 2.032158e-003, -7.291357e-004, 1.399338e+000, 5.515394e-001, 5.631541e-001, -5.483754e+000, -6.832337e-001, 6.170499e-001, -2.824393e-001, 3.546810e-001, 6.248420e-003, 1.638520e+000, 2.300717e-001, -3.083195e+000, -3.071409e-001, 2.822360e-001, -7.871125e-001, 2.420642e-001, -1.716096e-001, -1.936307e-002, 1.450902e+000, 1.590291e+000, 2.003824e-001, -8.374106e-001, 8.800366e-001, 1.702679e+000, -4.785357e+000, 3.194078e-001, 3.028099e-002, 6.649245e-002, -4.459174e-003, -1.738851e+000, -1.144728e+000, 6.950894e-001, 1.073870e+000, -4.176611e+000, 9.901497e-002, 2.719362e-002, 6.579628e-001, 6.542088e-001, // albedo 1, turbidity 9 -1.842858e+001, -4.464894e+000, -4.876181e+000, 4.999894e+000, -1.680473e-002, 9.284371e-002, 8.631599e-005, 1.551671e+000, 8.637202e-001, -1.946220e+001, -2.928492e+000, 1.932796e+000, -2.009963e+000, -2.067172e-002, 2.760643e-001, -1.316034e-003, 1.910005e+000, -2.057018e-002, 1.012726e+000, -6.397245e+000, -8.570688e-001, 9.466942e-001, -2.428074e-001, 4.505376e-002, 1.159119e-002, 1.686356e+000, 7.885028e-001, -3.502022e+000, -9.795202e-002, 3.286657e-001, -8.318684e-001, 1.254695e-001, 9.600123e-002, -3.501772e-002, 1.161309e+000, 1.205342e+000, 7.024550e-001, -6.903001e-001, 7.519618e-001, 1.501909e+000, -4.224528e+000, 1.253867e-001, 5.829515e-002, 2.671626e-001, 3.030079e-001, -2.056576e+000, -1.583471e+000, 7.947031e-001, 2.224097e+000, -4.127138e+000, 1.885249e-001, 1.729132e-005, 3.336881e-001, 5.332061e-001, // albedo 1, turbidity 10 -1.825745e+001, -5.122861e+000, -5.876715e+000, 5.970876e+000, -1.788919e-002, 1.063934e-001, 4.770037e-004, 1.612403e+000, 5.156506e-001, -1.981828e+001, -3.746331e+000, 2.729783e+000, -2.477317e+000, -2.797536e-002, -5.281985e-002, -3.739083e-003, 1.378246e+000, 5.904024e-001, 1.346751e+000, -6.486837e+000, -1.082622e+000, 1.125524e+000, -2.228944e-001, 3.975587e-001, 2.035973e-002, 1.884664e+000, 1.086023e-003, -3.996320e+000, -4.646476e-001, 3.008639e-002, -1.193861e+000, 4.443960e-001, -2.593178e-001, -5.378377e-002, 1.528777e+000, 1.734923e+000, 4.789259e-001, -8.952042e-001, 8.595191e-001, 2.353988e+000, -4.885398e+000, 4.438339e-001, 7.931163e-002, -8.144393e-002, 1.663921e-002, -1.772626e+000, -1.783205e+000, 7.322534e-001, 1.529827e+000, -2.789303e+000, -1.817210e-001, 2.737502e-002, 2.620216e-001, 6.227585e-001, }; static float datasetRad320[] = { // albedo 0, turbidity 1 9.282016e-004, 3.169257e-004, 5.255138e-003, -1.465200e-002, 7.187172e-002, 5.400860e-002, // albedo 0, turbidity 2 9.160628e-004, 2.599956e-004, 5.466998e-003, -1.503537e-002, 7.200167e-002, 5.387713e-002, // albedo 0, turbidity 3 9.148749e-004, 2.164768e-004, 5.576667e-003, -1.537254e-002, 7.215609e-002, 5.380753e-002, // albedo 0, turbidity 4 9.090685e-004, 1.467840e-004, 5.775870e-003, -1.598491e-002, 7.252530e-002, 5.329870e-002, // albedo 0, turbidity 5 8.902830e-004, 1.126529e-004, 5.945913e-003, -1.648173e-002, 7.220217e-002, 5.391054e-002, // albedo 0, turbidity 6 8.885423e-004, 1.142350e-004, 5.938903e-003, -1.668800e-002, 7.231405e-002, 5.331532e-002, // albedo 0, turbidity 7 8.674766e-004, 3.506619e-005, 6.176212e-003, -1.732036e-002, 7.223472e-002, 5.318228e-002, // albedo 0, turbidity 8 8.525095e-004, -1.752028e-005, 6.286417e-003, -1.779286e-002, 7.150222e-002, 5.334072e-002, // albedo 0, turbidity 9 8.232652e-004, -1.292152e-004, 6.645270e-003, -1.886566e-002, 7.052974e-002, 5.331726e-002, // albedo 0, turbidity 10 7.670001e-004, -1.885989e-004, 6.484739e-003, -1.852036e-002, 6.610758e-002, 5.484068e-002, // albedo 1, turbidity 1 1.105405e-003, 2.555979e-005, 7.984713e-003, -2.152422e-002, 8.452836e-002, 9.622688e-002, // albedo 1, turbidity 2 1.111427e-003, -6.046059e-005, 8.035207e-003, -2.134768e-002, 8.363698e-002, 9.641842e-002, // albedo 1, turbidity 3 1.103552e-003, -8.229160e-005, 8.170699e-003, -2.189940e-002, 8.404871e-002, 9.504912e-002, // albedo 1, turbidity 4 1.075129e-003, -1.473970e-004, 8.391094e-003, -2.255482e-002, 8.415497e-002, 9.338994e-002, // albedo 1, turbidity 5 1.036467e-003, -1.328992e-004, 8.348236e-003, -2.256138e-002, 8.304671e-002, 9.263679e-002, // albedo 1, turbidity 6 1.042383e-003, -2.016636e-004, 8.479624e-003, -2.296524e-002, 8.303746e-002, 9.082494e-002, // albedo 1, turbidity 7 1.014293e-003, -2.355927e-004, 8.551010e-003, -2.333261e-002, 8.258160e-002, 8.873588e-002, // albedo 1, turbidity 8 9.683336e-004, -2.120256e-004, 8.172046e-003, -2.223973e-002, 7.852279e-002, 8.864017e-002, // albedo 1, turbidity 9 9.139571e-004, -2.688667e-004, 8.068793e-003, -2.224390e-002, 7.590320e-002, 8.464876e-002, // albedo 1, turbidity 10 8.457855e-004, -3.459869e-004, 7.626953e-003, -2.067614e-002, 6.841363e-002, 8.244103e-002, }; static float dataset360[] = { // albedo 0, turbidity 1 -2.974290e+000, -1.670904e+000, -5.183199e+000, 5.377376e+000, -2.904124e-002, 2.486720e-001, 8.045624e-005, 1.889212e+000, 5.188203e-001, -2.638402e+000, -1.651876e+000, -1.229939e+000, 1.776358e+000, -6.372414e-002, 3.767834e-001, -6.475530e-004, 1.373589e+000, 4.349252e-001, -2.449142e+000, -1.541788e+000, 4.629358e-001, -1.149742e+000, -7.317185e-002, -2.422158e-001, 3.667113e-003, 3.146429e+000, 6.725657e-001, -8.559357e-001, -5.054959e-001, 4.334205e-001, 4.254155e-001, -2.920605e-001, 9.303230e-001, -1.212609e-002, 4.498482e-001, 2.117838e-001, -1.098145e+000, -5.123514e-001, 7.773196e-001, -1.325175e-001, 4.648396e-001, 1.386648e-001, 2.427679e-002, 1.199386e+000, 7.988611e-001, -1.124849e+000, -5.693597e-001, 7.315125e-001, 2.986435e-002, -4.536788e+000, 6.650081e-001, -9.004215e-007, 1.006380e+000, 4.999682e-001, // albedo 0, turbidity 2 -2.709497e+000, -1.635812e+000, -4.594177e+000, 4.809336e+000, -3.672907e-002, 2.383111e-001, 3.241989e-005, 1.885505e+000, 6.619619e-001, -2.590279e+000, -1.525236e+000, -6.846073e-001, 1.216080e+000, -8.022814e-002, 3.040074e-001, -4.984576e-004, 1.521429e+000, 1.746040e-001, -2.988403e+000, -1.938687e+000, 4.954649e-002, -8.992325e-001, -7.157111e-002, -4.370068e-002, 4.336645e-003, 2.849496e+000, 8.892788e-001, -2.932084e-001, -1.323910e-001, 5.535910e-001, 7.456284e-001, -2.713400e-001, 6.989175e-001, -1.513162e-002, 6.926848e-001, 5.719944e-001, -1.379400e+000, -6.876864e-001, 7.224534e-001, -6.172704e-001, 1.217500e-001, 3.074795e-001, 2.905167e-002, 1.123563e+000, 6.837510e-001, -1.042446e+000, -5.201193e-001, 7.107656e-001, 4.182566e-001, -4.956238e+000, 5.315425e-001, 6.232999e-003, 1.059015e+000, 5.116427e-001, // albedo 0, turbidity 3 -2.686687e+000, -1.615137e+000, -3.811956e+000, 4.018597e+000, -3.953418e-002, 2.171778e-001, -7.374887e-006, 1.875745e+000, 8.996180e-001, -3.049670e+000, -1.775802e+000, 2.577719e-002, 5.331200e-001, -9.424429e-002, 3.852753e-001, -8.678326e-005, 1.347053e+000, -1.078327e-001, -2.414334e+000, -1.637863e+000, -3.948523e-001, -4.867989e-001, -1.545516e-001, -2.045592e-001, 2.308206e-003, 3.257409e+000, 1.029606e+000, -6.821703e-001, -3.665215e-001, 7.496076e-001, 5.391760e-001, -2.903450e-001, 8.498544e-001, -1.388990e-002, 2.126622e-001, 6.857005e-001, -1.227285e+000, -5.958479e-001, 5.828611e-001, -4.050489e-001, -2.935835e-001, 1.410603e-001, 4.352812e-002, 1.406076e+000, 4.955059e-001, -1.080553e+000, -5.308084e-001, 6.980027e-001, 2.193524e-001, -5.007206e+000, 5.895807e-001, 1.122391e-002, 1.052433e+000, 6.643198e-001, // albedo 0, turbidity 4 -2.983088e+000, -1.746025e+000, -4.564198e+000, 4.776145e+000, -3.208607e-002, 2.008358e-001, -6.578048e-006, 1.829880e+000, 9.001069e-001, -2.858023e+000, -1.624623e+000, 1.859497e+000, -1.348577e+000, -7.427284e-002, 2.943068e-001, -1.961205e-004, 1.502334e+000, -3.183648e-001, -2.858102e+000, -2.072804e+000, -1.205584e+000, 5.674135e-001, -3.934144e-001, -3.736288e-002, 4.780332e-003, 2.831298e+000, 1.553942e+000, -3.305766e-001, -8.277591e-003, 8.561917e-001, -2.239172e-001, 5.896697e-001, 6.229823e-001, -2.242577e-002, 7.216263e-001, 4.295956e-001, -1.322728e+000, -7.101315e-001, 5.645563e-001, 9.897384e-001, -6.756374e+000, 2.491515e-001, 5.308124e-002, 1.166258e+000, 5.472501e-001, -1.117086e+000, -5.760006e-001, 6.388217e-001, 1.659290e-001, -4.687099e+000, 4.544540e-001, 2.672063e-002, 1.067777e+000, 6.419825e-001, // albedo 0, turbidity 5 -2.943340e+000, -1.779161e+000, -3.715839e+000, 3.949049e+000, -4.499824e-002, 2.234466e-001, -8.091518e-006, 1.825217e+000, 9.000118e-001, -3.717358e+000, -1.850324e+000, 2.277659e+000, -2.027790e+000, -1.240730e-001, 3.029522e-001, -2.176255e-004, 1.585933e+000, -2.794001e-001, -2.439542e+000, -2.277701e+000, -1.702329e+000, 2.025885e+000, -1.142291e-001, -2.011641e-001, 5.563891e-003, 2.424957e+000, 1.399542e+000, -1.562453e-001, 5.099893e-001, 1.026847e+000, -2.516874e+000, -2.212969e+000, 9.252660e-001, -2.696795e-002, 1.443711e+000, 7.450372e-001, -1.579698e+000, -1.110703e+000, 4.743061e-001, 4.160187e+000, -4.597085e+000, -2.112156e-001, 6.791770e-002, 6.131169e-001, 2.291635e-001, -9.959610e-001, -4.119588e-001, 5.707529e-001, -3.505536e-003, -4.253949e+000, 7.498003e-001, 8.246945e-003, 1.397857e+000, 8.021253e-001, // albedo 0, turbidity 6 -2.304734e+000, -1.483605e+000, -1.531059e+000, 1.707306e+000, -1.150367e-001, 2.153063e-001, -3.351533e-006, 2.021261e+000, 5.742842e-001, -3.130477e+000, -1.966839e+000, 6.058600e-001, -9.209976e-001, -1.932901e-001, 3.242645e-001, 3.361262e-002, 1.529938e+000, 2.851152e-001, -1.110129e+000, -1.306323e+000, -3.235833e-001, 2.998748e+000, -1.535927e-002, -4.001906e-001, -9.430492e-002, 2.211086e+000, 8.632200e-001, -1.174540e+000, 7.550161e-002, -1.849588e-001, -6.281432e+000, -6.186665e+000, 1.173048e+000, 1.481656e-001, 2.668578e+000, 6.145923e-001, -1.104583e+000, -8.430389e-001, 8.668416e-001, 9.153752e+000, -7.289540e-001, -4.346537e-001, -9.065784e-002, 2.866983e-001, 6.920973e-001, -1.105893e+000, -4.500399e-001, 4.286451e-001, 1.207864e+000, -5.018291e+000, 6.988292e-001, 3.891745e-002, 1.602324e+000, 6.269169e-001, // albedo 0, turbidity 7 -3.709341e+000, -2.038242e+000, -3.127214e+000, 3.287030e+000, -4.565671e-002, 2.427627e-001, -7.503980e-006, 1.817881e+000, 9.000389e-001, -3.393374e+000, -1.710497e+000, 1.661275e+000, -1.388896e+000, -1.012293e-001, 1.676172e-001, -5.719846e-004, 1.694199e+000, -3.140071e-001, -2.812820e+000, -2.678401e+000, -1.170428e+000, 1.560988e+000, -4.488218e-001, 1.088693e-001, 1.391966e-002, 2.144426e+000, 1.525731e+000, 2.547360e-001, 8.840167e-001, 5.469168e-001, -2.615530e+000, -1.048663e+000, 4.823171e-001, -5.958515e-002, 1.842479e+000, 5.322138e-001, -1.612173e+000, -1.055541e+000, 4.733463e-001, 5.083504e+000, -5.558403e+000, 8.029584e-002, 1.294180e-001, 7.807964e-001, 3.949822e-001, -1.098367e+000, -5.550631e-001, 4.221569e-001, -1.661587e-003, -4.970027e+000, 3.479325e-001, 4.503648e-002, 1.369224e+000, 6.753984e-001, // albedo 0, turbidity 8 -4.292777e+000, -2.231300e+000, -4.359252e+000, 4.562131e+000, -3.759725e-002, 2.170783e-001, -6.945269e-006, 1.791630e+000, 8.996451e-001, -4.016595e+000, -1.761175e+000, 2.616213e+000, -2.658657e+000, -8.209207e-002, 2.736152e-001, -6.864170e-004, 1.820262e+000, -2.712707e-001, -2.942646e+000, -3.350329e+000, -1.645817e+000, 2.957424e+000, -1.073783e-001, -1.920050e-001, 1.665992e-002, 1.723144e+000, 1.394962e+000, 9.793627e-001, 1.743715e+000, 5.396545e-001, -4.618273e+000, -2.186669e+000, 1.012973e+000, -7.213786e-002, 2.388103e+000, 6.712519e-001, -2.085434e+000, -1.445755e+000, 3.384806e-001, 7.702938e+000, -3.897179e+000, -5.947697e-001, 1.614194e-001, 7.854754e-001, 3.291034e-001, -9.660466e-001, -5.247410e-001, 4.199048e-001, -3.304707e-003, -5.014144e+000, 6.733599e-001, 2.345161e-002, 1.225739e+000, 7.256834e-001, // albedo 0, turbidity 9 -3.950771e+000, -2.192673e+000, -7.263653e+000, 7.343312e+000, -1.840332e-002, 1.893809e-001, -3.583629e-006, 1.901172e+000, 5.902387e-001, -6.384690e+000, -2.515788e+000, 3.874778e+000, -3.776079e+000, -3.484710e-002, 3.311078e-001, 8.248395e-003, 1.612712e+000, 3.123684e-001, -6.207616e-001, -2.681061e+000, -2.005212e+000, 2.445498e+000, -1.935675e-001, -1.988856e-001, -1.553754e-002, 2.210740e+000, 6.507040e-001, -1.241493e+000, 5.908170e-001, 3.899777e-001, -2.344038e+000, -1.820327e-001, 7.889592e-001, -1.468064e-002, 1.586758e+000, 1.007885e+000, -4.395130e-001, -3.700611e-001, 2.452754e-001, 3.602006e+000, -4.692896e+000, -8.620746e-002, 1.418548e-001, 1.521301e+000, 3.989756e-001, -1.794977e+000, -1.190586e+000, 3.928989e-001, 1.946953e+000, -1.874118e+000, -3.292602e-002, 2.983309e-002, 6.737092e-001, 7.322706e-001, // albedo 0, turbidity 10 -8.896186e+000, -3.278330e+000, -7.998349e+000, 8.023312e+000, -1.357555e-002, 1.947910e-001, -5.390226e-006, 1.798414e+000, 7.881395e-001, -8.040403e+000, -2.528514e+000, 3.774303e+000, -3.590457e+000, -3.551313e-002, 3.650761e-001, -4.401382e-004, 1.701545e+000, -6.992899e-003, -4.150010e-001, -3.539507e+000, -1.527733e+000, 1.415242e+000, -1.831476e-001, -3.009746e-001, 1.211955e-002, 2.365976e+000, 9.928240e-001, -2.090923e+000, 1.673638e-001, -2.183495e-001, -8.374584e-001, 2.774184e-002, 7.912769e-001, -6.650609e-002, 1.154446e+000, 7.863979e-001, 5.115239e-001, 2.415831e-001, 4.022318e-001, 2.292950e+000, -4.061496e+000, 7.453182e-002, 1.902451e-001, 1.587339e+000, 5.207620e-001, -2.334879e+000, -1.642495e+000, 2.384458e-001, 3.068363e+000, -1.699588e+000, -3.936924e-001, 3.028660e-002, 4.715374e-001, 7.091893e-001, // albedo 1, turbidity 1 -2.375941e+000, -1.508643e+000, -5.070151e+000, 5.509378e+000, -2.915769e-002, 2.122471e-001, 8.584007e-005, 1.517285e+000, 5.163253e-001, -2.605398e+000, -1.589160e+000, -1.137560e+000, 1.827729e+000, -4.939637e-002, 3.243952e-001, -6.464612e-004, 1.008816e+000, 4.568463e-001, -2.176260e+000, -1.601522e+000, 7.060324e-001, -1.060717e+000, -5.144614e-002, -1.938031e-001, 3.449257e-003, 2.641594e+000, 5.976852e-001, -7.365744e-001, -3.720296e-001, 7.315328e-001, 3.156067e-001, -2.739385e-001, 8.252942e-001, -1.055013e-002, 7.327610e-002, 3.218251e-001, -1.017537e+000, -4.631811e-001, 1.093174e+000, -7.215941e-002, 5.408457e-001, -1.848322e-002, 1.942990e-002, 6.882763e-001, 7.268524e-001, -1.025215e+000, -3.712574e-001, 9.661278e-001, 7.791398e-003, -4.508617e+000, 4.371074e-001, -1.241898e-006, 1.152655e+000, 5.008240e-001, // albedo 1, turbidity 2 -2.621793e+000, -1.611544e+000, -4.494730e+000, 4.902741e+000, -2.935751e-002, 1.930048e-001, 1.821579e-005, 1.522018e+000, 6.563013e-001, -2.473330e+000, -1.495083e+000, -5.536781e-001, 1.305457e+000, -7.261347e-002, 2.967738e-001, -2.858526e-004, 1.132650e+000, 1.737068e-001, -2.843519e+000, -1.913751e+000, 2.006296e-001, -8.580922e-001, -5.273753e-002, -7.800250e-002, 2.395781e-003, 2.505017e+000, 9.023934e-001, -1.805184e-001, -3.670063e-002, 7.583717e-001, 7.594739e-001, -2.092951e-001, 6.278666e-001, -8.086828e-003, 4.136002e-001, 6.026937e-001, -1.274753e+000, -5.831501e-001, 9.711756e-001, -6.209175e-001, 1.488633e-001, 2.117108e-001, 1.531499e-002, 9.306008e-001, 7.201852e-001, -9.224434e-001, -3.344822e-001, 9.964647e-001, 3.991735e-001, -4.951439e+000, 4.332347e-001, -1.082832e-005, 9.570977e-001, 5.221054e-001, // albedo 1, turbidity 3 -2.648100e+000, -1.587720e+000, -3.738681e+000, 4.084015e+000, -3.301163e-002, 1.736140e-001, -5.598265e-006, 1.628176e+000, 8.967917e-001, -3.004556e+000, -1.702983e+000, 1.060112e-001, 5.816666e-001, -8.140777e-002, 3.584557e-001, -7.793874e-005, 1.090228e+000, -1.079451e-001, -2.337937e+000, -1.584523e+000, -2.912486e-001, -4.467895e-001, -9.195281e-002, -2.355753e-001, 1.887118e-003, 3.053238e+000, 1.043382e+000, -5.985994e-001, -2.846782e-001, 8.903642e-001, 5.578845e-001, -2.510042e-001, 8.033778e-001, -9.920460e-003, 7.388584e-002, 7.097127e-001, -1.155357e+000, -4.638306e-001, 8.041892e-001, -4.051351e-001, -2.819435e-001, 8.505708e-002, 2.749222e-002, 1.334820e+000, 5.216620e-001, -1.010658e+000, -3.816787e-001, 9.644918e-001, 2.144477e-001, -5.005667e+000, 5.475125e-001, 3.758162e-005, 1.033427e+000, 6.866266e-001, // albedo 1, turbidity 4 -2.686681e+000, -1.694114e+000, -4.346908e+000, 4.745876e+000, -2.879846e-002, 2.237339e-001, -6.438656e-006, 1.456353e+000, 9.000340e-001, -2.684912e+000, -1.616888e+000, 2.447798e+000, -1.626883e+000, -7.346183e-002, 2.641722e-001, -1.001518e-004, 1.045501e+000, -2.314856e-001, -2.587652e+000, -1.999748e+000, -1.325810e+000, 7.561102e-001, -4.182131e-001, -4.285017e-002, 2.719759e-003, 2.420598e+000, 1.281981e+000, -2.679506e-001, 5.139740e-002, 1.276587e+000, -2.286956e-001, 7.388924e-001, 5.606395e-001, -1.472508e-002, 5.105614e-001, 7.670396e-001, -1.267160e+000, -7.441021e-001, 9.154665e-001, 8.190436e-001, -6.805266e+000, 1.013064e-001, 4.140297e-002, 3.378301e-001, 3.128860e-001, -9.570978e-001, -3.478847e-001, 9.709923e-001, -3.444499e-003, -4.677921e+000, 3.551546e-001, 6.241534e-003, 1.052060e+000, 7.543152e-001, // albedo 1, turbidity 5 -3.093830e+000, -1.859478e+000, -4.003711e+000, 4.391665e+000, -3.051581e-002, 2.180265e-001, -7.401285e-006, 1.448366e+000, 9.000549e-001, -3.121106e+000, -1.664385e+000, 2.868256e+000, -2.280292e+000, -8.456847e-002, 2.227469e-001, -1.681252e-004, 1.176332e+000, -2.605895e-001, -2.166025e+000, -2.172663e+000, -1.705862e+000, 1.960864e+000, -2.185020e-001, 1.891067e-002, 4.423413e-003, 2.071931e+000, 1.297661e+000, -5.263078e-001, 2.296403e-001, 1.342025e+000, -2.034590e+000, -1.024013e+000, 4.873264e-001, -1.982506e-002, 9.818474e-001, 1.040041e+000, -1.138361e+000, -8.186096e-001, 8.845700e-001, 3.291911e+000, -5.915866e+000, 1.125846e-001, 4.477952e-002, 9.195132e-002, -1.138939e-002, -1.013651e+000, -3.811416e-001, 9.420266e-001, -3.599378e-003, -4.895655e+000, 2.864445e-001, 1.940262e-002, 1.026648e+000, 7.421204e-001, // albedo 1, turbidity 6 -2.379373e+000, -1.540348e+000, -1.318467e+000, 1.724703e+000, -1.017147e-001, 1.811106e-001, -3.047951e-006, 1.598808e+000, 5.796580e-001, -3.200327e+000, -2.016985e+000, 9.935187e-001, -9.970906e-001, -2.159523e-001, 3.183812e-001, 1.575987e-002, 1.180131e+000, 2.839510e-001, -1.107956e+000, -1.330969e+000, -1.627216e-001, 2.985435e+000, -2.198633e-002, -4.401148e-001, -5.433064e-002, 1.701087e+000, 8.289746e-001, -9.423359e-001, 4.619106e-002, 3.116348e-002, -6.353122e+000, -6.192769e+000, 1.175886e+000, 1.020452e-001, 2.180417e+000, 7.076018e-001, -1.037343e+000, -5.711080e-001, 1.282899e+000, 8.808032e+000, -8.741903e-001, -6.097972e-001, -5.996612e-002, 1.533313e-001, 5.842877e-001, -1.002208e+000, -3.271512e-001, 7.288675e-001, 7.950560e-001, -5.029931e+000, 4.493639e-001, 2.389923e-002, 1.568465e+000, 5.653910e-001, // albedo 1, turbidity 7 -3.584221e+000, -2.140498e+000, -5.324613e+000, 5.753381e+000, -2.662581e-002, 2.099272e-001, -6.879519e-006, 1.362229e+000, 9.000467e-001, -3.579609e+000, -1.804420e+000, 3.448490e+000, -2.929179e+000, -6.009529e-002, 2.821561e-001, -6.203809e-004, 1.312035e+000, -3.013934e-001, -2.053811e+000, -2.420850e+000, -1.795999e+000, 1.835004e+000, -3.451800e-001, -1.042135e-001, 1.511574e-002, 1.751304e+000, 1.491704e+000, -2.602659e-001, 5.963320e-001, 1.059632e+000, -1.214076e+000, 6.424455e-001, 6.890202e-001, -6.544341e-002, 1.457883e+000, 5.321707e-001, -1.266632e+000, -8.504227e-001, 8.680693e-001, 1.899473e+000, -8.680238e+000, -1.798563e-001, 1.477665e-001, 2.430031e-001, 4.229871e-001, -1.021321e+000, -5.129049e-001, 9.006232e-001, 1.534018e+000, -3.672948e+000, 2.301115e-001, 5.151145e-003, 7.460819e-001, 5.418252e-001, // albedo 1, turbidity 8 -4.095186e+000, -2.274183e+000, -4.115160e+000, 4.514741e+000, -3.131440e-002, 1.475658e-001, -5.329133e-006, 1.411833e+000, 8.893477e-001, -3.691554e+000, -1.654418e+000, 3.158573e+000, -2.961366e+000, -7.834161e-002, 3.035141e-001, -4.241191e-004, 1.485200e+000, -1.689443e-001, -2.697067e+000, -3.473351e+000, -1.707297e+000, 3.138823e+000, -8.323430e-002, -1.605972e-001, 1.025052e-002, 1.132282e+000, 1.093318e+000, 7.049827e-001, 1.769870e+000, 8.659868e-001, -4.445404e+000, -2.256134e+000, 7.768538e-001, -4.741793e-002, 2.212406e+000, 1.109562e+000, -1.771411e+000, -1.358270e+000, 7.604506e-001, 7.191590e+000, -4.358366e+000, -3.375251e-001, 1.136852e-001, 1.844576e-001, -1.208189e-003, -9.623648e-001, -5.518470e-001, 9.623684e-001, -5.697517e-003, -5.015884e+000, 2.811964e-001, 2.100168e-002, 4.434131e-001, 7.212648e-001, // albedo 1, turbidity 9 -5.131552e+000, -2.558716e+000, -8.066753e+000, 8.403192e+000, -1.450692e-002, 1.494495e-001, -2.898774e-006, 1.427512e+000, 5.020826e-001, -6.192910e+000, -2.261479e+000, 5.059205e+000, -4.892079e+000, -2.703716e-002, 3.381259e-001, 2.231257e-002, 1.490697e+000, 5.441761e-001, -6.741018e-001, -3.356237e+000, -2.207329e+000, 3.300094e+000, -1.801120e-001, -2.560242e-001, -6.216731e-002, 1.180699e+000, 2.241782e-001, -8.312435e-001, 1.325391e+000, 5.324159e-001, -2.912438e+000, -8.384977e-002, 7.600872e-001, 7.749519e-002, 2.129188e+000, 1.328287e+000, -7.455272e-001, -8.504579e-001, 9.021474e-001, 3.426594e+000, -4.607412e+000, -1.706127e-001, 4.792024e-002, 2.354077e-001, 2.718195e-001, -1.448374e+000, -9.739004e-001, 8.801628e-001, 1.705262e+000, -2.420298e+000, -1.077392e-002, 2.691713e-002, 1.854876e-001, 7.097466e-001, // albedo 1, turbidity 10 -8.672396e+000, -3.339107e+000, -7.666257e+000, 7.916291e+000, -1.396976e-002, 1.676538e-001, -5.816416e-006, 1.448247e+000, 8.178892e-001, -7.852799e+000, -2.606120e+000, 4.231840e+000, -3.774406e+000, -3.540722e-002, 2.178494e-001, 6.198617e-005, 1.295236e+000, 1.130678e-001, -1.374103e-001, -3.570476e+000, -1.588768e+000, 1.538806e+000, -1.923629e-001, -1.793545e-002, 3.373950e-003, 2.008581e+000, 6.041668e-001, -2.211224e+000, 1.190704e-001, 6.700025e-002, -8.972445e-001, 2.133056e-001, 4.471730e-001, -3.148150e-002, 9.759721e-001, 1.166537e+000, 5.932825e-001, 2.482606e-001, 9.239617e-001, 2.382787e+000, -4.611846e+000, 1.608983e-001, 1.385590e-001, 7.641781e-001, 3.076032e-001, -2.098394e+000, -1.561705e+000, 7.602298e-001, 1.783879e+000, -1.486238e+000, -4.025919e-001, 2.965074e-002, -8.717180e-002, 7.279518e-001, }; static float datasetRad360[] = { // albedo 0, turbidity 1 2.494129e-003, 3.556297e-003, 2.965923e-004, 2.713084e-003, 1.335823e-001, 8.293879e-002, // albedo 0, turbidity 2 2.473622e-003, 3.518055e-003, 4.432438e-004, 1.754027e-003, 1.352516e-001, 8.253805e-002, // albedo 0, turbidity 3 2.485307e-003, 3.507686e-003, 4.235269e-004, 1.120748e-003, 1.360769e-001, 8.328522e-002, // albedo 0, turbidity 4 2.421491e-003, 3.278595e-003, 1.395344e-003, -1.953245e-003, 1.392978e-001, 8.376885e-002, // albedo 0, turbidity 5 2.403587e-003, 3.114517e-003, 2.224702e-003, -5.305220e-003, 1.435766e-001, 8.315234e-002, // albedo 0, turbidity 6 2.351950e-003, 2.915308e-003, 3.179213e-003, -8.297787e-003, 1.471589e-001, 8.200387e-002, // albedo 0, turbidity 7 2.347797e-003, 2.761449e-003, 3.671854e-003, -1.012039e-002, 1.480091e-001, 8.399335e-002, // albedo 0, turbidity 8 2.296250e-003, 2.420416e-003, 5.106803e-003, -1.515460e-002, 1.526421e-001, 8.454641e-002, // albedo 0, turbidity 9 2.193368e-003, 1.826966e-003, 7.606333e-003, -2.312584e-002, 1.588488e-001, 8.547295e-002, // albedo 0, turbidity 10 2.037533e-003, 9.415569e-004, 1.104382e-002, -3.348390e-002, 1.637893e-001, 8.792408e-002, // albedo 1, turbidity 1 3.061048e-003, 2.126839e-003, 1.132767e-002, -2.788848e-002, 1.948610e-001, 1.618476e-001, // albedo 1, turbidity 2 3.047180e-003, 2.153513e-003, 1.116935e-002, -2.810228e-002, 1.949994e-001, 1.614103e-001, // albedo 1, turbidity 3 3.038920e-003, 2.051613e-003, 1.130934e-002, -2.861029e-002, 1.941964e-001, 1.617911e-001, // albedo 1, turbidity 4 2.963024e-003, 1.869150e-003, 1.189063e-002, -3.088695e-002, 1.962576e-001, 1.593205e-001, // albedo 1, turbidity 5 2.918936e-003, 1.726267e-003, 1.250792e-002, -3.337994e-002, 1.973927e-001, 1.577752e-001, // albedo 1, turbidity 6 2.855489e-003, 1.647214e-003, 1.256484e-002, -3.387525e-002, 1.965371e-001, 1.571482e-001, // albedo 1, turbidity 7 2.825443e-003, 1.406555e-003, 1.336433e-002, -3.675617e-002, 1.982073e-001, 1.535780e-001, // albedo 1, turbidity 8 2.678428e-003, 1.109106e-003, 1.431453e-002, -4.011878e-002, 1.979278e-001, 1.510186e-001, // albedo 1, turbidity 9 2.555750e-003, 6.244779e-004, 1.562522e-002, -4.466841e-002, 1.968517e-001, 1.462399e-001, // albedo 1, turbidity 10 2.323920e-003, 1.300657e-004, 1.663828e-002, -4.826021e-002, 1.889056e-001, 1.427310e-001, }; static float dataset400[] = { // albedo 0, turbidity 1 -1.869600e+000, -9.575785e-001, -6.993871e+000, 7.306207e+000, -3.240320e-002, 3.834949e-001, 4.369976e-005, 2.254773e+000, 5.025988e-001, -1.746138e+000, -1.001117e+000, -1.758295e+000, 2.492931e+000, -6.202861e-002, 4.442043e-001, -3.779550e-004, 1.411622e+000, 4.890101e-001, -1.536453e+000, -5.330479e-001, 1.126830e+000, -2.452367e+000, -6.694842e-002, -2.983825e-002, 2.320196e-003, 5.488905e+000, 5.403856e-001, -1.069780e+000, -5.815078e-001, 8.612956e-001, 1.301347e+000, -4.089489e-001, 1.269432e+000, -9.018004e-003, -2.283572e+000, 3.760374e-001, -1.060384e+000, -2.207518e-001, 6.362691e-001, -5.757237e-001, 4.275177e-001, 8.443714e-002, 2.082596e-002, 3.125040e+000, 7.891611e-001, -1.077246e+000, -2.993040e-001, 8.167430e-001, 2.203982e-001, -3.984213e+000, 1.123699e+000, 1.313138e-002, 1.750491e+000, 4.999653e-001, // albedo 0, turbidity 2 -1.752499e+000, -9.053927e-001, -1.080943e+001, 1.110516e+001, -2.092090e-002, 3.348109e-001, -8.432141e-006, 2.326824e+000, 9.000500e-001, -1.888565e+000, -1.067725e+000, 1.491851e+000, -7.934014e-001, -4.853718e-002, 5.346693e-001, 9.170370e-005, 1.397595e+000, -3.635730e-001, -1.471013e+000, -5.497976e-001, -4.310423e-001, -8.787275e-001, -9.206447e-002, -1.490862e-001, -4.078054e-005, 5.442983e+000, 1.757010e+000, -1.061905e+000, -5.429222e-001, 1.412232e+000, 8.460977e-001, -2.973654e-001, 1.357299e+000, -5.347332e-003, -2.444304e+000, -3.363016e-002, -1.071200e+000, -2.263246e-001, 3.639469e-001, -6.109244e-001, -2.484665e-001, -7.097027e-002, 4.735641e-002, 3.445733e+000, 8.486491e-001, -1.081645e+000, -3.128264e-001, 8.436471e-001, 3.884148e-001, -5.004662e+000, 1.137000e+000, 1.500838e-002, 1.585647e+000, 5.832608e-001, // albedo 0, turbidity 3 -1.774187e+000, -9.327599e-001, -9.130103e+000, 9.413272e+000, -2.448089e-002, 3.487996e-001, -3.033497e-006, 2.291071e+000, 6.408360e-001, -1.849342e+000, -1.038735e+000, 2.863013e+000, -2.260302e+000, -5.040252e-002, 4.583723e-001, 1.008690e-002, 1.502617e+000, 7.223351e-002, -1.624679e+000, -7.257060e-001, -1.493033e+000, 5.658415e-001, -2.079847e-001, -4.651180e-002, -3.701743e-002, 4.858534e+000, 1.342775e+000, -8.692395e-001, -3.025565e-001, 1.630221e+000, -4.624355e-002, 8.408669e-002, 1.091981e+000, 6.506253e-002, -1.403006e+000, 2.076066e-001, -1.169258e+000, -3.711802e-001, 3.440155e-001, -1.044556e-001, -3.304858e+000, 1.185883e-001, 1.489352e-002, 2.642598e+000, 8.151882e-001, -1.058391e+000, -2.657785e-001, 6.984363e-001, 9.737578e-002, -1.903943e+000, 8.963329e-001, 6.480860e-002, 2.034024e+000, 5.870424e-001, // albedo 0, turbidity 4 -1.898858e+000, -1.031814e+000, -9.726056e+000, 1.000989e+001, -2.125268e-002, 3.569897e-001, -2.706653e-006, 2.147646e+000, 5.982401e-001, -2.136007e+000, -1.206456e+000, 3.801172e+000, -3.254852e+000, -4.516490e-002, 4.001123e-001, 2.151890e-002, 1.481457e+000, 1.444904e-001, -1.355343e+000, -6.736369e-001, -2.052620e+000, 1.298239e+000, -1.986869e-001, 6.321488e-002, -6.792635e-002, 4.482593e+000, 1.322565e+000, -9.063816e-001, -1.873797e-001, 1.559544e+000, -2.631298e-001, 5.988684e-002, 9.375378e-001, 9.681349e-002, -6.480890e-001, 2.362949e-001, -1.170470e+000, -3.968082e-001, 2.266604e-001, -2.018118e-001, -3.768512e+000, 9.706445e-002, 6.046660e-002, 2.723200e+000, 7.968878e-001, -1.085813e+000, -3.519543e-001, 7.537557e-001, 3.003522e-001, -1.811803e+000, 7.945754e-001, 5.293207e-002, 1.335214e+000, 6.385980e-001, // albedo 0, turbidity 5 -1.743240e+000, -9.391727e-001, -8.905876e+000, 9.139326e+000, -2.333803e-002, 3.093783e-001, -2.051734e-006, 2.320564e+000, 5.474845e-001, -2.624196e+000, -1.516703e+000, 5.053093e+000, -4.599198e+000, -4.248730e-002, 4.820250e-001, 1.829762e-002, 1.216991e+000, 2.739806e-001, -1.040612e+000, -6.103044e-001, -3.190021e+000, 3.216574e+000, -3.285978e-001, -1.982489e-001, -5.367025e-002, 3.984414e+000, 1.158312e+000, -9.537244e-001, -6.895800e-003, 1.788307e+000, -2.659655e+000, 6.473584e-001, 1.333544e+000, 5.529579e-002, 8.049825e-001, 4.930209e-001, -1.163791e+000, -5.095388e-001, 1.215079e-001, 3.427998e+000, -9.243257e+000, -5.059496e-001, 1.412681e-001, 1.829389e+000, 5.544610e-001, -1.118058e+000, -3.706501e-001, 6.885180e-001, -1.596776e-003, -3.279613e+000, 1.068229e+000, 3.010797e-002, 1.479756e+000, 7.483765e-001, // albedo 0, turbidity 6 -1.811701e+000, -1.002650e+000, -9.194183e+000, 9.469966e+000, -2.224886e-002, 3.237441e-001, -2.632967e-006, 2.168879e+000, 5.952956e-001, -2.746180e+000, -1.592055e+000, 4.225172e+000, -3.929912e+000, -3.866297e-002, 3.982440e-001, 3.812089e-002, 1.390284e+000, 1.922369e-001, -9.558770e-001, -6.401790e-001, -2.117905e+000, 2.293799e+000, -2.226591e-001, 6.151477e-002, -1.223358e-001, 3.475975e+000, 1.124575e+000, -9.065351e-001, 1.443765e-001, 7.871576e-001, -1.631026e+000, 1.537369e-001, 8.353048e-001, 1.849704e-001, 1.650615e+000, 4.473559e-001, -1.180081e+000, -5.441674e-001, 3.963103e-001, 1.375519e+000, -4.882926e+000, -9.391794e-004, 6.455569e-002, 1.774670e+000, 6.989373e-001, -1.128755e+000, -3.892532e-001, 5.327884e-001, 1.825253e+000, -2.335719e+000, 5.863162e-001, 5.535626e-002, 1.452293e+000, 6.920090e-001, // albedo 0, turbidity 7 -2.042064e+000, -1.144943e+000, -5.152625e+000, 5.384535e+000, -3.519943e-002, 3.025845e-001, -2.994849e-006, 2.113418e+000, 6.000255e-001, -2.700541e+000, -1.485611e+000, 2.159154e+000, -2.188608e+000, -5.879735e-002, 3.921779e-001, 5.020849e-002, 1.869923e+000, 2.118398e-001, -1.187417e+000, -1.102630e+000, -9.404690e-001, 2.427532e+000, -2.948903e-001, -3.437257e-002, -1.636446e-001, 1.894926e+000, 1.001327e+000, -5.639857e-001, 7.170770e-001, -1.146502e-001, -3.487513e+000, -7.711076e-001, 1.046031e+000, 2.606854e-001, 3.873520e+000, 5.637980e-001, -1.363103e+000, -8.396317e-001, 5.750351e-001, 4.317766e+000, -2.364722e+000, -4.135433e-001, 2.669162e-002, 5.768700e-001, 6.649078e-001, -1.102449e+000, -3.685043e-001, 4.622549e-001, -2.018634e-003, -3.947538e+000, 8.449276e-001, 8.837036e-002, 1.601304e+000, 7.026980e-001, // albedo 0, turbidity 8 -2.314053e+000, -1.314766e+000, -7.125646e+000, 7.357344e+000, -2.585710e-002, 2.863908e-001, -2.425744e-006, 2.039404e+000, 5.594003e-001, -2.630411e+000, -1.404258e+000, 3.675058e+000, -3.804226e+000, -4.249037e-002, 3.486414e-001, 5.675141e-002, 1.944935e+000, 2.880711e-001, -1.884599e+000, -1.657069e+000, -1.731916e+000, 3.034605e+000, -1.746846e-001, -1.559184e-002, -1.600465e-001, 1.915108e+000, 9.460232e-001, 6.351036e-002, 1.061776e+000, 1.195544e-002, -3.018584e+000, -5.618808e-001, 1.008146e+000, 2.013783e-001, 3.212273e+000, 6.523624e-001, -1.672505e+000, -9.752710e-001, 5.282860e-001, 3.776331e+000, -4.325128e+000, -4.384279e-001, 1.352387e-001, 8.847662e-001, 5.717158e-001, -1.007695e+000, -3.840375e-001, 3.463543e-001, 2.848366e+000, -2.105699e+000, 4.636429e-001, 2.800131e-002, 1.306056e+000, 7.618236e-001, // albedo 0, turbidity 9 -2.865406e+000, -1.637174e+000, -7.429613e+000, 7.592861e+000, -2.196505e-002, 2.800873e-001, -3.908530e-006, 1.962505e+000, 5.891464e-001, -3.196334e+000, -1.512711e+000, 3.947880e+000, -4.029796e+000, -3.699620e-002, 1.461452e-001, 5.921432e-002, 1.806132e+000, 2.331816e-001, -2.335492e+000, -2.353032e+000, -1.764665e+000, 2.841986e+000, -7.331326e-002, 4.537047e-001, -1.668000e-001, 2.156269e+000, 9.812486e-001, 3.278911e-001, 1.315177e+000, -1.438189e-001, -2.859630e+000, -8.436262e-001, 2.645711e-001, 2.154409e-001, 2.264493e+000, 5.975203e-001, -1.738015e+000, -1.091057e+000, 5.425696e-001, 4.650166e+000, -3.975190e+000, 2.066035e-001, 1.017332e-001, 9.321625e-001, 6.517783e-001, -1.006457e+000, -4.243112e-001, 1.934952e-001, 2.795030e+000, -1.680697e+000, -9.428375e-002, 7.158314e-002, 1.082383e+000, 7.234775e-001, // albedo 0, turbidity 10 -4.195701e+000, -2.171135e+000, -5.278016e+000, 5.393085e+000, -2.419182e-002, 2.050075e-001, -3.797795e-006, 1.853402e+000, 6.912927e-001, -4.119053e+000, -1.648023e+000, 2.332552e+000, -2.173813e+000, -6.442977e-002, 2.188945e-001, 3.548565e-002, 1.792598e+000, 4.162082e-002, -4.016823e+000, -3.599323e+000, -6.179057e-001, 6.454998e-001, -9.913704e-002, 2.770986e-001, -9.265471e-002, 2.227501e+000, 1.179216e+000, 1.066227e+000, 1.392783e+000, -9.653695e-001, -5.471637e-001, -8.500569e-001, 4.678476e-001, 8.760324e-002, 1.564314e+000, 4.885251e-001, -1.855594e+000, -1.029300e+000, 8.521013e-001, 3.975027e+000, -3.806819e+000, -2.044703e-002, 1.757298e-001, 7.790123e-001, 6.918921e-001, -1.014961e+000, -6.014045e-001, 1.926619e-002, 2.357335e+000, -1.312911e+000, -8.783609e-002, 7.739369e-002, 7.356770e-001, 7.042591e-001, // albedo 1, turbidity 1 -1.467874e+000, -7.636581e-001, -7.251111e+000, 7.726558e+000, -2.759341e-002, 3.527534e-001, 5.340629e-005, 2.007747e+000, 5.447487e-001, -1.863242e+000, -1.048209e+000, -1.580541e+000, 2.558030e+000, -5.622126e-002, 3.053960e-001, -4.657733e-004, 9.956390e-001, 3.409087e-001, -1.384101e+000, -5.553588e-001, 1.191974e+000, -2.157512e+000, -3.567589e-002, 1.020018e-001, 2.940191e-003, 4.555372e+000, 8.736043e-001, -9.828878e-001, -4.220161e-001, 1.184916e+000, 9.230716e-001, -4.062756e-001, 1.064980e+000, -1.060088e-002, -1.764815e+000, 2.932808e-001, -1.057001e+000, -2.727017e-001, 1.000018e+000, -3.108668e-001, 6.848382e-001, -1.682596e-001, 2.301218e-002, 2.075821e+000, 7.647327e-001, -1.058165e+000, -2.436130e-001, 1.074414e+000, 8.554434e-002, -3.846431e+000, 7.595465e-001, 9.729528e-006, 1.915942e+000, 4.999612e-001, // albedo 1, turbidity 2 -1.610179e+000, -8.336019e-001, -1.443356e+001, 1.492556e+001, -1.381931e-002, 2.902743e-001, -7.665717e-006, 1.981513e+000, 9.000423e-001, -2.004083e+000, -1.148388e+000, 3.747156e+000, -2.808560e+000, -3.298677e-002, 4.224754e-001, 4.166438e-004, 8.792110e-001, -2.321793e-001, -1.178554e+000, -5.064839e-001, -1.117126e+000, 2.815740e-001, -7.068438e-002, -3.031589e-002, -3.468069e-003, 4.539093e+000, 1.385612e+000, -1.091191e+000, -4.200919e-001, 1.826508e+000, 7.131992e-002, -1.883417e-001, 1.061437e+000, 1.311913e-002, -1.972550e+000, 2.511246e-001, -9.987232e-001, -2.073656e-001, 7.443384e-001, -7.245157e-002, -5.588818e-001, -1.364188e-001, 2.023795e-002, 2.829822e+000, 7.230021e-001, -1.075477e+000, -2.556973e-001, 1.051690e+000, 3.075960e-002, -1.895492e+000, 6.408333e-001, 2.109454e-002, 1.891240e+000, 5.652527e-001, // albedo 1, turbidity 3 -1.531711e+000, -8.266123e-001, -9.324763e+000, 9.811491e+000, -1.988560e-002, 3.404598e-001, -2.068369e-006, 1.869307e+000, 5.860842e-001, -2.113444e+000, -1.209106e+000, 3.526508e+000, -2.628730e+000, -4.634065e-002, 3.182739e-001, 9.500212e-003, 1.004871e+000, 2.109968e-001, -1.196720e+000, -5.485073e-001, -1.667136e+000, 9.920197e-001, -1.622954e-001, 6.951315e-002, -3.482877e-002, 4.214632e+000, 1.108967e+000, -1.003096e+000, -3.200944e-001, 2.042427e+000, -4.417822e-001, -1.404599e-001, 9.288535e-001, 6.077264e-002, -1.386737e+000, 4.557129e-001, -1.061048e+000, -2.908451e-001, 6.390633e-001, 1.406786e-001, -1.834706e+000, -1.432145e-001, 1.914080e-002, 2.284516e+000, 5.965839e-001, -1.054623e+000, -2.267971e-001, 1.028491e+000, -3.197518e-003, -1.705329e+000, 6.747358e-001, 2.072713e-002, 2.140509e+000, 7.205824e-001, // albedo 1, turbidity 4 -1.610001e+000, -8.622601e-001, -1.060181e+001, 1.106133e+001, -1.648296e-002, 2.590559e-001, -1.904522e-006, 1.930415e+000, 6.006964e-001, -2.308577e+000, -1.440194e+000, 2.937335e+000, -2.093599e+000, -3.430217e-002, 3.427774e-001, 2.590705e-002, 5.673750e-001, 1.250422e-001, -9.441254e-001, -3.064812e-001, -8.895068e-001, 2.815271e-001, -8.036228e-002, 1.867017e-001, -7.809247e-002, 4.774631e+000, 1.391904e+000, -1.214397e+000, -5.423074e-001, 1.361001e+000, 1.782273e-001, -3.648675e-001, 7.181838e-001, 1.135547e-001, -1.935982e+000, 1.820361e-001, -9.377631e-001, -1.533211e-001, 8.439993e-001, -3.893771e-001, -2.564779e-001, -6.742272e-002, 2.255856e-002, 2.780601e+000, 7.972008e-001, -1.101428e+000, -3.069552e-001, 9.687591e-001, 4.500576e-001, -4.912444e+000, 5.398387e-001, 3.638172e-002, 1.582999e+000, 6.425950e-001, // albedo 1, turbidity 5 -1.687541e+000, -9.378170e-001, -8.475686e+000, 8.929279e+000, -2.132746e-002, 2.917650e-001, -2.177239e-006, 1.863407e+000, 5.908179e-001, -2.278432e+000, -1.387936e+000, 5.425292e+000, -4.725025e+000, -3.892912e-002, 4.084727e-001, 1.842665e-002, 8.461986e-001, 1.673366e-001, -1.302702e+000, -7.200083e-001, -3.084331e+000, 3.191487e+000, -3.222828e-001, -1.493849e-001, -5.641672e-002, 3.624218e+000, 1.256086e+000, -7.886965e-001, -3.966453e-002, 2.110076e+000, -2.232935e+000, 7.269719e-001, 1.163410e+000, 7.133744e-002, -1.660119e-001, 4.329084e-001, -1.157760e+000, -4.084596e-001, 5.689088e-001, 2.379590e+000, -9.687743e+000, -5.598487e-001, 9.191895e-002, 1.923047e+000, 5.802927e-001, -1.047250e+000, -2.873072e-001, 1.046858e+000, 6.890046e-001, -2.947892e+000, 7.245997e-001, 1.125227e-002, 1.352625e+000, 7.193979e-001, // albedo 1, turbidity 6 -1.643764e+000, -9.086683e-001, -8.750078e+000, 9.165653e+000, -2.025728e-002, 2.737848e-001, -2.240987e-006, 1.943471e+000, 5.731722e-001, -2.473069e+000, -1.505194e+000, 5.448737e+000, -4.863726e+000, -3.662439e-002, 1.938729e-001, 4.741355e-002, 8.586572e-001, 2.284408e-001, -1.232599e+000, -7.896777e-001, -3.056911e+000, 3.546334e+000, -1.948820e-001, 3.344216e-001, -1.376967e-001, 3.029469e+000, 1.120573e+000, -6.095289e-001, 2.745468e-001, 1.809782e+000, -2.593032e+000, -1.710009e-002, 5.537278e-001, 1.935506e-001, 1.259882e+000, 4.970103e-001, -1.324655e+000, -6.255071e-001, 6.240868e-001, 2.021182e+000, -5.876050e+000, -1.507819e-001, 3.301250e-002, 1.142019e+000, 5.986671e-001, -9.888131e-001, -2.584852e-001, 1.052160e+000, 7.264224e-001, -2.563426e+000, 5.494058e-001, 1.821983e-002, 1.277896e+000, 7.557967e-001, // albedo 1, turbidity 7 -2.100689e+000, -1.204431e+000, -7.573121e+000, 8.039632e+000, -2.300526e-002, 2.839214e-001, -2.346958e-006, 1.678847e+000, 5.536303e-001, -2.610610e+000, -1.587799e+000, 5.460928e+000, -5.158708e+000, -4.505650e-002, 3.876929e-001, 3.852459e-002, 1.172854e+000, 3.104745e-001, -8.340903e-001, -7.487965e-001, -3.154774e+000, 4.600448e+000, -1.818975e-001, -1.871764e-001, -1.222094e-001, 2.067197e+000, 8.802127e-001, -9.180308e-001, 3.752197e-001, 1.471125e+000, -4.691789e+000, -5.128294e-001, 1.164707e+000, 1.831224e-001, 2.900937e+000, 7.718397e-001, -1.126819e+000, -6.652330e-001, 7.386065e-001, 5.362044e+000, -6.196453e+000, -7.280092e-001, 6.312604e-002, 2.874666e-001, 4.225580e-001, -1.091610e+000, -3.433417e-001, 1.042206e+000, 1.075776e-001, -4.443940e+000, 7.469895e-001, 3.166247e-002, 1.019495e+000, 7.523771e-001, // albedo 1, turbidity 8 -2.234623e+000, -1.310221e+000, -8.525764e+000, 8.932373e+000, -1.814945e-002, 2.615153e-001, -2.992344e-006, 1.672403e+000, 5.897681e-001, -2.566352e+000, -1.472664e+000, 5.894182e+000, -5.619094e+000, -3.204346e-002, 2.993298e-001, 4.281047e-002, 1.303481e+000, 2.453403e-001, -1.577477e+000, -1.491725e+000, -3.065840e+000, 4.446634e+000, -1.689128e-001, 9.559287e-002, -1.384724e-001, 1.778589e+000, 9.159045e-001, -2.747774e-001, 8.787060e-001, 1.071723e+000, -4.169230e+000, -3.029966e-001, 6.326611e-001, 2.145395e-001, 2.611218e+000, 7.082708e-001, -1.433045e+000, -8.939972e-001, 8.538090e-001, 4.481475e+000, -5.978961e+000, -1.608369e-001, 5.335732e-002, 3.510751e-001, 5.421327e-001, -9.961738e-001, -3.023960e-001, 9.152994e-001, 2.936173e+000, -2.311060e+000, 1.216642e-001, 2.844950e-002, 9.492671e-001, 6.929460e-001, // albedo 1, turbidity 9 -2.428587e+000, -1.538689e+000, -9.076712e+000, 9.464050e+000, -1.503392e-002, 2.373401e-001, -2.770103e-006, 1.537508e+000, 5.959289e-001, -3.240872e+000, -1.646067e+000, 6.091797e+000, -5.738481e+000, -3.098072e-002, 2.698026e-001, 3.864212e-002, 1.286514e+000, 2.461153e-001, -1.970987e+000, -2.124015e+000, -2.894000e+000, 3.858260e+000, -1.449222e-001, 1.903898e-001, -1.194017e-001, 1.882566e+000, 8.764452e-001, 3.562238e-002, 1.092427e+000, 6.291668e-001, -3.337396e+000, -2.817141e-001, 4.799828e-001, 1.674350e-001, 1.943489e+000, 7.728749e-001, -1.501790e+000, -9.408520e-001, 1.000954e+000, 4.599103e+000, -5.295662e+000, -1.111397e-001, 1.040124e-001, 3.185557e-001, 4.959400e-001, -9.859417e-001, -3.827367e-001, 8.040930e-001, 2.980678e+000, -2.015582e+000, -8.947514e-003, 1.696367e-002, 6.489501e-001, 7.555598e-001, // albedo 1, turbidity 10 -3.758956e+000, -2.159015e+000, -7.207163e+000, 7.516659e+000, -1.643521e-002, 2.465725e-001, -4.045068e-006, 1.471688e+000, 6.687943e-001, -4.635664e+000, -1.766046e+000, 4.282669e+000, -4.058908e+000, -2.908998e-002, 1.202684e-001, 3.167305e-002, 1.450927e+000, 8.171815e-002, -3.458011e+000, -3.657280e+000, -1.484743e+000, 2.264533e+000, -1.033120e-001, 4.282323e-001, -8.387881e-002, 1.687334e+000, 1.130604e+000, 9.673527e-001, 1.500425e+000, -3.604932e-001, -2.050346e+000, -3.778381e-001, 2.416298e-001, 8.439313e-002, 1.458583e+000, 5.816071e-001, -1.808078e+000, -1.089975e+000, 1.291838e+000, 5.144631e+000, -5.047822e+000, 4.301183e-002, 1.426941e-001, 1.187472e-001, 6.145551e-001, -8.399253e-001, -3.832885e-001, 6.306417e-001, 2.179775e+000, -1.492762e+000, -1.682763e-001, 4.109851e-002, 4.221724e-001, 7.086504e-001, }; static float datasetRad400[] = { // albedo 0, turbidity 1 5.767645e-003, 1.219302e-002, -2.188467e-002, 8.262275e-002, 1.719839e-001, 1.233791e-001, // albedo 0, turbidity 2 5.661981e-003, 1.258489e-002, -2.324339e-002, 8.372421e-002, 1.730981e-001, 1.255797e-001, // albedo 0, turbidity 3 5.644031e-003, 1.248986e-002, -2.287316e-002, 7.999388e-002, 1.815345e-001, 1.252983e-001, // albedo 0, turbidity 4 5.479152e-003, 1.215496e-002, -2.122586e-002, 7.189527e-002, 1.962517e-001, 1.245648e-001, // albedo 0, turbidity 5 5.385972e-003, 1.187505e-002, -2.025911e-002, 6.602510e-002, 2.067312e-001, 1.264910e-001, // albedo 0, turbidity 6 5.319970e-003, 1.160513e-002, -1.904232e-002, 6.030292e-002, 2.158311e-001, 1.261204e-001, // albedo 0, turbidity 7 5.179289e-003, 1.125842e-002, -1.708641e-002, 5.111365e-002, 2.285030e-001, 1.278260e-001, // albedo 0, turbidity 8 4.994685e-003, 1.025385e-002, -1.254777e-002, 3.429945e-002, 2.490310e-001, 1.302691e-001, // albedo 0, turbidity 9 4.759538e-003, 8.205142e-003, -3.246300e-003, 3.909938e-003, 2.819549e-001, 1.322430e-001, // albedo 0, turbidity 10 4.412341e-003, 4.910210e-003, 1.040886e-002, -3.627125e-002, 3.147182e-001, 1.409331e-001, // albedo 1, turbidity 1 7.016633e-003, 9.796846e-003, -9.823849e-004, 2.324224e-002, 3.035010e-001, 2.573850e-001, // albedo 1, turbidity 2 6.984411e-003, 9.584282e-003, -5.945671e-004, 2.061312e-002, 3.090019e-001, 2.547364e-001, // albedo 1, turbidity 3 6.865141e-003, 9.540856e-003, -3.311701e-004, 1.726495e-002, 3.147099e-001, 2.539552e-001, // albedo 1, turbidity 4 6.701191e-003, 9.352606e-003, 3.392916e-004, 1.159886e-002, 3.228446e-001, 2.530111e-001, // albedo 1, turbidity 5 6.513679e-003, 8.873317e-003, 2.339520e-003, 2.817964e-003, 3.341256e-001, 2.496316e-001, // albedo 1, turbidity 6 6.405833e-003, 8.466409e-003, 3.661909e-003, -3.045984e-003, 3.414328e-001, 2.464327e-001, // albedo 1, turbidity 7 6.220899e-003, 7.997469e-003, 5.957591e-003, -1.302863e-002, 3.523355e-001, 2.418785e-001, // albedo 1, turbidity 8 5.912801e-003, 6.826679e-003, 1.008544e-002, -2.771812e-002, 3.640405e-001, 2.386599e-001, // albedo 1, turbidity 9 5.550967e-003, 5.157051e-003, 1.661696e-002, -5.072656e-002, 3.807009e-001, 2.315489e-001, // albedo 1, turbidity 10 5.011118e-003, 2.636752e-003, 2.499879e-002, -7.576617e-002, 3.828189e-001, 2.328116e-001, }; static float dataset440[] = { // albedo 0, turbidity 1 -1.397312e+000, -5.327311e-001, -5.456059e+000, 5.777674e+000, -5.111575e-002, 4.730804e-001, 7.375500e-003, 3.032806e+000, 5.181890e-001, -1.561639e+000, -7.024946e-001, -2.140322e+000, 2.841761e+000, -8.846023e-002, 5.529005e-001, 6.219344e-003, 2.004212e+000, 3.701256e-001, -1.047473e+000, -1.152734e-001, 2.275873e+000, -3.020347e+000, -1.739218e-001, 2.250142e-001, -2.731776e-002, 6.659723e+000, 1.067495e+000, -1.298483e+000, -5.788209e-001, 4.906412e-001, 1.522576e+000, -5.650061e-001, 1.544707e+000, 4.638003e-002, -3.742019e+000, 2.485397e-001, -9.485899e-001, -7.383610e-002, 1.039247e+000, -4.744931e-001, -1.822357e-001, 2.284415e-001, -4.796962e-002, 4.363935e+000, 8.217971e-001, -1.099082e+000, -2.001688e-001, 7.365077e-001, 1.068489e-001, -5.005434e+000, 1.508145e+000, 8.181497e-002, 3.226865e+000, 4.999418e-001, // albedo 0, turbidity 2 -1.416143e+000, -5.515006e-001, -7.045898e+000, 7.448161e+000, -4.504075e-002, 5.055437e-001, -1.378949e-006, 2.955475e+000, 6.184716e-001, -1.698183e+000, -8.272914e-001, 9.984388e-001, -2.511235e-001, -9.262675e-002, 5.681534e-001, 5.377123e-003, 1.631048e+000, 1.137691e-001, -9.234085e-001, -2.165404e-002, 6.483039e-002, -8.535145e-001, -2.497457e-001, 1.695057e-001, -3.410225e-002, 6.726925e+000, 1.331197e+000, -1.265077e+000, -5.034231e-001, 1.196547e+000, 3.666463e-001, -3.960044e-001, 1.404008e+000, 1.129300e-001, -2.644439e+000, 1.103356e-001, -1.008210e+000, -1.455232e-001, 7.347739e-001, 2.462433e-002, -2.534587e+000, 3.088590e-001, -6.687136e-002, 3.786007e+000, 9.578369e-001, -1.076840e+000, -1.851501e-001, 7.341818e-001, -2.658571e-003, -5.001762e+000, 1.275390e+000, 1.277410e-001, 3.223315e+000, 5.147659e-001, // albedo 0, turbidity 3 -1.449526e+000, -5.738159e-001, -8.976383e+000, 9.275142e+000, -3.157845e-002, 5.011970e-001, -1.218363e-006, 3.001006e+000, 5.662190e-001, -1.748840e+000, -9.338946e-001, 5.557460e-002, 9.451626e-001, -6.929558e-002, 5.458365e-001, 5.505399e-003, 8.818793e-001, 2.135274e-001, -8.369988e-001, 1.127967e-001, 8.846958e-001, -2.467908e+000, -8.394011e-002, 1.684067e-001, -3.352743e-002, 7.957386e+000, 1.297777e+000, -1.284515e+000, -5.332365e-001, 5.511261e-001, 1.702784e+000, -6.616281e-001, 1.349449e+000, 1.269152e-001, -3.247373e+000, 2.115827e-001, -9.889637e-001, -9.962819e-002, 6.096776e-001, -8.472749e-001, 7.672924e-001, 7.425160e-002, 2.113714e-002, 4.990637e+000, 8.274585e-001, -1.093910e+000, -2.211349e-001, 6.959659e-001, 3.423174e-001, -5.004213e+000, 1.347201e+000, 1.198192e-001, 2.547517e+000, 6.329489e-001, // albedo 0, turbidity 4 -1.394462e+000, -5.287733e-001, -8.095187e+000, 8.076613e+000, -1.275227e-002, 1.916790e-001, 4.741296e-002, 3.145140e+000, 5.071760e-001, -2.234192e+000, -1.437079e+000, -5.734544e-001, 1.248687e+000, -4.136344e-002, 7.671749e-001, -1.273584e-002, 4.751894e-001, 4.116995e-001, -4.063889e-001, 4.920785e-001, 3.865520e-001, 2.254008e-001, -1.618861e-001, 1.950875e-001, -8.622479e-002, 3.836900e+000, 1.108189e+000, -1.366924e+000, -4.557853e-001, -6.731417e-001, -3.011452e-001, 2.413069e-001, 1.404821e+000, 1.920278e-001, 6.394529e+000, 4.219713e-001, -9.128947e-001, 1.980978e-002, 5.119874e-001, 8.027541e-002, -3.680159e+000, 6.597416e-001, 3.853339e-002, 3.969131e+000, 8.351942e-001, -1.162856e+000, -3.606511e-001, 7.055795e-001, -2.702137e-003, 4.777294e-001, -7.722331e-001, 3.446509e-001, 1.186834e+000, 5.118539e-001, // albedo 0, turbidity 5 -1.563353e+000, -6.916347e-001, -4.154766e+001, 4.181703e+001, -5.673370e-003, 4.344900e-001, 1.839829e-003, 2.669278e+000, 5.021266e-001, -1.948172e+000, -1.080669e+000, 1.082552e+001, -1.034262e+001, -1.196421e-002, 3.895739e-001, 5.621831e-002, 1.347130e+000, 4.561106e-001, -9.155219e-001, -1.456265e-001, -2.177275e+000, 2.079788e+000, -2.154465e-002, 7.743816e-001, -2.181642e-001, 4.897704e+000, 1.035464e+000, -1.010898e+000, -4.425431e-002, 3.067880e-001, -6.899235e-001, -1.891895e-001, 3.015686e-001, 4.236422e-001, 1.901582e+000, 3.916662e-001, -1.159005e+000, -4.048136e-001, 5.385745e-001, 3.423651e-001, 1.474365e-001, 3.516065e-001, 2.564260e-003, 1.815518e+000, 7.634079e-001, -1.081675e+000, -2.556981e-001, 6.544471e-001, 4.093649e-001, -3.215201e+000, 9.116400e-001, 1.406660e-001, 1.869407e+000, 6.968119e-001, // albedo 0, turbidity 6 -1.561484e+000, -7.153039e-001, -1.623772e+001, 1.650713e+001, -1.394913e-002, 4.467465e-001, 9.613464e-004, 2.564429e+000, 5.363746e-001, -2.308050e+000, -1.314851e+000, -1.484346e+000, 1.928705e+000, -2.164130e-002, 2.817711e-001, 7.177671e-002, 1.146387e+000, 3.025595e-001, -4.886429e-001, 8.279799e-002, 2.432876e+000, -2.276257e+000, -4.799742e-002, 9.362010e-001, -2.753669e-001, 4.784291e+000, 1.180593e+000, -1.306115e+000, -1.759650e-001, -1.392008e+000, 3.119302e-001, -2.268673e-001, 8.336951e-002, 5.250725e-001, 2.534962e+000, 2.800244e-001, -1.016608e+000, -3.429911e-001, 5.659470e-001, 9.044333e-001, 7.387499e-002, 4.267609e-001, -4.165623e-002, 1.452779e+000, 8.409560e-001, -1.127637e+000, -2.854231e-001, 4.933964e-001, -3.379287e-003, -1.181893e+000, 8.164171e-001, 1.910509e-001, 1.979338e+000, 6.658885e-001, // albedo 0, turbidity 7 -1.675310e+000, -8.020443e-001, -1.136130e+001, 1.159861e+001, -1.871156e-002, 4.151400e-001, -1.940992e-006, 2.486322e+000, 5.256426e-001, -2.071301e+000, -1.175325e+000, 1.789426e+000, -1.455233e+000, -2.855906e-002, 3.218745e-001, 7.776969e-002, 1.431615e+000, 3.478887e-001, -1.093503e+000, -4.120496e-001, -8.598647e-002, 4.564844e-001, -1.231980e-001, 7.992132e-001, -2.910745e-001, 3.881502e+000, 1.064658e+000, -7.736128e-001, 2.385498e-001, -7.867818e-001, -6.009723e-001, -1.808566e-001, -8.796429e-003, 5.412620e-001, 2.991552e+000, 4.008143e-001, -1.259083e+000, -5.300975e-001, 5.418031e-001, 1.150966e+000, -7.553821e-001, 5.991000e-001, -2.344718e-003, 1.097939e+000, 7.756612e-001, -1.094148e+000, -3.178958e-001, 4.126954e-001, 3.591106e-001, -1.415744e+000, 3.908399e-001, 1.806147e-001, 1.584959e+000, 6.862009e-001, // albedo 0, turbidity 8 -1.815485e+000, -9.306778e-001, -1.249527e+001, 1.271288e+001, -1.497209e-002, 3.576353e-001, -2.464284e-006, 2.326460e+000, 5.655414e-001, -2.225570e+000, -1.213627e+000, 6.082472e+000, -5.907562e+000, -2.446452e-002, 2.113558e-001, 7.708802e-002, 1.647556e+000, 2.416155e-001, -1.439532e+000, -8.666475e-001, -2.734807e+000, 3.355265e+000, -1.311068e-001, 1.048703e+000, -2.887025e-001, 3.419973e+000, 1.146322e+000, -5.599890e-001, 4.437236e-001, 1.582320e-001, -2.000110e+000, -2.859304e-001, -5.600631e-001, 5.382793e-001, 1.986387e+000, 3.455121e-001, -1.319304e+000, -6.466246e-001, 5.684685e-001, 2.050330e+000, -2.796053e+000, 1.001659e+000, -1.161356e-002, 9.737235e-001, 8.101246e-001, -1.097281e+000, -3.336023e-001, 1.781708e-001, 1.733079e+000, -1.378806e+000, -1.870394e-001, 1.997578e-001, 1.456148e+000, 6.791796e-001, // albedo 0, turbidity 9 -2.208666e+000, -1.219745e+000, -7.548669e+000, 7.680830e+000, -2.012473e-002, 3.627866e-001, -2.906182e-006, 2.147138e+000, 6.340095e-001, -1.967348e+000, -9.528057e-001, 4.171590e+000, -4.002838e+000, -5.074552e-002, 1.581866e-001, 5.920106e-002, 1.981564e+000, 1.023257e-001, -3.150304e+000, -2.193706e+000, -2.016165e+000, 2.374337e+000, -6.793058e-002, 9.623811e-001, -2.195022e-001, 2.736885e+000, 1.252161e+000, 4.737094e-001, 1.067875e+000, -1.003861e-001, -1.566752e+000, -1.217264e+000, -4.270598e-001, 3.968055e-001, 1.234108e+000, 3.105789e-001, -1.706975e+000, -9.607442e-001, 7.140098e-001, 3.981202e+000, -3.521433e+000, 6.308820e-001, 5.140937e-002, 7.435120e-001, 8.074305e-001, -1.012042e+000, -3.372525e-001, 2.589450e-002, 1.768224e+000, -1.059990e+000, -1.299077e-001, 1.790337e-001, 1.091012e+000, 6.873854e-001, // albedo 0, turbidity 10 -2.912541e+000, -1.677524e+000, -3.843452e+000, 3.954207e+000, -3.414327e-002, 2.945890e-001, -4.245832e-006, 1.934337e+000, 7.258748e-001, -1.567383e+000, -8.279686e-001, 1.690940e+000, -1.413268e+000, -1.216792e-001, 7.332798e-002, 4.862765e-002, 2.034766e+000, -5.041561e-002, -6.058613e+000, -3.509207e+000, -6.312870e-001, -4.558316e-002, 6.168891e-002, 8.153413e-001, -1.686845e-001, 2.670227e+000, 1.362906e+000, 1.347177e+000, 9.821888e-001, -9.242155e-001, 5.851576e-001, -1.897421e+000, -2.729487e-002, 2.866724e-001, 7.306238e-001, 2.792136e-001, -1.810783e+000, -1.027512e+000, 1.216071e+000, 5.270108e+000, -3.887149e+000, 6.193256e-002, 2.774610e-002, 1.484756e-001, 8.033249e-001, -9.801965e-001, -3.375841e-001, -3.004804e-001, 1.385754e+000, -6.834540e-001, 5.827734e-002, 2.268309e-001, 1.028696e+000, 6.797371e-001, // albedo 1, turbidity 1 -1.345260e+000, -5.085528e-001, -6.052009e+000, 6.604590e+000, -4.300752e-002, 4.745234e-001, 6.591457e-003, 2.595142e+000, 5.013653e-001, -1.573525e+000, -7.133524e-001, -1.671346e+000, 2.693205e+000, -7.828763e-002, 2.915699e-001, 1.795879e-002, 1.469445e+000, 4.927472e-001, -1.013665e+000, -1.731419e-001, 2.043423e+000, -2.919634e+000, -1.020807e-001, 5.467619e-001, -4.041481e-002, 5.853992e+000, 5.272064e-001, -1.173191e+000, -3.964683e-001, 1.097258e+000, 1.509973e+000, -5.675641e-001, 9.815927e-001, 6.962319e-002, -3.358210e+000, 4.263117e-001, -1.003507e+000, -1.124908e-001, 1.030642e+000, -5.357088e-001, 6.114201e-001, 1.628414e-001, -5.701497e-002, 4.541126e+000, 8.084996e-001, -1.071959e+000, -1.567262e-001, 9.923029e-001, 1.457160e-001, -4.742907e+000, 7.280970e-001, 6.770360e-002, 3.919300e+000, 4.999529e-001, // albedo 1, turbidity 2 -1.399982e+000, -5.538549e-001, -6.983148e+000, 7.513966e+000, -3.358417e-002, 3.667027e-001, 1.158837e-002, 2.499680e+000, 5.598537e-001, -1.602839e+000, -7.835806e-001, 1.200264e+000, -1.454290e-001, -7.431927e-002, 5.374263e-001, 9.505505e-004, 1.096167e+000, 2.185838e-001, -9.587294e-001, -6.134134e-002, 2.234030e-001, -8.115395e-001, -2.344054e-001, 2.018782e-001, -4.192332e-002, 6.331499e+000, 1.353587e+000, -1.166832e+000, -4.057833e-001, 1.461335e+000, 3.165401e-001, -3.245858e-001, 1.199323e+000, 1.100274e-001, -2.727373e+000, 5.329788e-002, -1.023178e+000, -1.351631e-001, 9.944251e-001, 2.103341e-002, -2.460318e+000, 5.136074e-003, -5.267951e-002, 4.097235e+000, 9.388837e-001, -1.071426e+000, -1.726491e-001, 1.048949e+000, -2.624840e-003, -4.993124e+000, 6.621513e-001, 7.801931e-002, 3.227750e+000, 5.363265e-001, // albedo 1, turbidity 3 -1.362723e+000, -5.257224e-001, -1.325130e+001, 1.374641e+001, -1.971887e-002, 4.480379e-001, -9.588735e-007, 2.679516e+000, 5.628531e-001, -1.824466e+000, -9.877790e-001, 4.631069e+000, -3.630521e+000, -4.340325e-002, 3.913450e-001, 3.415899e-002, 4.746800e-001, 2.022772e-001, -6.435267e-001, 1.629762e-001, -1.452097e+000, 8.028761e-001, -9.611017e-002, 4.267105e-001, -1.023573e-001, 6.652106e+000, 1.406057e+000, -1.400277e+000, -5.150235e-001, 1.752017e+000, -1.699743e-001, -3.411643e-001, 8.465596e-001, 2.127075e-001, -2.235971e+000, 4.728189e-002, -9.044866e-001, -7.979493e-002, 8.298122e-001, -5.604698e-002, -1.433761e+000, 1.011757e-001, -7.175544e-002, 4.243075e+000, 9.588179e-001, -1.115618e+000, -2.148000e-001, 1.109081e+000, 2.661209e-001, -5.008111e+000, 6.333048e-001, 9.274718e-002, 2.494529e+000, 5.890657e-001, // albedo 1, turbidity 4 -1.389611e+000, -5.579886e-001, -1.045229e+001, 1.092342e+001, -2.282772e-002, 4.054079e-001, 2.781558e-003, 2.578484e+000, 5.372706e-001, -1.893851e+000, -1.116122e+000, 2.111553e+000, -8.775468e-001, -5.640158e-002, 5.399894e-001, 1.929352e-002, -5.585557e-002, 2.870402e-001, -7.015617e-001, 1.884526e-001, -1.660273e-001, -8.785899e-001, -5.471987e-002, 1.787856e-001, -9.958870e-002, 7.207213e+000, 1.277933e+000, -1.279075e+000, -4.794032e-001, 9.037342e-001, 6.225399e-001, -6.592270e-001, 9.474313e-001, 2.524811e-001, -2.485658e+000, 2.050401e-001, -9.744212e-001, -9.899254e-002, 9.474600e-001, -2.536639e-001, 5.390432e-001, -8.465488e-002, -3.140532e-002, 4.512343e+000, 8.530654e-001, -1.093264e+000, -2.115594e-001, 9.876876e-001, 7.531309e-002, -5.003648e+000, 6.719560e-001, 1.111699e-001, 2.412349e+000, 6.482966e-001, // albedo 1, turbidity 5 -1.410458e+000, -5.905263e-001, -4.146328e+001, 4.190254e+001, -5.607421e-003, 4.437719e-001, -1.948391e-006, 2.496743e+000, 5.031933e-001, -1.817258e+000, -9.848495e-001, 1.089217e+001, -1.028029e+001, -1.221684e-002, 3.317008e-001, 5.060062e-002, 1.198443e+000, 4.449482e-001, -8.920534e-001, -8.835804e-002, -2.111594e+000, 2.083599e+000, -1.507800e-002, 6.993567e-001, -1.987686e-001, 4.793539e+000, 1.072586e+000, -1.048633e+000, -1.110825e-001, 5.438710e-001, -6.707296e-001, -1.825365e-001, 2.307221e-001, 4.056218e-001, 1.886912e+000, 3.579576e-001, -1.094223e+000, -3.084727e-001, 9.739595e-001, 3.972140e-001, 1.511647e-001, 2.788218e-001, -6.279180e-002, 1.866444e+000, 7.995203e-001, -1.078162e+000, -2.176197e-001, 1.088756e+000, 4.329413e-001, -3.209490e+000, 8.364785e-001, 7.689785e-002, 1.943182e+000, 7.150615e-001, // albedo 1, turbidity 6 -1.455846e+000, -6.322333e-001, -1.618289e+001, 1.656258e+001, -1.280603e-002, 4.130359e-001, -9.061644e-007, 2.461391e+000, 5.315915e-001, -2.222251e+000, -1.233356e+000, -1.454954e+000, 1.957432e+000, -1.730555e-002, 2.418496e-001, 7.240262e-002, 1.061939e+000, 3.148474e-001, -4.536196e-001, 1.457295e-001, 2.483934e+000, -2.244550e+000, -4.593767e-002, 8.967621e-001, -2.712877e-001, 4.732142e+000, 1.188839e+000, -1.277343e+000, -2.046024e-001, -1.229720e+000, 3.977256e-001, -2.209195e-001, 6.033235e-002, 5.267707e-001, 2.536445e+000, 2.759606e-001, -1.029833e+000, -2.979843e-001, 8.742883e-001, 1.037710e+000, 1.350257e-001, 4.066094e-001, -1.376375e-001, 1.500753e+000, 8.676699e-001, -1.095935e+000, -2.211775e-001, 9.320585e-001, 8.955212e-002, -1.113388e+000, 7.909911e-001, 1.393848e-001, 2.057146e+000, 6.699739e-001, // albedo 1, turbidity 7 -1.571831e+000, -7.466353e-001, -1.226063e+001, 1.265995e+001, -1.514083e-002, 3.639653e-001, -2.504287e-006, 2.204454e+000, 5.468861e-001, -2.235398e+000, -1.371434e+000, 1.787996e+000, -1.073965e+000, -2.503530e-002, 2.143584e-001, 7.703453e-002, 5.207181e-001, 2.714312e-001, -6.944677e-001, -7.243136e-002, -6.193104e-001, 9.567440e-001, -6.317194e-002, 8.881508e-001, -2.783301e-001, 4.224532e+000, 1.192802e+000, -1.133391e+000, -9.811942e-002, 2.312721e-001, -1.100585e+000, -3.655097e-001, 2.268787e-003, 5.074358e-001, 1.512457e+000, 3.165593e-001, -1.057051e+000, -3.424797e-001, 9.536822e-001, 1.034064e+000, 6.413292e-001, 1.165363e-001, -4.248128e-002, 1.592803e+000, 7.875911e-001, -1.096695e+000, -2.745143e-001, 1.077920e+000, -8.435082e-004, -3.715956e+000, 5.197900e-001, 1.171467e-001, 1.236912e+000, 6.915287e-001, // albedo 1, turbidity 8 -1.711623e+000, -9.023881e-001, -9.799257e+000, 1.022040e+001, -1.708447e-002, 3.309925e-001, -3.241111e-006, 1.932295e+000, 5.844205e-001, -2.351937e+000, -1.340391e+000, 6.329976e+000, -6.054139e+000, -2.843868e-002, 2.298301e-001, 7.698142e-002, 1.109800e+000, 1.863187e-001, -1.141314e+000, -6.670322e-001, -3.262632e+000, 4.551521e+000, -8.614941e-002, 8.058038e-001, -2.791051e-001, 3.084281e+000, 1.236638e+000, -7.950557e-001, 2.489854e-001, 9.966347e-001, -3.391737e+000, -7.235716e-001, -2.155609e-001, 5.126659e-001, 1.452322e+000, 2.882812e-001, -1.182289e+000, -5.192524e-001, 9.672941e-001, 3.091448e+000, -4.193043e+000, 4.051469e-001, -5.708309e-002, 9.386723e-001, 8.208828e-001, -1.080579e+000, -2.918654e-001, 9.499317e-001, 2.856082e+000, -2.256007e+000, 1.377750e-002, 1.012914e-001, 9.716489e-001, 6.832750e-001, // albedo 1, turbidity 9 -1.964781e+000, -1.162652e+000, -6.074737e+000, 6.497797e+000, -2.595660e-002, 3.222936e-001, -3.220871e-006, 1.685891e+000, 6.501551e-001, -2.352213e+000, -1.199539e+000, 4.248376e+000, -3.876965e+000, -6.837923e-002, 1.764412e-001, 5.514810e-002, 1.442736e+000, 6.979575e-002, -2.560247e+000, -1.883591e+000, -1.916723e+000, 2.598994e+000, -2.372381e-002, 8.442578e-001, -2.063113e-001, 2.359942e+000, 1.287838e+000, 7.281064e-002, 7.835433e-001, 1.380748e-001, -2.065580e+000, -1.696648e+000, -4.575316e-001, 3.840004e-001, 9.397056e-001, 3.103904e-001, -1.444446e+000, -7.662151e-001, 1.364103e+000, 4.930232e+000, -4.455564e+000, 6.735458e-001, -4.052978e-003, 3.194173e-001, 7.842959e-001, -1.039666e+000, -3.171617e-001, 7.295920e-001, 2.813846e+000, -1.561230e+000, -4.128303e-001, 1.004149e-001, 6.653613e-001, 6.980277e-001, // albedo 1, turbidity 10 -2.999915e+000, -1.721740e+000, -4.796494e+000, 5.021888e+000, -2.163250e-002, 3.309183e-001, -4.051804e-006, 1.645464e+000, 7.145890e-001, -1.673162e+000, -1.056666e+000, 3.209766e+000, -2.559187e+000, -7.456364e-002, 6.215063e-002, 4.469425e-002, 1.242757e+000, -1.580590e-002, -5.775475e+000, -3.239700e+000, -1.356432e+000, 1.099950e+000, -9.497509e-002, 7.121875e-001, -1.656838e-001, 2.553396e+000, 1.286227e+000, 1.241869e+000, 6.671222e-001, -4.156007e-001, -8.167921e-001, -1.037816e+000, 5.950065e-002, 3.114868e-001, 6.414114e-001, 3.677503e-001, -1.580126e+000, -7.852349e-001, 1.749569e+000, 5.987990e+000, -5.075133e+000, -4.693815e-002, -5.106759e-002, -9.755925e-001, 7.440092e-001, -9.732917e-001, -1.939297e-001, 2.709367e-001, 1.352990e+000, -9.040352e-001, 5.181217e-003, 2.302437e-001, 1.506500e+000, 6.840186e-001, }; static float datasetRad440[] = { // albedo 0, turbidity 1 9.406889e-003, 1.954373e-002, -4.018205e-002, 1.740051e-001, 1.351020e-001, 1.365376e-001, // albedo 0, turbidity 2 9.206049e-003, 2.042313e-002, -4.377380e-002, 1.787089e-001, 1.388614e-001, 1.384128e-001, // albedo 0, turbidity 3 9.050889e-003, 2.086396e-002, -4.652916e-002, 1.794829e-001, 1.524222e-001, 1.376563e-001, // albedo 0, turbidity 4 8.656343e-003, 2.210653e-002, -5.212791e-002, 1.836315e-001, 1.663040e-001, 1.419649e-001, // albedo 0, turbidity 5 8.355466e-003, 2.244975e-002, -5.393078e-002, 1.788056e-001, 1.868417e-001, 1.445069e-001, // albedo 0, turbidity 6 8.187585e-003, 2.235434e-002, -5.291187e-002, 1.693688e-001, 2.073941e-001, 1.424517e-001, // albedo 0, turbidity 7 7.909229e-003, 2.199365e-002, -5.165975e-002, 1.577725e-001, 2.297489e-001, 1.468516e-001, // albedo 0, turbidity 8 7.580566e-003, 2.048421e-002, -4.471863e-002, 1.277026e-001, 2.737620e-001, 1.497600e-001, // albedo 0, turbidity 9 7.101943e-003, 1.675094e-002, -2.761544e-002, 7.078506e-002, 3.397147e-001, 1.557184e-001, // albedo 0, turbidity 10 6.525444e-003, 1.090411e-002, -1.995302e-003, -8.176097e-003, 4.124321e-001, 1.714881e-001, // albedo 1, turbidity 1 1.111702e-002, 1.783998e-002, -1.949635e-002, 1.124970e-001, 2.993330e-001, 2.864943e-001, // albedo 1, turbidity 2 1.099681e-002, 1.809609e-002, -2.099087e-002, 1.131858e-001, 3.057413e-001, 2.866962e-001, // albedo 1, turbidity 3 1.070017e-002, 1.818573e-002, -2.159895e-002, 1.084494e-001, 3.229180e-001, 2.835407e-001, // albedo 1, turbidity 4 1.032234e-002, 1.871074e-002, -2.469404e-002, 1.069731e-001, 3.380450e-001, 2.864479e-001, // albedo 1, turbidity 5 9.893912e-003, 1.844953e-002, -2.358500e-002, 9.439551e-002, 3.642566e-001, 2.829554e-001, // albedo 1, turbidity 6 9.650400e-003, 1.877062e-002, -2.542361e-002, 9.189004e-002, 3.720610e-001, 2.856265e-001, // albedo 1, turbidity 7 9.322628e-003, 1.810055e-002, -2.246559e-002, 7.543314e-002, 3.958251e-001, 2.842134e-001, // albedo 1, turbidity 8 8.842659e-003, 1.604245e-002, -1.397353e-002, 4.233011e-002, 4.358270e-001, 2.789888e-001, // albedo 1, turbidity 9 8.169168e-003, 1.265551e-002, 4.076399e-004, -7.877623e-003, 4.830048e-001, 2.768485e-001, // albedo 1, turbidity 10 7.383449e-003, 7.340131e-003, 2.094279e-002, -7.138907e-002, 5.217098e-001, 2.803810e-001, }; static float dataset480[] = { // albedo 0, turbidity 1 -1.255072e+000, -3.501170e-001, -5.952795e+000, 6.529723e+000, -6.362962e-002, 6.436422e-001, 7.745270e-003, 3.657426e+000, 5.329375e-001, -1.344988e+000, -4.365880e-001, -1.750961e+000, 2.262943e+000, -1.049983e-001, 3.754288e-001, 5.298712e-002, 3.402851e+000, 3.874229e-001, -1.073402e+000, -1.395260e-001, 2.839003e+000, -2.827315e+000, -1.882090e-001, 1.054349e+000, -8.976330e-002, 5.604794e+000, 6.740510e-001, -1.183711e+000, -4.011868e-001, 7.358740e-001, 1.479436e+000, -7.268596e-001, 1.133998e+000, 1.205942e-001, -4.232970e+000, 1.060586e+000, -1.018668e+000, -8.561816e-002, 1.030241e+000, -4.461392e-001, 3.940284e-001, 1.220382e+000, -1.391238e-001, 5.771847e+000, 5.627180e-001, -1.080081e+000, -1.746769e-001, 1.174843e+000, 9.389450e-002, -4.893194e+000, 1.162505e+000, 1.563406e-001, 2.606800e+000, 4.999990e-001, // albedo 0, turbidity 2 -1.268430e+000, -3.752425e-001, -8.504068e+000, 9.021017e+000, -4.092613e-002, 6.553965e-001, 8.607147e-003, 3.444138e+000, 5.600385e-001, -1.459780e+000, -5.882818e-001, 1.800729e+000, -9.674514e-001, -8.308819e-002, 4.453337e-001, 4.086836e-002, 1.853978e+000, 2.818975e-001, -8.680288e-001, 1.148721e-001, 3.161508e-001, -1.524870e+000, -1.921031e-001, 6.496299e-001, 4.422347e-004, 8.241268e+000, 9.821338e-001, -1.277439e+000, -4.550135e-001, 1.088681e+000, 1.552370e+000, -6.184442e-001, 1.386667e+000, 1.035135e-001, -3.331179e+000, 5.236122e-001, -9.964896e-001, -9.832891e-002, 9.746026e-001, -9.125638e-001, -7.457170e-001, 9.111352e-001, -7.027011e-002, 4.669829e+000, 7.455938e-001, -1.083449e+000, -1.686372e-001, 1.003727e+000, 4.085513e-001, -4.725304e+000, 1.112591e+000, 1.855240e-001, 3.038195e+000, 5.969305e-001, // albedo 0, turbidity 3 -1.290677e+000, -3.901158e-001, -9.520695e+000, 9.828711e+000, -3.154131e-002, 5.939314e-001, 2.686840e-002, 3.612397e+000, 5.140176e-001, -1.535002e+000, -6.667464e-001, 2.735758e-002, 9.423936e-001, -8.287240e-002, 6.775029e-001, 4.575744e-003, 1.432097e+000, 3.872415e-001, -7.903104e-001, 1.563438e-001, -2.022567e-001, -1.026670e+000, 9.063977e-003, 3.942033e-001, -1.241980e-002, 7.980026e+000, 1.066191e+000, -1.278947e+000, -3.694875e-001, 8.111792e-001, 4.993027e-001, -1.096772e+000, 1.008837e+000, 2.920972e-001, -7.314209e-001, 3.179440e-001, -1.006667e+000, -1.519095e-001, 8.774664e-001, -1.909283e-001, 3.756189e+000, 9.311862e-001, -9.327427e-002, 3.499747e+000, 8.574583e-001, -1.086931e+000, -1.774734e-001, 8.989024e-001, 5.536469e-002, -3.474034e+000, 9.736834e-001, 2.325787e-001, 2.809427e+000, 6.246481e-001, // albedo 0, turbidity 4 -1.346571e+000, -4.451276e-001, -2.373159e+001, 2.408962e+001, -1.225268e-002, 5.720568e-001, 1.636363e-002, 3.288957e+000, 5.104502e-001, -1.607315e+000, -7.416360e-001, -5.233286e-001, 1.169215e+000, -2.350907e-002, 4.942922e-001, 3.544231e-002, 1.659598e+000, 3.959771e-001, -8.259129e-001, 9.305732e-002, 4.864320e+000, -5.585537e+000, -4.428624e-002, 7.540493e-001, -1.060506e-001, 6.548781e+000, 1.138009e+000, -1.204471e+000, -2.620580e-001, -2.637261e+000, 3.057335e+000, -1.226916e-001, 5.657925e-001, 4.446409e-001, 1.136957e+000, 2.881385e-001, -1.035718e+000, -2.116415e-001, 1.288642e+000, -3.834162e-001, -9.488050e-002, 7.404996e-001, -6.538922e-002, 2.336877e+000, 8.612030e-001, -1.087946e+000, -1.841898e-001, 4.491757e-001, 1.691479e-001, 1.022577e-001, 9.202996e-001, 2.926112e-001, 2.844475e+000, 6.452620e-001, // albedo 0, turbidity 5 -1.381782e+000, -4.914069e-001, -4.813999e+001, 4.837634e+001, -5.296025e-003, 5.571609e-001, 1.649034e-002, 3.203385e+000, 5.048069e-001, -1.776157e+000, -9.226583e-001, 1.389662e+001, -1.292490e+001, -1.480095e-002, 5.073308e-001, 4.585849e-002, 7.385206e-001, 4.280887e-001, -8.381948e-001, 1.229315e-001, -3.370527e+000, 1.825510e+000, -9.728251e-003, 8.572929e-001, -1.855299e-001, 7.471741e+000, 1.133190e+000, -1.125194e+000, -2.647028e-001, 6.942391e-001, 1.389102e+000, -2.216447e-001, 1.356485e-001, 5.812792e-001, -5.073865e-001, 2.675490e-001, -1.095144e+000, -2.442208e-001, 4.787687e-001, -2.707940e+000, 6.129627e-001, 7.213058e-001, -6.034254e-002, 2.798703e+000, 8.787214e-001, -1.062019e+000, -1.765309e-001, 5.423897e-001, 3.783099e+000, -5.007038e+000, 7.376299e-001, 3.034085e-001, 2.733411e+000, 6.555070e-001, // albedo 0, turbidity 6 -1.390263e+000, -5.185474e-001, -1.630741e+001, 1.654109e+001, -1.499201e-002, 5.661787e-001, 1.452544e-002, 3.046179e+000, 5.026700e-001, -1.935801e+000, -9.953289e-001, -1.483271e+000, 1.913745e+000, -2.518160e-002, 4.593343e-001, 4.285617e-002, 1.448437e+000, 4.509310e-001, -7.547378e-001, 2.590987e-002, 2.480507e+000, -2.271835e+000, -5.259620e-002, 9.001709e-001, -2.024986e-001, 4.958191e+000, 1.036940e+000, -1.157324e+000, -1.198742e-001, -1.440574e+000, 3.070751e-001, -1.807577e-001, 4.059237e-002, 6.210184e-001, 2.425946e+000, 3.828327e-001, -1.065566e+000, -3.139616e-001, 5.715306e-001, 8.053761e-001, 1.396364e-001, 4.009778e-001, 5.681033e-003, 1.354013e+000, 7.861375e-001, -1.095972e+000, -2.178745e-001, 4.681537e-001, 1.235458e-001, -1.084613e+000, 1.006455e+000, 2.754677e-001, 2.239616e+000, 6.954839e-001, // albedo 0, turbidity 7 -1.453150e+000, -5.790574e-001, -1.243832e+001, 1.263425e+001, -1.892784e-002, 4.979177e-001, 1.035899e-002, 2.982682e+000, 5.056256e-001, -1.925518e+000, -1.010928e+000, 1.513827e+000, -9.219873e-001, -3.776925e-002, 4.692652e-001, 4.083023e-002, 1.303495e+000, 4.245150e-001, -1.134311e+000, -2.754710e-001, -2.443212e-001, 3.845396e-002, -1.074645e-001, 1.066657e+000, -2.324557e-001, 4.996897e+000, 1.052268e+000, -8.094396e-001, 1.096826e-001, -5.117072e-001, -1.915992e-001, -1.991693e-001, -5.943341e-001, 6.791986e-001, 1.332014e+000, 3.606306e-001, -1.227889e+000, -4.522793e-001, 5.338266e-002, 1.074118e+000, 8.733709e-002, 1.005448e+000, -1.725176e-002, 1.326110e+000, 8.063751e-001, -1.065450e+000, -2.160134e-001, 3.413994e-001, 4.950303e-001, -1.077199e+000, 3.654185e-001, 3.125819e-001, 1.998536e+000, 6.865917e-001, // albedo 0, turbidity 8 -1.594869e+000, -7.366760e-001, -1.252117e+001, 1.275030e+001, -1.697659e-002, 4.892543e-001, 2.831848e-003, 2.542039e+000, 5.457358e-001, -1.980952e+000, -9.910920e-001, 6.178699e+000, -5.888582e+000, -3.099336e-002, 3.859266e-001, 4.511764e-002, 1.839601e+000, 2.791527e-001, -1.766081e+000, -8.995150e-001, -2.712687e+000, 3.263201e+000, -1.840688e-001, 1.305410e+000, -2.675879e-001, 3.647246e+000, 1.168203e+000, -3.742071e-001, 4.678023e-001, 6.371403e-002, -2.016941e+000, -2.723239e-001, -1.446876e+000, 7.533604e-001, 1.131760e+000, 2.537537e-001, -1.380378e+000, -6.406403e-001, 7.018678e-001, 2.032023e+000, -2.393487e+000, 1.930827e+000, -1.260608e-001, 7.634327e-001, 8.870918e-001, -1.088465e+000, -2.971190e-001, 1.411657e-001, 1.879601e+000, -1.310304e+000, -7.045740e-001, 3.313185e-001, 1.264266e+000, 6.534482e-001, // albedo 0, turbidity 9 -2.229949e+000, -1.153733e+000, -7.505783e+000, 7.718722e+000, -2.407129e-002, 4.175820e-001, 4.559186e-005, 2.157318e+000, 6.337774e-001, -1.995509e+000, -8.778717e-001, 4.191031e+000, -3.968507e+000, -5.176872e-002, 1.960357e-001, 3.755797e-002, 1.975436e+000, 1.077053e-001, -3.174785e+000, -2.105130e+000, -2.062230e+000, 2.391786e+000, -4.217147e-002, 9.727297e-001, -1.540078e-001, 2.691773e+000, 1.235189e+000, 4.882832e-001, 1.097365e+000, -1.866214e-001, -1.567231e+000, -1.216396e+000, -4.391280e-001, 4.541998e-001, 1.167636e+000, 3.003642e-001, -1.709118e+000, -9.374505e-001, 6.559000e-001, 3.977860e+000, -3.525762e+000, 6.202828e-001, 7.863257e-002, 6.882512e-001, 8.161696e-001, -9.999977e-001, -2.777886e-001, 9.586687e-003, 1.766813e+000, -1.065121e+000, -1.325963e-001, 2.512239e-001, 1.055043e+000, 6.874661e-001, // albedo 0, turbidity 10 -2.932652e+000, -1.609416e+000, -3.825171e+000, 3.969752e+000, -3.638195e-002, 3.557402e-001, -4.379735e-006, 1.927804e+000, 7.278380e-001, -1.591732e+000, -7.579896e-001, 1.711976e+000, -1.369988e+000, -1.107557e-001, 1.237841e-001, 1.548121e-002, 2.024749e+000, -4.315379e-002, -6.085760e+000, -3.429651e+000, -6.780006e-001, -1.902709e-002, 6.566034e-002, 8.329946e-001, -1.012845e-001, 2.617589e+000, 1.342663e+000, 1.335204e+000, 1.035931e+000, -1.008915e+000, 5.915758e-001, -1.907371e+000, -3.568938e-002, 3.295382e-001, 6.546480e-001, 2.435447e-001, -1.800155e+000, -1.010684e+000, 1.160290e+000, 5.269190e+000, -3.895543e+000, 5.274946e-002, 3.971324e-002, 8.769492e-002, 8.252336e-001, -9.843476e-001, -3.014031e-001, -3.167912e-001, 1.384556e+000, -6.881572e-001, 5.617519e-002, 2.805263e-001, 9.930291e-001, 6.783964e-001, // albedo 1, turbidity 1 -1.257325e+000, -3.441598e-001, -5.951667e+000, 6.530618e+000, -5.773033e-002, 6.437990e-001, 8.453838e-003, 3.657343e+000, 5.329715e-001, -1.346061e+000, -4.331978e-001, -1.749638e+000, 2.263845e+000, -1.013807e-001, 3.755084e-001, 5.287214e-002, 3.402954e+000, 3.874047e-001, -1.073983e+000, -1.372222e-001, 2.840388e+000, -2.826616e+000, -1.866609e-001, 1.054193e+000, -8.989038e-002, 5.604984e+000, 6.739811e-001, -1.184707e+000, -3.992543e-001, 7.374377e-001, 1.479838e+000, -7.263903e-001, 1.133619e+000, 1.199206e-001, -4.232702e+000, 1.060412e+000, -1.021623e+000, -8.422241e-002, 1.032293e+000, -4.460168e-001, 3.941239e-001, 1.219939e+000, -1.420884e-001, 5.772239e+000, 5.623142e-001, -1.087791e+000, -1.754873e-001, 1.178006e+000, 9.386850e-002, -4.893184e+000, 1.162164e+000, 1.535543e-001, 2.607460e+000, 4.997706e-001, // albedo 1, turbidity 2 -1.251295e+000, -3.651612e-001, -9.950987e+000, 1.058444e+001, -3.065334e-002, 5.979560e-001, 1.817303e-002, 3.132460e+000, 5.458738e-001, -1.374134e+000, -5.079738e-001, 2.333109e+000, -1.251359e+000, -7.802080e-002, 3.182768e-001, 3.746599e-002, 1.963940e+000, 2.733180e-001, -9.862389e-001, -2.441831e-002, 2.657376e-001, -1.054016e+000, -8.576871e-002, 7.356127e-001, -4.711349e-002, 6.677884e+000, 1.206629e+000, -1.140461e+000, -3.212487e-001, 1.547332e+000, 9.031281e-001, -8.421239e-001, 1.166595e+000, 1.643076e-001, -2.534096e+000, 1.884034e-001, -1.049493e+000, -1.256523e-001, 1.205849e+000, -3.649526e-001, 8.075413e-001, 3.421308e-001, -1.173508e-001, 4.535809e+000, 9.497555e-001, -1.063961e+000, -1.336751e-001, 1.173271e+000, 1.016777e-001, -4.093576e+000, 4.559998e-001, 1.519017e-001, 4.153208e+000, 5.324846e-001, // albedo 1, turbidity 3 -1.271751e+000, -3.837936e-001, -1.052025e+001, 1.102826e+001, -2.411879e-002, 5.019991e-001, 3.094786e-002, 3.138107e+000, 5.059631e-001, -1.472034e+000, -6.259760e-001, -5.356154e-001, 1.713500e+000, -6.089970e-002, 4.750716e-001, 6.622428e-003, 1.224931e+000, 4.198087e-001, -8.587401e-001, 1.099859e-001, 3.258521e-001, -1.301658e+000, -4.452458e-002, 6.461336e-001, -2.947489e-002, 7.603712e+000, 1.091511e+000, -1.221875e+000, -3.659269e-001, 9.953072e-001, 8.481237e-001, -5.952235e-001, 1.016442e+000, 2.259940e-001, -1.925411e+000, 3.654292e-001, -1.008105e+000, -1.136472e-001, 1.248935e+000, -3.865165e-001, 1.714619e+000, -1.216223e-001, -2.436842e-002, 4.227455e+000, 7.030495e-001, -1.082262e+000, -1.513279e-001, 1.052383e+000, 2.125686e-001, -5.028093e-001, 8.694047e-001, 1.099128e-001, 3.634467e+000, 7.206727e-001, // albedo 1, turbidity 4 -1.310438e+000, -4.332417e-001, -2.812457e+001, 2.859054e+001, -7.241887e-003, 4.123186e-001, 2.839263e-002, 2.866138e+000, 5.063521e-001, -1.598864e+000, -7.787419e-001, 4.189377e+000, -3.122921e+000, -1.896105e-002, 6.071985e-001, 1.999660e-002, 7.039076e-001, 4.125456e-001, -7.834866e-001, 1.890740e-001, 1.102853e+000, -1.842558e+000, -3.985000e-002, 6.423282e-001, -1.131231e-001, 7.222493e+000, 1.177285e+000, -1.244910e+000, -3.668018e-001, -2.083168e-001, 1.051092e+000, -1.483362e-001, 4.066210e-001, 4.623360e-001, -1.971682e-001, 2.178890e-001, -1.010078e+000, -1.593623e-001, 1.747411e+000, -6.961852e-002, -1.503091e-001, 5.439839e-001, -1.874287e-001, 2.074758e+000, 9.133302e-001, -1.086611e+000, -1.529597e-001, 4.548984e-001, 2.836062e-001, 4.168066e-001, 3.953841e-001, 2.451427e-001, 3.799065e+000, 6.288711e-001, // albedo 1, turbidity 5 -1.338369e+000, -4.683873e-001, -3.858110e+001, 3.898823e+001, -5.111812e-003, 4.638476e-001, 2.389163e-002, 2.774207e+000, 5.242274e-001, -1.785780e+000, -9.773633e-001, 6.470331e+000, -5.147348e+000, -1.593592e-002, 4.175720e-001, 2.497956e-002, 7.090702e-002, 3.252744e-001, -6.972735e-001, 2.786524e-001, 4.011350e-003, -1.686706e+000, -4.966516e-003, 8.368703e-001, -1.225606e-001, 7.731542e+000, 1.267577e+000, -1.307129e+000, -4.728119e-001, 2.639424e-002, 2.633155e+000, -2.357439e-001, 1.263362e-001, 4.765765e-001, -2.025027e+000, 1.705113e-001, -9.583414e-001, -7.928834e-002, 1.447497e+000, -2.797571e+000, 8.553597e-001, 4.842942e-001, -7.727878e-002, 3.765006e+000, 9.191738e-001, -1.114040e+000, -2.132678e-001, 1.030931e+000, 2.871507e+000, -5.013319e+000, 2.699945e-001, 1.819978e-001, 2.239642e+000, 6.539653e-001, // albedo 1, turbidity 6 -1.393024e+000, -5.200008e-001, -1.941271e+001, 1.986171e+001, -1.212818e-002, 5.019138e-001, 7.897163e-003, 2.696459e+000, 5.258316e-001, -1.831466e+000, -1.018106e+000, 3.204932e+000, -2.139369e+000, -2.441969e-002, 3.191029e-001, 5.563321e-002, 1.320760e-001, 3.265220e-001, -7.994553e-001, 1.337239e-001, -1.563712e+000, 7.392042e-001, -3.136373e-002, 1.008208e+000, -1.988762e-001, 6.626579e+000, 1.223213e+000, -1.159543e+000, -2.836180e-001, 1.057464e+000, -3.647533e-001, -2.513115e-001, -1.995636e-001, 5.943224e-001, -4.865436e-001, 2.279895e-001, -1.044528e+000, -2.152538e-001, 1.023157e+000, 5.599579e-002, 6.321805e-001, 5.155639e-001, -1.111252e-001, 2.282270e+000, 8.647371e-001, -1.092518e+000, -1.865821e-001, 1.057856e+000, 3.491427e-001, -2.631526e+000, 3.584288e-001, 2.191649e-001, 2.389704e+000, 6.765946e-001, // albedo 1, turbidity 7 -1.384989e+000, -5.305700e-001, -1.459855e+001, 1.497673e+001, -1.471976e-002, 4.569028e-001, 5.419006e-003, 2.735360e+000, 5.389891e-001, -2.086660e+000, -1.234696e+000, 2.053196e+000, -1.257012e+000, -2.129117e-002, 1.990309e-001, 8.511032e-002, -1.312659e-001, 2.800139e-001, -7.309069e-001, 1.413931e-001, -1.773938e-001, 2.938820e-001, -4.933601e-002, 1.496853e+000, -3.213358e-001, 6.305852e+000, 1.298086e+000, -1.203529e+000, -3.216432e-001, -1.458970e-001, -5.598789e-001, -2.934068e-001, -1.206192e+000, 7.793654e-001, -9.223710e-001, 1.229360e-001, -1.002538e+000, -1.984480e-001, 1.233954e+000, 8.779171e-001, 3.133737e-001, 1.311239e+000, -2.132532e-001, 2.223702e+000, 9.461065e-001, -1.123572e+000, -2.342682e-001, 9.679089e-001, -1.017991e-003, -1.960819e+000, -1.153680e-001, 2.843114e-001, 1.779831e+000, 6.400916e-001, // albedo 1, turbidity 8 -1.537393e+000, -6.924151e-001, -1.239252e+001, 1.285585e+001, -1.666284e-002, 4.429862e-001, 2.398230e-003, 2.210714e+000, 5.509453e-001, -1.817841e+000, -9.662082e-001, 6.281905e+000, -5.778709e+000, -3.131226e-002, 3.074609e-001, 4.530074e-002, 1.409838e+000, 2.538213e-001, -1.790530e+000, -8.332867e-001, -2.605975e+000, 3.383959e+000, -1.685493e-001, 1.307568e+000, -2.569465e-001, 3.272862e+000, 1.247743e+000, -3.808658e-001, 3.525732e-001, 3.897535e-001, -2.085715e+000, -1.845614e-001, -1.470598e+000, 7.033938e-001, 8.475130e-001, 1.758974e-001, -1.374360e+000, -5.517879e-001, 1.276626e+000, 1.821209e+000, -2.480880e+000, 1.866494e+000, -1.649246e-001, 6.333864e-001, 9.339444e-001, -1.024167e+000, -2.097189e-001, 8.424991e-001, 1.767689e+000, -1.312031e+000, -8.191386e-001, 2.156968e-001, 1.201032e+000, 6.593457e-001, // albedo 1, turbidity 9 -2.190652e+000, -1.106580e+000, -7.466636e+000, 7.752518e+000, -2.263662e-002, 4.154878e-001, -1.646586e-006, 2.076563e+000, 6.322611e-001, -1.972368e+000, -8.108244e-001, 4.233742e+000, -3.927321e+000, -5.152609e-002, 2.005285e-001, 2.985984e-002, 1.903602e+000, 1.099985e-001, -3.148093e+000, -2.033135e+000, -2.019650e+000, 2.409779e+000, -1.255187e-002, 9.697956e-001, -1.538080e-001, 2.617071e+000, 1.234755e+000, 5.592882e-001, 1.073057e+000, -2.763735e-002, -1.563728e+000, -1.191791e+000, -4.331798e-001, 4.622361e-001, 1.142664e+000, 2.988891e-001, -1.706427e+000, -8.516236e-001, 1.014996e+000, 3.980336e+000, -3.487485e+000, 6.331985e-001, -1.818380e-002, 7.352340e-001, 8.452629e-001, -1.006197e+000, -1.932306e-001, 5.337019e-001, 1.797637e+000, -9.474717e-001, -1.353274e-001, 2.049954e-001, 1.156100e+000, 6.894153e-001, // albedo 1, turbidity 10 -2.473813e+000, -1.478132e+000, -3.492210e+000, 3.805303e+000, -3.251673e-002, 3.621052e-001, -6.447770e-006, 1.596383e+000, 8.551930e-001, -1.494464e+000, -7.635918e-001, 2.071212e+000, -1.536108e+000, -1.369345e-001, 1.287259e-001, 2.147844e-002, 1.753080e+000, -2.246103e-001, -6.305007e+000, -3.323156e+000, -7.099379e-001, 1.686111e-001, 1.080881e-001, 8.729732e-001, -1.291207e-001, 2.282989e+000, 1.475588e+000, 1.325532e+000, 5.765517e-001, -7.011257e-001, 7.720216e-001, -2.013560e+000, -1.990572e-001, 3.922685e-001, 9.898769e-003, 1.789360e-001, -1.590406e+000, -7.529646e-001, 1.930414e+000, 5.169169e+000, -4.221403e+000, 4.614858e-002, -9.527005e-002, -7.894472e-001, 8.458063e-001, -1.005785e+000, -2.286223e-001, 3.330253e-001, 1.438452e+000, -7.701349e-001, 2.780764e-002, 2.630698e-001, 8.329894e-001, 6.747408e-001, }; static float datasetRad480[] = { // albedo 0, turbidity 1 1.367487e-002, 1.998477e-002, -2.747378e-002, 2.012913e-001, 1.065803e-001, 1.249226e-001, // albedo 0, turbidity 2 1.319623e-002, 2.233282e-002, -3.838862e-002, 2.216885e-001, 1.032539e-001, 1.308019e-001, // albedo 0, turbidity 3 1.265118e-002, 2.391819e-002, -4.721677e-002, 2.352182e-001, 1.174476e-001, 1.303906e-001, // albedo 0, turbidity 4 1.204726e-002, 2.745130e-002, -6.437791e-002, 2.605947e-001, 1.298129e-001, 1.378516e-001, // albedo 0, turbidity 5 1.125691e-002, 3.031033e-002, -7.856070e-002, 2.797308e-001, 1.411425e-001, 1.486601e-001, // albedo 0, turbidity 6 1.087451e-002, 3.134174e-002, -8.308676e-002, 2.793109e-001, 1.610134e-001, 1.502290e-001, // albedo 0, turbidity 7 1.035757e-002, 3.176437e-002, -8.486370e-002, 2.674373e-001, 1.974534e-001, 1.533206e-001, // albedo 0, turbidity 8 9.649434e-003, 3.087937e-002, -8.067259e-002, 2.353243e-001, 2.553337e-001, 1.608814e-001, // albedo 0, turbidity 9 8.869346e-003, 2.627497e-002, -5.891488e-002, 1.570602e-001, 3.504762e-001, 1.724148e-001, // albedo 0, turbidity 10 8.105360e-003, 1.756907e-002, -2.001928e-002, 3.536541e-002, 4.692392e-001, 1.926373e-001, // albedo 1, turbidity 1 1.531497e-002, 2.090118e-002, -1.665041e-002, 1.626765e-001, 2.602854e-001, 2.739350e-001, // albedo 1, turbidity 2 1.500055e-002, 2.258405e-002, -2.517423e-002, 1.780058e-001, 2.604774e-001, 2.803331e-001, // albedo 1, turbidity 3 1.435727e-002, 2.473634e-002, -3.651251e-002, 1.966627e-001, 2.645889e-001, 2.894029e-001, // albedo 1, turbidity 4 1.368791e-002, 2.602874e-002, -4.462666e-002, 2.008996e-001, 2.978971e-001, 2.872899e-001, // albedo 1, turbidity 5 1.298035e-002, 2.709110e-002, -5.084570e-002, 2.010066e-001, 3.257828e-001, 2.917322e-001, // albedo 1, turbidity 6 1.267531e-002, 2.752851e-002, -5.364450e-002, 1.962715e-001, 3.472458e-001, 2.928354e-001, // albedo 1, turbidity 7 1.200196e-002, 2.782022e-002, -5.449978e-002, 1.818445e-001, 3.795420e-001, 2.974612e-001, // albedo 1, turbidity 8 1.115769e-002, 2.603247e-002, -4.606362e-002, 1.383509e-001, 4.427481e-001, 2.969281e-001, // albedo 1, turbidity 9 1.034375e-002, 2.111036e-002, -2.502615e-002, 6.215948e-002, 5.253192e-001, 2.999927e-001, // albedo 1, turbidity 10 9.270257e-003, 1.252950e-002, 1.085115e-002, -5.004679e-002, 6.169243e-001, 3.053035e-001, }; static float dataset520[] = { // albedo 0, turbidity 1 -1.171338e+000, -2.379456e-001, -6.515446e+000, 7.133235e+000, -5.382867e-002, 6.889982e-001, 4.250983e-002, 4.471437e+000, 5.087463e-001, -1.193029e+000, -2.445141e-001, -4.311723e-001, 1.019354e+000, -1.281643e-001, 7.837279e-001, 2.609613e-002, 5.965800e+000, 4.381607e-001, -1.165299e+000, -2.503239e-001, 3.829843e+000, -2.234083e+000, -4.693988e-001, 1.045109e+000, -6.241707e-002, 2.623310e-001, 7.500398e-001, -1.077288e+000, -2.659342e-001, -7.565678e-002, 1.145086e+000, -2.316655e-002, 1.564941e+000, 9.375322e-002, -7.476929e-001, 6.076913e-001, -1.075530e+000, -1.232648e-001, 1.877081e+000, -1.186427e-001, -2.748628e+000, 1.249377e+000, -1.085780e-001, 3.838331e+000, 8.601227e-001, -1.067002e+000, -1.572453e-001, 1.350156e+000, 3.140948e-003, -3.277283e+000, 1.488404e+000, 1.127058e-001, 2.655730e+000, 4.999138e-001, // albedo 0, turbidity 2 -1.175145e+000, -2.454528e-001, -8.173280e+000, 8.622722e+000, -3.895019e-002, 6.739096e-001, 6.622835e-002, 4.450872e+000, 5.061382e-001, -1.226543e+000, -2.979950e-001, 3.102814e+000, -2.662701e+000, -1.012309e-001, 5.142095e-001, 4.939276e-002, 5.007851e+000, 4.179865e-001, -1.075743e+000, -1.267529e-001, 1.017884e-001, 4.839556e-001, -4.025119e-001, 1.120466e+000, -5.059103e-002, 3.601070e+000, 1.104232e+000, -1.104008e+000, -2.079352e-001, 1.094572e+000, 1.147058e+000, -1.516726e-001, 1.526097e+000, 1.922554e-001, 4.060614e-001, 2.975787e-001, -1.080135e+000, -1.942481e-001, 1.409056e+000, -3.800384e+000, -7.125701e+000, 9.731220e-001, -7.312793e-002, 2.377810e+000, 9.223131e-001, -1.066280e+000, -1.421591e-001, 1.272936e+000, 7.891881e+000, -3.626975e+000, 1.294678e+000, 1.331475e-001, 2.986127e+000, 5.316962e-001, // albedo 0, turbidity 3 -1.210057e+000, -2.827640e-001, -5.179186e+000, 5.514430e+000, -5.638504e-002, 6.656727e-001, 5.417868e-002, 4.216550e+000, 5.495231e-001, -1.311087e+000, -3.921139e-001, 1.436554e+000, -7.051260e-001, -1.462714e-001, 2.604620e-001, 5.771570e-002, 3.493766e+000, 5.041164e-001, -9.705912e-001, -4.316197e-002, 5.357225e-001, -1.399982e+000, -3.407923e-001, 1.585242e+000, -6.423039e-002, 5.338193e+000, 9.835385e-001, -1.177697e+000, -1.893604e-001, -5.207247e-002, 4.572666e+000, -5.523178e-001, 2.677765e-001, 3.872768e-001, 1.978123e+000, 4.095974e-001, -1.029420e+000, -2.105096e-001, 1.657176e+000, -1.028655e+001, -7.725428e+000, 1.707122e+000, -7.681108e-002, 1.074660e+000, 8.312794e-001, -1.082084e+000, -1.321893e-001, 8.487219e-001, 1.858290e+001, -3.172656e+000, 6.915801e-001, 1.905927e-001, 3.901473e+000, 6.144141e-001, // albedo 0, turbidity 4 -1.259854e+000, -3.329630e-001, -2.270176e+000, 2.357599e+000, -9.019414e-002, 5.779792e-001, 7.706039e-002, 3.971905e+000, 4.999172e-001, -1.413220e+000, -5.430979e-001, -1.715627e-001, 1.151561e+000, -2.318489e-001, 2.791441e-001, 1.306646e-002, 1.794583e+000, 6.167457e-001, -9.926840e-001, 2.303697e-002, 7.306051e-001, -2.124879e+000, -2.221853e-001, 1.635982e+000, -8.684297e-002, 7.621636e+000, 9.443863e-001, -1.113409e+000, -2.409045e-001, -1.979662e-001, 5.089736e+000, -2.071840e+000, -6.954891e-001, 5.966469e-001, -1.346819e+000, 3.752080e-001, -1.055595e+000, -1.703680e-001, 1.089771e+000, -1.041463e+001, -4.687545e+000, 2.149733e+000, -1.118987e-001, 3.558810e+000, 8.741214e-001, -1.070779e+000, -1.445161e-001, 6.385947e-001, 1.695445e+001, -3.724275e+000, -3.465499e-002, 3.645376e-001, 3.232410e+000, 6.285788e-001, // albedo 0, turbidity 5 -1.297812e+000, -3.805039e-001, -1.474455e+000, 1.558382e+000, -1.292485e-001, 5.206238e-001, 7.166147e-002, 3.651150e+000, 4.998781e-001, -1.680599e+000, -8.036751e-001, 8.267015e-001, -2.109200e-001, -4.326451e-001, 3.843930e-001, 5.207142e-002, 6.938520e-001, 4.752346e-001, -8.467684e-001, 1.620743e-001, -5.520307e-001, 8.293798e-001, 8.728132e-001, 9.075147e-001, -1.734859e-001, 7.815672e+000, 1.126843e+000, -1.182658e+000, -3.290773e-001, 1.442907e-001, -1.705529e+000, -1.186174e+001, -1.903040e-001, 7.826049e-001, -1.497409e+000, 2.238945e-001, -1.032316e+000, -1.590425e-001, 9.289968e-001, 1.217091e+001, 1.274690e+000, 1.400296e+000, -3.047612e-001, 2.805729e+000, 9.198989e-001, -1.073060e+000, -1.623303e-001, 3.798836e-001, 2.223272e+000, -4.660805e+000, -1.172357e-001, 5.306455e-001, 3.105520e+000, 6.420864e-001, // albedo 0, turbidity 6 -1.374072e+000, -4.453408e-001, -1.081601e+000, 1.104314e+000, -1.730612e-001, 5.074812e-001, 5.784588e-002, 3.488150e+000, 5.037112e-001, -1.704606e+000, -8.629255e-001, -3.905040e-001, 2.152742e+000, -6.716606e-001, 5.638527e-001, -5.967161e-003, 4.886292e-001, 4.385432e-001, -9.651511e-001, 1.186522e-001, 3.421397e-001, -4.626814e+000, 9.716770e-001, 7.579588e-001, -1.064476e-002, 8.154392e+000, 1.103676e+000, -1.067172e+000, -3.214506e-001, -3.934660e-001, 9.254630e+000, -3.599603e+000, -1.624031e-001, 5.478446e-001, -2.781628e+000, 2.905848e-001, -1.063218e+000, -1.412572e-001, 8.153795e-001, -1.467486e+001, -2.020170e+000, 1.094685e+000, 7.786265e-002, 3.719129e+000, 8.826899e-001, -1.070058e+000, -1.684172e-001, 2.225147e-001, 2.345795e+001, -4.342429e+000, -4.661816e-002, 3.545794e-001, 3.051769e+000, 6.567686e-001, // albedo 0, turbidity 7 -1.397244e+000, -4.874379e-001, -2.217129e+000, 2.415780e+000, -1.039290e-001, 5.444596e-001, 2.296795e-002, 3.242776e+000, 5.575920e-001, -1.943117e+000, -1.042293e+000, 1.936194e+000, -7.807718e-001, -4.753317e-001, 6.351817e-001, 3.357824e-002, 3.221570e-001, 2.277390e-001, -1.007469e+000, 4.283560e-002, -1.830583e+000, -1.613949e-001, 5.103059e-001, 1.830881e-001, -6.111472e-002, 7.698471e+000, 1.322151e+000, -9.885823e-001, -2.796329e-001, 9.017585e-001, 9.500529e-001, -8.751757e+000, 5.198673e-001, 6.111910e-001, -3.165369e+000, 1.193651e-001, -1.105054e+000, -1.835801e-001, 2.099263e-001, 3.626436e+000, 4.241807e-001, 2.861915e-002, -3.245808e-002, 3.560209e+000, 9.581069e-001, -1.061783e+000, -1.955111e-001, 3.405765e-001, 1.682185e+001, -4.868111e+000, 3.591669e-001, 3.518670e-001, 2.163473e+000, 6.425305e-001, // albedo 0, turbidity 8 -1.452178e+000, -5.662818e-001, -1.492883e+000, 1.742373e+000, -1.894966e-001, 6.129524e-001, 2.370115e-006, 3.042560e+000, 7.988979e-001, -2.146318e+000, -1.176122e+000, 1.480664e+000, 1.846814e-001, -9.003192e-001, 2.819986e-001, -6.858291e-003, 5.447940e-001, -2.109028e-001, -1.465359e+000, -3.055025e-001, -1.747423e+000, -2.538335e+000, 6.082904e-001, 6.523133e-001, 1.426957e-001, 6.921276e+000, 1.637843e+000, -7.135462e-001, -2.351046e-001, 1.111445e+000, 2.259275e+000, -7.853810e+000, -3.006083e-001, 3.100486e-001, -4.047366e+000, -3.732308e-002, -1.188030e+000, -2.177467e-001, 8.022451e-002, 8.746107e+000, -6.824017e-001, 5.968181e-001, 7.024883e-002, 3.164998e+000, 9.909158e-001, -1.038065e+000, -1.989059e-001, 1.630845e-001, 1.261969e+001, -4.006594e+000, -3.213161e-001, 3.948313e-001, 2.040063e+000, 6.364874e-001, // albedo 0, turbidity 9 -1.789980e+000, -8.450140e-001, -2.591234e+000, 2.769295e+000, -8.338896e-002, 5.620741e-001, -8.271253e-006, 2.531602e+000, 9.001159e-001, -1.468080e+000, -7.426812e-001, 2.369441e+000, -1.635443e+000, -3.560365e-001, 2.130482e-001, -2.124886e-003, 1.863478e+000, -3.426455e-001, -3.911974e+000, -1.873182e+000, -2.428294e+000, 1.019786e+000, 2.178584e-001, 9.599962e-001, 3.763471e-002, 4.121844e+000, 1.708236e+000, 5.986629e-001, 4.160930e-001, 1.499968e+000, -4.234635e+000, -7.153272e+000, -8.777277e-001, 4.276508e-001, -2.268730e+000, -9.278595e-002, -1.581111e+000, -5.414559e-001, 3.449756e-002, 2.095624e+001, -1.717086e+000, 6.913385e-001, -1.227380e-001, 1.401315e+000, 9.723511e-001, -9.931334e-001, -2.191364e-001, 1.647201e-001, 2.954460e+000, -2.889774e+000, -4.261816e-001, 4.166838e-001, 1.370273e+000, 6.561021e-001, // albedo 0, turbidity 10 -2.368520e+000, -1.245557e+000, -3.473878e+000, 3.511922e+000, -4.076311e-002, 4.228576e-001, -8.136079e-006, 2.268992e+000, 9.001266e-001, -1.498984e+000, -9.483364e-001, 2.970418e+000, -2.003511e+000, -3.005171e-001, 3.242320e-001, 6.724107e-003, 1.693927e+000, -2.648941e-001, -6.258071e+000, -2.616781e+000, -3.186408e+000, -3.570416e-002, 5.972101e-001, 5.638927e-001, -8.227073e-002, 3.805214e+000, 1.486701e+000, 7.183470e-001, -1.332710e-001, 1.495243e+000, 3.859652e+000, -5.605361e+000, 3.808435e-001, 4.998100e-001, -1.207866e+000, 1.082917e-001, -1.422091e+000, -5.984032e-001, 2.297508e-001, 1.726780e+000, -6.684454e-001, -1.024912e+000, -1.967199e-001, -3.214571e-001, 8.922300e-001, -1.018798e+000, -2.003211e-001, 5.344788e-002, 1.474717e+001, -4.025558e+000, 9.010150e-001, 3.605184e-001, 1.504726e+000, 6.720300e-001, // albedo 1, turbidity 1 -1.150179e+000, -2.233430e-001, -6.725138e+000, 7.601675e+000, -6.176639e-002, 7.963802e-001, 2.476816e-002, 4.311811e+000, 5.070506e-001, -1.184017e+000, -2.330060e-001, 1.903877e-001, 4.425206e-001, -1.173330e-001, 2.459899e-001, 6.799957e-002, 5.710763e+000, 4.639162e-001, -1.129855e+000, -2.313999e-001, 3.299978e+000, -1.861830e+000, -3.626476e-001, 1.858194e+000, -9.845844e-002, 6.523143e-001, 6.278178e-001, -1.090030e+000, -2.445577e-001, 4.546659e-001, 9.848860e-001, -4.044981e-001, 3.532740e-001, 1.409977e-001, -7.724273e-001, 2.901711e-001, -1.048192e+000, -1.048720e-001, 2.079951e+000, -7.519850e-002, -1.451911e+000, 1.354243e+000, -1.508252e-001, 4.159135e+000, 8.685415e-001, -1.081709e+000, -1.496534e-001, 1.433416e+000, -8.415186e-005, -3.147387e+000, 6.964893e-002, 1.345400e-001, 3.372381e+000, 5.369835e-001, // albedo 1, turbidity 2 -1.163329e+000, -2.341078e-001, -8.084459e+000, 8.765664e+000, -4.227908e-002, 6.476384e-001, 5.575993e-002, 4.291594e+000, 5.023286e-001, -1.234281e+000, -3.038288e-001, 3.304120e+000, -2.565467e+000, -1.080261e-001, 5.183037e-001, 2.633070e-002, 4.459108e+000, 4.526356e-001, -1.015235e+000, -1.003890e-001, 2.834337e-001, 4.230399e-001, -4.060874e-001, 1.119918e+000, -2.357803e-002, 3.215664e+000, 1.089777e+000, -1.171497e+000, -2.465867e-001, 1.219344e+000, 1.184120e+000, -6.451707e-002, 1.087554e+000, 1.687897e-001, 4.111776e-001, 2.471485e-001, -1.010262e+000, -1.337460e-001, 1.953577e+000, -3.761183e+000, -7.089300e+000, 5.963565e-001, -8.297304e-002, 2.741114e+000, 9.771003e-001, -1.102719e+000, -1.647974e-001, 1.510508e+000, 7.573412e+000, -3.431528e+000, 3.953995e-001, 6.793657e-002, 2.744717e+000, 5.018037e-001, // albedo 1, turbidity 3 -1.186728e+000, -2.648685e-001, -7.540497e+000, 8.152868e+000, -4.363040e-002, 6.836829e-001, 3.221451e-002, 4.013046e+000, 6.004295e-001, -1.302626e+000, -3.904258e-001, 3.431819e+000, -2.975541e+000, -7.666020e-002, 2.464561e-002, 1.054528e-001, 3.161765e+000, 3.544185e-001, -9.615438e-001, -4.842098e-002, -4.756207e-001, 9.408081e-001, -3.108222e-001, 1.708814e+000, -1.241215e-001, 4.416567e+000, 1.207369e+000, -1.178731e+000, -1.824314e-001, 8.266664e-001, 1.001614e+000, 3.024332e-001, 3.291998e-002, 4.178949e-001, 2.532397e+000, 2.014902e-001, -1.018913e+000, -2.016682e-001, 2.132865e+000, -3.323938e+000, -8.751654e+000, 1.240780e+000, -1.801214e-001, 6.145479e-001, 9.457932e-001, -1.101603e+000, -1.521834e-001, 1.348807e+000, 5.640453e+000, -2.695953e+000, -7.496627e-002, 1.719606e-001, 3.175091e+000, 5.968939e-001, // albedo 1, turbidity 4 -1.229694e+000, -3.167126e-001, -3.548352e+000, 3.846155e+000, -5.028022e-002, 5.061677e-001, 7.498335e-002, 3.626295e+000, 4.999424e-001, -1.436439e+000, -5.562909e-001, 8.010070e-001, 3.290243e-001, -1.385772e-001, 4.556269e-002, 2.571935e-002, 1.623385e+000, 5.222220e-001, -8.876360e-001, 5.717281e-002, 4.713905e-001, -1.668970e+000, -3.199243e-001, 2.050582e+000, -7.783980e-002, 6.117601e+000, 1.070445e+000, -1.235363e+000, -2.778190e-001, 1.577638e-001, 3.982457e+000, -2.266885e-002, -1.411004e+000, 5.570462e-001, 1.740426e-001, 2.747952e-001, -9.785264e-001, -1.458813e-001, 1.996989e+000, -7.517409e+000, -6.602487e+000, 2.387711e+000, -1.996484e-001, 2.112759e+000, 9.289256e-001, -1.117781e+000, -1.699302e-001, 1.214480e+000, 1.141083e+001, -3.253445e+000, -8.156284e-001, 2.248021e-001, 2.860500e+000, 6.151694e-001, // albedo 1, turbidity 5 -1.290523e+000, -3.813116e-001, -6.728796e-001, 1.007366e+000, -2.068030e-001, 4.422499e-001, 6.016254e-002, 3.218056e+000, 5.068822e-001, -1.614452e+000, -7.953309e-001, 5.977485e-001, 1.056365e+000, -8.402403e-001, 3.713919e-001, 3.164720e-002, -2.526630e-001, 4.072481e-001, -8.377211e-001, 2.276878e-001, -3.232539e-001, -2.390300e+000, 2.127070e+000, 7.169058e-001, -4.032313e-002, 9.072383e+000, 1.188019e+000, -1.226600e+000, -4.426177e-001, 6.370202e-001, 3.846913e+000, -1.128719e+001, 3.667721e-002, 5.000027e-001, -4.192432e+000, 2.376054e-001, -9.852235e-001, -5.890324e-002, 1.529937e+000, 4.301220e+000, -1.839775e+000, 8.993504e-001, -1.040866e-001, 4.636528e+000, 8.466710e-001, -1.118112e+000, -2.040213e-001, 1.203227e+000, 7.252102e+000, -4.515955e+000, -2.398231e-001, 2.375855e-001, 1.923160e+000, 6.645269e-001, // albedo 1, turbidity 6 -1.330626e+000, -4.272516e-001, -1.317682e+000, 1.650847e+000, -1.192771e-001, 4.904191e-001, 4.074827e-002, 3.015846e+000, 5.271835e-001, -1.711989e+000, -8.644776e-001, 4.057135e-001, 9.037139e-001, -3.100084e-001, 6.317697e-002, 1.065625e-001, 9.226240e-002, 3.022474e-001, -8.465894e-001, 1.652715e-001, -2.532361e-001, -2.422693e+000, 3.144841e-001, 1.839347e+000, -2.818162e-001, 7.856667e+000, 1.387977e+000, -1.192114e+000, -3.830569e-001, 5.124751e-001, 7.280034e+000, -2.610477e+000, -1.832768e+000, 9.101904e-001, -3.349116e+000, -7.313079e-002, -1.011026e+000, -1.061217e-001, 1.357854e+000, -1.496195e+001, -2.180975e+000, 2.484329e+000, -3.239225e-001, 3.899425e+000, 1.179264e+000, -1.106228e+000, -1.927917e-001, 1.179701e+000, 2.379834e+001, -4.870211e+000, -1.290713e+000, 2.854422e-001, 2.078973e+000, 5.128625e-001, // albedo 1, turbidity 7 -1.342815e+000, -4.571984e-001, -1.803521e+000, 2.229578e+000, -1.196587e-001, 5.694038e-001, 1.194687e-002, 2.950110e+000, 5.961719e-001, -1.937297e+000, -1.078823e+000, 2.178495e+000, -1.251900e+000, -3.577875e-001, 2.553915e-001, 8.081142e-002, -4.723152e-001, 1.174551e-001, -9.292675e-001, 1.125551e-001, -1.708569e+000, 1.832840e+000, 5.150525e-001, 9.287322e-001, -1.746780e-001, 7.793815e+000, 1.498832e+000, -1.058850e+000, -3.495292e-001, 1.135259e+000, -4.069374e+000, -9.727412e+000, -7.670653e-001, 7.550431e-001, -4.105064e+000, -5.149354e-002, -1.079472e+000, -1.399984e-001, 1.058148e+000, 1.392667e+001, -6.245343e-001, 1.192083e+000, -2.578858e-001, 4.030723e+000, 1.025069e+000, -1.093159e+000, -2.150433e-001, 1.210946e+000, 3.349246e+000, -4.030345e+000, -5.362971e-001, 2.886842e-001, 1.192375e+000, 6.363049e-001, // albedo 1, turbidity 8 -1.408172e+000, -5.491538e-001, -1.360219e+000, 1.738150e+000, -1.505117e-001, 6.030014e-001, -6.866289e-006, 2.656101e+000, 9.001849e-001, -2.171702e+000, -1.231851e+000, 1.860400e+000, 3.613146e-002, -7.300078e-001, 1.974371e-001, -5.351202e-003, -1.443434e-001, -3.779605e-001, -1.284657e+000, -1.935945e-001, -1.494185e+000, -2.070689e+000, 2.974020e-001, 8.048383e-001, 1.097715e-001, 6.907960e+000, 1.819367e+000, -8.288598e-001, -3.374917e-001, 1.029011e+000, 1.347088e+000, -7.655126e+000, -8.232335e-001, 3.722934e-001, -4.847675e+000, -1.864913e-001, -1.146031e+000, -1.480097e-001, 1.051391e+000, 8.396865e+000, -1.407010e+000, 1.240651e+000, -3.942068e-002, 3.291458e+000, 1.060212e+000, -1.069599e+000, -2.047532e-001, 9.437765e-001, 1.189879e+001, -4.026750e+000, -9.372092e-001, 2.463501e-001, 1.782902e+000, 6.235027e-001, // albedo 1, turbidity 9 -1.793508e+000, -8.986075e-001, -2.346395e+000, 2.775625e+000, -7.052213e-002, 5.349215e-001, -7.457456e-006, 1.901248e+000, 9.001358e-001, -1.629402e+000, -8.273410e-001, 2.270930e+000, -1.125114e+000, -3.562854e-001, 1.948044e-001, 1.703882e-003, 1.426305e+000, -3.737234e-001, -3.443431e+000, -1.686429e+000, -1.515036e+000, -6.941862e-001, 4.976814e-001, 1.144483e+000, -4.277285e-002, 3.662107e+000, 1.819972e+000, 3.138150e-001, 2.426714e-001, 7.717995e-001, 2.759520e+000, -7.216077e+000, -1.389093e+000, 5.332838e-001, -2.316313e+000, -2.636593e-001, -1.449802e+000, -4.017798e-001, 1.133688e+000, 2.114337e+000, 6.227965e-002, 1.378688e+000, -1.759313e-001, 9.446579e-001, 1.165017e+000, -1.049420e+000, -2.614006e-001, 9.473363e-001, 1.531288e+001, -4.714989e+000, -8.992715e-001, 2.423509e-001, 9.148027e-001, 5.650972e-001, // albedo 1, turbidity 10 -2.382332e+000, -1.290760e+000, -3.316114e+000, 3.587059e+000, -3.748522e-002, 4.468493e-001, -7.212198e-006, 1.789208e+000, 9.001267e-001, -1.333339e+000, -9.355999e-001, 3.281313e+000, -2.263103e+000, -2.499164e-001, 1.591742e-001, 8.117981e-003, 1.345396e+000, -2.689053e-001, -6.612658e+000, -2.809230e+000, -2.744061e+000, 1.005261e+000, 4.216309e-001, 1.055067e+000, -9.021558e-002, 2.940833e+000, 1.495270e+000, 1.251113e+000, 5.915517e-002, 1.142846e+000, -2.807371e-001, -5.335452e+000, -6.967012e-001, 5.129558e-001, -5.264483e-001, 1.137786e-001, -1.517768e+000, -5.807447e-001, 1.179477e+000, 1.252252e+001, -2.305973e+000, 2.184822e-001, -3.092917e-001, -1.524373e+000, 8.724218e-001, -1.037889e+000, -2.065780e-001, 6.479897e-001, 4.786848e-002, -2.348244e+000, -3.053490e-002, 4.059549e-001, 1.313102e+000, 6.713422e-001, }; static float datasetRad520[] = { // albedo 0, turbidity 1 1.459826e-002, 1.539451e-002, -1.848659e-003, 1.563602e-001, 6.773320e-002, 9.272923e-002, // albedo 0, turbidity 2 1.433599e-002, 1.641988e-002, -1.010719e-002, 1.752844e-001, 7.101618e-002, 9.423920e-002, // albedo 0, turbidity 3 1.361165e-002, 2.045058e-002, -3.003054e-002, 2.142268e-001, 6.624853e-002, 1.021088e-001, // albedo 0, turbidity 4 1.263245e-002, 2.450953e-002, -5.278634e-002, 2.554090e-001, 7.442617e-002, 1.093243e-001, // albedo 0, turbidity 5 1.161553e-002, 2.837614e-002, -7.218472e-002, 2.860706e-001, 8.559036e-002, 1.183292e-001, // albedo 0, turbidity 6 1.106384e-002, 3.079241e-002, -8.377247e-002, 3.007502e-001, 9.584072e-002, 1.242989e-001, // albedo 0, turbidity 7 1.036501e-002, 3.253539e-002, -9.274680e-002, 3.036297e-001, 1.249370e-001, 1.307019e-001, // albedo 0, turbidity 8 9.469294e-003, 3.287197e-002, -9.329500e-002, 2.773078e-001, 1.866053e-001, 1.366498e-001, // albedo 0, turbidity 9 8.599754e-003, 2.901873e-002, -7.532574e-002, 2.032418e-001, 2.837623e-001, 1.499765e-001, // albedo 0, turbidity 10 7.760808e-003, 1.977285e-002, -3.328752e-002, 7.084295e-002, 4.155148e-001, 1.708600e-001, // albedo 1, turbidity 1 1.597952e-002, 1.790201e-002, -1.839686e-003, 1.470389e-001, 1.698205e-001, 2.119268e-001, // albedo 1, turbidity 2 1.553599e-002, 1.969270e-002, -1.173079e-002, 1.677871e-001, 1.714108e-001, 2.173300e-001, // albedo 1, turbidity 3 1.489601e-002, 2.206336e-002, -2.576017e-002, 1.949160e-001, 1.781909e-001, 2.236776e-001, // albedo 1, turbidity 4 1.384558e-002, 2.528945e-002, -4.419483e-002, 2.249469e-001, 1.968802e-001, 2.312108e-001, // albedo 1, turbidity 5 1.299228e-002, 2.767429e-002, -5.793193e-002, 2.409692e-001, 2.215448e-001, 2.384850e-001, // albedo 1, turbidity 6 1.245635e-002, 2.874175e-002, -6.384005e-002, 2.429023e-001, 2.428387e-001, 2.418906e-001, // albedo 1, turbidity 7 1.170787e-002, 3.001101e-002, -6.977107e-002, 2.368382e-001, 2.775809e-001, 2.482129e-001, // albedo 1, turbidity 8 1.081211e-002, 2.854760e-002, -6.360294e-002, 1.948047e-001, 3.501631e-001, 2.490269e-001, // albedo 1, turbidity 9 9.903541e-003, 2.416012e-002, -4.342521e-002, 1.140965e-001, 4.468771e-001, 2.561579e-001, // albedo 1, turbidity 10 8.793464e-003, 1.518177e-002, -4.699154e-003, -9.107614e-003, 5.554550e-001, 2.692918e-001, }; static float dataset560[] = { // albedo 0, turbidity 1 -1.121223e+000, -1.710187e-001, -1.383038e+001, 1.475343e+001, -3.137953e-002, 1.035662e+000, 4.060064e-002, 5.222551e+000, 5.001051e-001, -1.172565e+000, -1.880874e-001, 7.283594e+000, -5.774643e+000, -9.051333e-002, 9.108126e-001, -1.565410e-002, 6.194404e+000, 4.688599e-001, -1.124108e+000, -3.082835e-001, -2.179926e-001, 1.330167e+000, -4.502254e-001, 1.470140e+000, 4.202392e-004, -4.724308e+000, 1.134678e+000, -1.079809e+000, -9.226814e-002, 1.465364e+000, 1.348856e+000, 4.357794e-001, 1.771543e+000, 8.121383e-003, 6.057395e+000, 2.462141e-001, -1.086667e+000, -2.709889e-001, 2.249152e+000, -3.177505e+000, -7.138130e+000, 1.112553e+000, -9.718434e-003, -2.392239e+000, 9.352768e-001, -1.071154e+000, -1.272150e-001, 1.644374e+000, 4.326598e+000, -2.244682e+000, 1.611051e+000, 7.835546e-003, 3.213282e+000, 6.580432e-001, // albedo 0, turbidity 2 -1.133883e+000, -1.835049e-001, -1.232301e+001, 1.307796e+001, -3.760123e-002, 1.051162e+000, 3.392954e-002, 5.319376e+000, 6.501601e-001, -1.116119e+000, -1.457114e-001, 5.436576e+000, -5.114276e+000, -7.178414e-002, 2.658168e-001, 1.603756e-001, 7.619379e+000, 3.112698e-001, -1.215552e+000, -3.391607e-001, 4.502377e-001, 1.281602e+000, -4.095778e-001, 2.374058e+000, -1.988430e-001, -3.809377e+000, 1.254846e+000, -9.657094e-001, 3.858547e-002, 3.324554e-001, 1.541740e+000, 6.029572e-001, 2.346414e-001, 3.902458e-001, 7.263050e+000, 1.353991e-001, -1.152042e+000, -3.155103e-001, 2.163244e+000, -5.230832e+000, -7.443608e+000, 2.247834e+000, -1.632216e-001, -1.725315e+000, 1.034709e+000, -1.051862e+000, -1.310458e-001, 1.554942e+000, 1.063510e+001, -3.558989e+000, 6.764257e-001, 1.428912e-001, 2.541641e+000, 5.000389e-001, // albedo 0, turbidity 3 -1.156925e+000, -2.104634e-001, -1.793090e+001, 1.817524e+001, -1.225514e-002, 6.518753e-001, 1.085708e-001, 4.947239e+000, 5.635117e-001, -1.183783e+000, -2.187288e-001, 5.860654e+000, -5.643960e+000, -4.453459e-002, 6.724995e-001, 1.698133e-002, 6.742131e+000, 6.353553e-001, -1.143101e+000, -2.644541e-001, 9.354577e-001, 9.256854e-001, -1.074845e-001, 1.663131e+000, 4.998918e-002, -2.049721e+000, 8.150826e-001, -1.021102e+000, 2.478746e-002, -1.367363e+000, -9.011684e-002, -5.001730e-001, 4.316685e-002, 3.952231e-001, 8.084754e+000, 5.380131e-001, -1.101145e+000, -2.731481e-001, 2.483816e+000, 3.581780e-001, 4.249615e-001, 2.284087e+000, -5.836688e-002, -1.651434e+000, 7.685430e-001, -1.073863e+000, -1.705854e-001, 1.169673e+000, -2.183705e-003, -5.007439e+000, 2.318154e-001, 2.738714e-001, 2.187327e+000, 6.676882e-001, // albedo 0, turbidity 4 -1.207581e+000, -2.653224e-001, -9.004497e+000, 8.985720e+000, -9.024461e-003, 4.273132e-001, 1.378091e-001, 4.307648e+000, 5.309421e-001, -1.278614e+000, -3.516334e-001, 2.489304e+000, -1.840089e+000, -6.293646e-002, 8.426903e-001, -7.266949e-002, 4.434869e+000, 7.077739e-001, -1.150333e+000, -2.033123e-001, 8.150312e-001, -7.926382e-001, -3.230951e-001, 1.291679e+000, 1.822329e-001, 1.619133e+000, 7.522432e-001, -1.002248e+000, -3.092969e-002, -1.092273e+000, 2.820671e+000, 4.504455e-001, -5.121048e-001, 4.229688e-001, 4.037073e+000, 5.843543e-001, -1.087962e+000, -2.434172e-001, 1.817322e+000, -6.031774e+000, -4.873903e+000, 2.094606e+000, 1.184743e-001, 2.293346e-001, 7.283940e-001, -1.072272e+000, -1.614715e-001, 8.337136e-001, 1.086866e+001, -3.373042e+000, 2.260332e-002, 2.622468e-001, 2.470766e+000, 7.078601e-001, // albedo 0, turbidity 5 -1.263850e+000, -3.278851e-001, -5.336400e+000, 5.102832e+000, 2.070020e-003, 3.605369e-001, 1.633426e-001, 3.790121e+000, 4.999503e-001, -1.507623e+000, -6.465694e-001, -2.983753e+000, 4.212027e+000, -5.868795e-002, 3.852488e-001, -7.222995e-002, 1.042808e+000, 6.632120e-001, -1.041397e+000, 6.326589e-002, 3.860471e+000, -5.579882e+000, -1.730201e-001, 2.303753e+000, 6.102393e-002, 7.287763e+000, 8.916057e-001, -1.049861e+000, -2.836044e-001, -2.302537e+000, 6.724969e+000, 4.373598e-001, -2.422514e+000, 6.952438e-001, -2.633600e+000, 4.070954e-001, -1.054117e+000, -1.206625e-001, 1.764625e+000, -9.467716e+000, -3.436987e+000, 3.394707e+000, -8.149683e-002, 3.485918e+000, 8.515716e-001, -1.072517e+000, -1.574135e-001, 2.214599e-001, 1.331766e+001, -3.915381e+000, -1.229973e+000, 6.267275e-001, 2.923262e+000, 6.516824e-001, // albedo 0, turbidity 6 -1.293503e+000, -3.676147e-001, -1.323095e+001, 1.301713e+001, -3.471894e-004, 3.957986e-001, 1.317480e-001, 3.616827e+000, 4.998510e-001, -1.757697e+000, -8.202513e-001, 2.560133e+000, -1.337734e+000, -3.413795e-002, 5.633043e-001, -4.355758e-002, 7.324869e-001, 5.728008e-001, -8.814599e-001, 9.828960e-002, -2.701428e-001, -1.298657e+000, -6.721423e-002, 1.581675e+000, 4.095024e-002, 6.548913e+000, 9.726866e-001, -1.125663e+000, -2.625873e-001, -2.797592e-001, 2.848739e+000, -3.363778e-002, -1.672768e+000, 7.349952e-001, -1.708628e+000, 3.557813e-001, -1.044841e+000, -1.712889e-001, 7.091708e-001, -4.275119e+000, -7.565130e-001, 2.483873e+000, -7.781321e-002, 2.667776e+000, 8.709126e-001, -1.067360e+000, -1.543712e-001, 3.884866e-001, 6.915851e+000, -4.250734e+000, -6.525729e-001, 6.368377e-001, 2.671865e+000, 6.566986e-001, // albedo 0, turbidity 7 -1.360356e+000, -4.336026e-001, -1.442967e+001, 1.428579e+001, -3.990325e-003, 4.600126e-001, 1.023159e-001, 3.367805e+000, 4.999150e-001, -2.054147e+000, -1.064745e+000, -7.857491e-001, 2.214734e+000, -3.764113e-002, 8.504761e-001, -4.222958e-002, 1.091377e-001, 4.732161e-001, -8.953952e-001, 1.048085e-001, 1.481293e+000, -4.223012e+000, -4.164160e-002, 5.999023e-001, 6.310005e-002, 7.156883e+000, 1.066682e+000, -1.030251e+000, -2.777709e-001, -8.361086e-001, 5.611154e+000, 1.861240e-001, -5.823197e-001, 6.716210e-001, -3.269717e+000, 2.922029e-001, -1.095631e+000, -1.966849e-001, 6.300566e-001, -7.129591e+000, -7.351951e-001, 1.400340e+000, -6.997516e-003, 2.879018e+000, 8.879337e-001, -1.052935e+000, -1.551958e-001, 2.334578e-001, 1.040948e+001, -4.426381e+000, -3.477323e-001, 6.257070e-001, 2.451148e+000, 6.570737e-001, // albedo 0, turbidity 8 -1.382656e+000, -4.830539e-001, -1.107403e+001, 1.127854e+001, -2.723641e-002, 8.478005e-001, 2.907652e-003, 3.290364e+000, 7.398950e-001, -2.230895e+000, -1.163446e+000, -1.001991e+001, 1.125340e+001, -3.233871e-002, 3.041577e-001, 3.870458e-003, 3.463879e-001, -8.829082e-002, -1.489234e+000, -3.402035e-001, 2.948409e+000, -8.098077e+000, 9.078299e-002, -3.179835e-001, 4.730321e-001, 6.765707e+000, 1.440217e+000, -6.206234e-001, -1.701007e-001, -7.346357e-002, 9.350033e+000, 1.548964e-001, 1.313206e+000, -1.479143e-001, -5.119165e+000, 1.854277e-001, -1.226372e+000, -2.128299e-001, -1.643093e-001, -9.382334e+000, -4.857784e-001, -1.374948e-001, 5.877245e-001, 3.862307e+000, 8.700125e-001, -1.030598e+000, -1.931668e-001, 3.691403e-001, 1.066393e+001, -4.244968e+000, -5.872571e-002, 4.193140e-001, 1.461878e+000, 6.699478e-001, // albedo 0, turbidity 9 -1.606656e+000, -7.140209e-001, -1.149565e+001, 1.168427e+001, -2.245577e-002, 7.718953e-001, -8.349882e-006, 2.654449e+000, 9.001224e-001, -2.100494e+000, -1.013602e+000, -1.638934e+001, 1.729185e+001, -1.580924e-002, 5.038208e-002, -1.628735e-002, 1.762584e+000, -3.121794e-001, -3.228292e+000, -1.459508e+000, 7.424519e+000, -1.194272e+001, 4.931054e-002, 6.493074e-001, 3.590561e-001, 4.068321e+000, 1.613039e+000, 1.278814e-001, 4.010913e-002, -2.185675e+000, 1.164548e+001, 2.706306e-002, 1.632886e-001, -1.090111e-002, -3.342580e+000, 1.916992e-002, -1.400278e+000, -2.825658e-001, 4.168149e-001, -1.195909e+001, -1.122968e-002, 1.863328e-001, 4.263033e-001, 2.270053e+000, 9.748449e-001, -1.017511e+000, -2.884028e-001, 3.544996e-001, 1.535118e+001, -5.009184e+000, 1.511064e-001, 2.916578e-001, 7.889658e-001, 6.294910e-001, // albedo 0, turbidity 10 -2.031136e+000, -1.076357e+000, -8.660773e+000, 8.800317e+000, -2.370842e-002, 5.736027e-001, -8.441313e-006, 2.248669e+000, 9.001280e-001, -1.270967e+000, -7.828844e-001, -1.198232e+001, 1.262753e+001, -1.509989e-002, 1.663438e-001, 2.440939e-004, 2.068640e+000, -2.521574e-001, -6.600872e+000, -2.689874e+000, 6.453928e+000, -9.592747e+000, -3.551170e-002, 1.325662e+000, -1.894375e-002, 3.506163e+000, 1.469724e+000, 7.961323e-001, -1.989144e-001, -2.685238e+000, 1.034230e+001, 2.076702e-001, -7.692350e-001, 6.184894e-001, -1.969413e+000, 3.842922e-002, -1.459073e+000, -4.964034e-001, 1.060127e+000, -1.277712e+001, -9.634553e-001, 5.610879e-001, -2.034286e-001, 3.525910e-001, 1.003048e+000, -1.021565e+000, -2.553022e-001, 6.367571e-002, 2.028825e+001, -4.623219e+000, -2.400428e-002, 4.251423e-001, 9.640897e-001, 6.080298e-001, // albedo 1, turbidity 1 -1.121224e+000, -1.710171e-001, -1.383038e+001, 1.475343e+001, -3.137812e-002, 1.035662e+000, 4.060006e-002, 5.222551e+000, 5.001051e-001, -1.172565e+000, -1.880857e-001, 7.283595e+000, -5.774643e+000, -9.051285e-002, 9.108124e-001, -1.565627e-002, 6.194404e+000, 4.688599e-001, -1.124109e+000, -3.082816e-001, -2.179926e-001, 1.330167e+000, -4.502252e-001, 1.470140e+000, 4.158616e-004, -4.724308e+000, 1.134678e+000, -1.079810e+000, -9.226583e-002, 1.465364e+000, 1.348856e+000, 4.357794e-001, 1.771543e+000, 8.115381e-003, 6.057395e+000, 2.462140e-001, -1.086668e+000, -2.709863e-001, 2.249153e+000, -3.177505e+000, -7.138130e+000, 1.112553e+000, -9.724210e-003, -2.392239e+000, 9.352768e-001, -1.071158e+000, -1.272123e-001, 1.644374e+000, 4.326598e+000, -2.244682e+000, 1.611051e+000, 7.831866e-003, 3.213282e+000, 6.580432e-001, // albedo 1, turbidity 2 -1.125449e+000, -1.733403e-001, -1.228038e+001, 1.311695e+001, -3.541409e-002, 1.005494e+000, 4.147852e-002, 5.316886e+000, 6.051699e-001, -1.101273e+000, -1.422106e-001, 5.484715e+000, -5.089835e+000, -6.655928e-002, 2.076815e-001, 1.633101e-001, 7.624535e+000, 3.044941e-001, -1.213425e+000, -3.085010e-001, 5.550585e-001, 1.302798e+000, -3.946488e-001, 2.285152e+000, -1.925101e-001, -3.790065e+000, 1.263207e+000, -9.610579e-001, 9.458093e-003, 5.293256e-001, 1.553214e+000, 6.053752e-001, 1.172267e-001, 3.674690e-001, 7.305350e+000, 1.509544e-001, -1.119731e+000, -2.765693e-001, 2.433951e+000, -5.229810e+000, -7.449777e+000, 2.123304e+000, -2.242917e-001, -1.669115e+000, 1.041008e+000, -1.094324e+000, -1.418743e-001, 1.836224e+000, 1.063054e+001, -3.561209e+000, 5.916534e-001, 9.296571e-002, 2.600060e+000, 4.999316e-001, // albedo 1, turbidity 3 -1.155818e+000, -2.162981e-001, -2.560068e+001, 2.636088e+001, -1.382944e-002, 8.101983e-001, 4.709210e-002, 4.301909e+000, 6.416958e-001, -1.171460e+000, -1.866443e-001, 8.497645e+000, -8.396229e+000, -3.345417e-002, 2.960022e-001, 7.985279e-002, 7.420544e+000, 5.552152e-001, -1.114385e+000, -2.963805e-001, 5.955009e-002, 2.320529e+000, -7.649266e-002, 2.277940e+000, -5.942479e-002, -4.040964e+000, 9.588558e-001, -1.070647e+000, 4.194546e-002, -5.701942e-001, -1.001278e+000, -3.389615e-001, -8.559533e-001, 5.070784e-001, 9.805560e+000, 3.529747e-001, -1.057912e+000, -2.733753e-001, 3.080618e+000, 7.477366e-001, 3.484876e-001, 2.214994e+000, -2.597625e-001, -2.842961e+000, 9.178917e-001, -1.105636e+000, -1.815423e-001, 1.651373e+000, -2.553941e-003, -5.008441e+000, -6.378055e-001, 2.370503e-001, 1.890656e+000, 6.018255e-001, // albedo 1, turbidity 4 -1.194221e+000, -2.570801e-001, -8.919095e+000, 9.380192e+000, -2.650470e-002, 6.233645e-001, 6.663964e-002, 4.027438e+000, 6.125383e-001, -1.308216e+000, -3.781794e-001, 2.369107e+000, -1.977066e+000, -4.079773e-002, 1.443960e-001, 8.206719e-002, 3.465933e+000, 5.442867e-001, -1.048459e+000, -1.617720e-001, 1.015136e+000, -2.989579e-001, -2.764989e-001, 2.427990e+000, -1.147612e-001, 1.522921e+000, 1.041410e+000, -1.105796e+000, -4.826962e-002, -8.419705e-001, 3.285981e+000, 7.975109e-001, -1.954456e+000, 7.424696e-001, 4.604902e+000, 2.602059e-001, -1.033856e+000, -2.507382e-001, 2.882633e+000, -8.250912e+000, -6.878129e+000, 2.948966e+000, -2.850302e-001, -8.253849e-001, 9.844934e-001, -1.125219e+000, -1.879003e-001, 1.474838e+000, 1.453266e+001, -3.271910e+000, -1.231579e+000, 2.397524e-001, 1.654932e+000, 5.625696e-001, // albedo 1, turbidity 5 -1.246640e+000, -3.202274e-001, -6.355032e+000, 6.364143e+000, 9.028376e-004, 3.146975e-001, 1.550718e-001, 3.413749e+000, 4.999065e-001, -1.477471e+000, -5.819223e-001, 1.329471e+000, -2.694229e-001, -4.575905e-002, 5.087866e-001, -6.857139e-002, 1.810092e+000, 6.318693e-001, -1.046136e+000, -6.763679e-002, 6.725076e-001, -1.036786e+000, -3.192799e-001, 1.724205e+000, 6.468388e-002, 3.953855e+000, 9.417528e-001, -1.033910e+000, -1.295544e-001, -4.551294e-001, 2.659205e+000, 8.887235e-001, -1.733153e+000, 6.540117e-001, 8.046523e-001, 3.597443e-001, -1.094530e+000, -2.282012e-001, 2.298267e+000, -5.184881e+000, -6.122309e+000, 2.590799e+000, -1.618707e-001, 1.116033e+000, 8.867666e-001, -1.095556e+000, -1.807112e-001, 1.406193e+000, 8.120385e+000, -3.058239e+000, -1.121150e+000, 2.933606e-001, 1.488339e+000, 6.374827e-001, // albedo 1, turbidity 6 -1.270123e+000, -3.552595e-001, -8.975893e+000, 9.110080e+000, -3.388207e-003, 3.559109e-001, 1.201097e-001, 3.109904e+000, 4.998957e-001, -1.663376e+000, -7.846840e-001, 6.951405e-001, 3.139107e-001, -2.448004e-002, 3.572505e-001, 1.453572e-002, 6.307761e-001, 5.142914e-001, -9.518772e-001, 7.764573e-002, 1.247094e+000, -2.224855e+000, -1.195310e-001, 1.709581e+000, -8.836329e-002, 5.688916e+000, 1.113629e+000, -1.087154e+000, -2.665646e-001, -8.624251e-001, 4.536060e+000, 4.180650e-001, -1.629798e+000, 8.479560e-001, -1.293696e+000, 1.869693e-001, -1.064826e+000, -1.599892e-001, 2.285337e+000, -8.584887e+000, -3.074560e+000, 2.139459e+000, -2.592372e-001, 1.937577e+000, 9.957954e-001, -1.099622e+000, -1.849797e-001, 1.193609e+000, 1.416481e+001, -5.009527e+000, -8.592493e-001, 3.485606e-001, 1.884203e+000, 6.097274e-001, // albedo 1, turbidity 7 -1.344841e+000, -4.339942e-001, -9.193112e+000, 9.385864e+000, -9.742818e-003, 4.812040e-001, 7.690647e-002, 2.843801e+000, 5.228047e-001, -1.975928e+000, -1.042040e+000, 9.695714e-001, 3.718000e-001, -3.334078e-002, 1.333620e-001, 8.180282e-002, -1.652429e-001, 3.267010e-001, -8.651864e-001, 1.288722e-001, 6.811456e-001, -3.282787e+000, -9.074685e-002, 1.894059e+000, -1.849744e-001, 6.610614e+000, 1.322978e+000, -1.103780e+000, -3.279618e-001, -4.193802e-001, 7.331165e+000, 6.529659e-001, -2.227297e+000, 9.625482e-001, -3.348971e+000, -7.261722e-003, -1.055963e+000, -1.527328e-001, 1.786114e+000, -1.367578e+001, -3.450729e+000, 2.641691e+000, -3.229222e-001, 2.800131e+000, 1.129409e+000, -1.111541e+000, -2.123518e-001, 1.286159e+000, 2.297563e+001, -4.591526e+000, -1.374672e+000, 3.462811e-001, 1.071127e+000, 5.498514e-001, // albedo 1, turbidity 8 -1.387544e+000, -4.964558e-001, -9.744778e+000, 1.014533e+001, -2.463089e-002, 7.188705e-001, 3.919951e-003, 2.760792e+000, 7.369418e-001, -2.206536e+000, -1.191342e+000, -2.244384e+000, 3.629413e+000, -3.601610e-002, 7.725349e-002, 5.357588e-002, -2.692147e-001, -1.142476e-001, -1.358286e+000, -2.268740e-001, 9.805731e-001, -5.163195e+000, -8.589000e-003, 7.697565e-001, 2.198750e-001, 7.029301e+000, 1.567170e+000, -7.167767e-001, -2.969978e-001, 2.300987e-001, 7.956088e+000, 6.339728e-001, -6.195374e-001, 2.502844e-001, -6.307569e+000, -2.208822e-002, -1.210525e+000, -1.245541e-001, 9.742409e-001, -9.705683e+000, -1.658899e+000, 1.365829e+000, 2.003500e-001, 4.400174e+000, 1.042345e+000, -1.061524e+000, -2.323500e-001, 1.284880e+000, 1.294836e+001, -5.011732e+000, -9.141086e-001, 2.723804e-001, 6.225528e-001, 6.030977e-001, // albedo 1, turbidity 9 -1.548946e+000, -6.802676e-001, -1.274231e+001, 1.312954e+001, -1.834225e-002, 7.051580e-001, -8.330446e-006, 2.320435e+000, 9.001244e-001, -1.867128e+000, -9.670210e-001, -6.847422e+000, 7.952765e+000, -1.985986e-002, 1.690548e-002, -1.176902e-002, 8.988469e-001, -3.242269e-001, -3.470633e+000, -1.555121e+000, 2.684966e+000, -5.964736e+000, -5.524158e-003, 1.187089e+000, 2.552534e-001, 4.394076e+000, 1.656399e+000, 4.095837e-001, 1.440005e-001, -5.602190e-001, 7.110869e+000, 2.313366e-001, -1.373206e+000, 1.973962e-001, -4.112998e+000, -5.877027e-002, -1.540633e+000, -3.264234e-001, 1.072405e+000, -7.205546e+000, -5.125251e-001, 2.009905e+000, 1.531985e-001, 2.113439e+000, 1.042547e+000, -1.013330e+000, -2.663837e-001, 1.168934e+000, 9.315778e+000, -4.320502e+000, -1.303393e+000, 2.825872e-001, 2.365015e-001, 5.993344e-001, // albedo 1, turbidity 10 -2.055426e+000, -1.093229e+000, -3.487182e+000, 3.753855e+000, -4.639837e-002, 5.797714e-001, -8.056992e-006, 1.916262e+000, 9.001298e-001, -1.643864e+000, -9.676934e-001, -1.147133e+001, 1.253880e+001, 2.347351e-002, -1.602964e-002, 4.481579e-003, 1.373645e+000, -2.884929e-001, -6.156336e+000, -2.568735e+000, 6.499533e+000, -9.136753e+000, -1.751599e-001, 1.876960e+000, -7.959051e-002, 3.074951e+000, 1.579874e+000, 7.378485e-001, -2.614544e-001, -2.861777e+000, 9.518947e+000, 5.033808e-001, -1.844722e+000, 6.855962e-001, -1.497263e+000, -9.081643e-002, -1.341940e+000, -3.847183e-001, 2.045437e+000, -1.179073e+001, -1.532773e+000, 1.639939e+000, -2.668175e-001, -8.401827e-001, 1.083722e+000, -1.086126e+000, -2.811402e-001, 7.554239e-001, 1.862181e+001, -4.343385e+000, -8.611011e-001, 3.146558e-001, 7.022438e-001, 5.872694e-001, }; static float datasetRad560[] = { // albedo 0, turbidity 1 1.518543e-002, 1.176421e-002, 1.736355e-002, 1.085640e-001, 4.928107e-002, 6.789277e-002, // albedo 0, turbidity 2 1.482072e-002, 1.335627e-002, 7.685462e-003, 1.336625e-001, 4.842644e-002, 7.083679e-002, // albedo 0, turbidity 3 1.406436e-002, 1.604888e-002, -9.000273e-003, 1.735923e-001, 4.526955e-002, 7.742648e-002, // albedo 0, turbidity 4 1.296165e-002, 2.074811e-002, -3.672731e-002, 2.310227e-001, 4.272776e-002, 8.807197e-002, // albedo 0, turbidity 5 1.185836e-002, 2.557920e-002, -6.240734e-002, 2.766326e-001, 4.714655e-002, 9.809189e-002, // albedo 0, turbidity 6 1.107469e-002, 2.825097e-002, -7.618392e-002, 2.978619e-001, 5.429803e-002, 1.044545e-001, // albedo 0, turbidity 7 1.030435e-002, 3.060206e-002, -8.858708e-002, 3.072427e-001, 8.473378e-002, 1.077059e-001, // albedo 0, turbidity 8 9.197751e-003, 3.269422e-002, -9.785581e-002, 2.997964e-001, 1.328366e-001, 1.192367e-001, // albedo 0, turbidity 9 8.191103e-003, 3.038883e-002, -8.623921e-002, 2.362785e-001, 2.259917e-001, 1.331360e-001, // albedo 0, turbidity 10 7.275920e-003, 2.128876e-002, -4.464890e-002, 1.022425e-001, 3.640615e-001, 1.521652e-001, // albedo 1, turbidity 1 1.623600e-002, 1.386631e-002, 1.790676e-002, 9.999420e-002, 1.334051e-001, 1.524062e-001, // albedo 1, turbidity 2 1.580346e-002, 1.594123e-002, 5.795411e-003, 1.311774e-001, 1.256680e-001, 1.627637e-001, // albedo 1, turbidity 3 1.508292e-002, 1.888592e-002, -1.186753e-002, 1.719109e-001, 1.235706e-001, 1.739866e-001, // albedo 1, turbidity 4 1.385430e-002, 2.238574e-002, -3.390048e-002, 2.155912e-001, 1.366535e-001, 1.840316e-001, // albedo 1, turbidity 5 1.289448e-002, 2.572803e-002, -5.406854e-002, 2.481650e-001, 1.539663e-001, 1.943329e-001, // albedo 1, turbidity 6 1.229427e-002, 2.715903e-002, -6.212273e-002, 2.543339e-001, 1.780617e-001, 1.961306e-001, // albedo 1, turbidity 7 1.142362e-002, 2.928317e-002, -7.246911e-002, 2.573202e-001, 2.123595e-001, 2.030761e-001, // albedo 1, turbidity 8 1.030850e-002, 2.979460e-002, -7.568370e-002, 2.359473e-001, 2.693691e-001, 2.158786e-001, // albedo 1, turbidity 9 9.256414e-003, 2.622384e-002, -5.910990e-002, 1.602850e-001, 3.679614e-001, 2.281095e-001, // albedo 1, turbidity 10 8.220083e-003, 1.701079e-002, -1.768254e-002, 2.593519e-002, 4.977242e-001, 2.394514e-001, }; static float dataset600[] = { // albedo 0, turbidity 1 -1.120756e+000, -1.756050e-001, -3.557732e+000, 5.117996e+000, -1.042966e-001, 1.269364e+000, 1.318863e-002, 3.718263e+000, 5.393663e-001, -1.170564e+000, -1.845108e-001, 1.081952e+000, 1.330153e+000, -2.486698e-001, 7.864551e-001, 3.710973e-003, 4.567181e+000, 4.998408e-001, -1.036563e+000, -2.605284e-001, 3.803752e+000, -3.585400e+000, -9.070196e-001, 2.380958e+000, -1.320680e-002, -4.210738e+000, 1.085121e+000, -1.193752e+000, -1.236757e-001, -2.036484e-001, 4.137855e+000, 1.566414e+000, 8.510547e-001, 1.653213e-002, 5.488784e+000, 2.335910e-001, -9.950781e-001, -2.103974e-001, 2.992004e+000, -4.050491e+000, -6.354208e+000, 2.250652e+000, -1.548511e-002, -1.876535e+000, 9.733518e-001, -1.106820e+000, -1.804412e-001, 1.960315e+000, 3.667064e+000, -2.460232e+000, 9.553453e-001, 1.238019e-002, 1.307691e+000, 5.564710e-001, // albedo 0, turbidity 2 -1.112834e+000, -1.534956e-001, -4.968015e+000, 6.079068e+000, -8.917942e-002, 1.167545e+000, 5.945633e-002, 5.295468e+000, 6.272123e-001, -1.160910e+000, -1.640745e-001, 7.416807e-001, -2.894668e-001, -8.983936e-002, 3.778575e-002, 2.133300e-001, 6.390765e+000, 3.592393e-001, -1.054872e+000, -2.642844e-001, 4.375802e+000, -1.434824e+000, -7.521504e-001, 3.669027e+000, -2.992879e-001, -5.159653e+000, 1.284643e+000, -1.147542e+000, 1.011446e-002, -2.308529e+000, 1.587994e+000, 1.226957e+000, -1.328837e+000, 5.996235e-001, 1.004278e+001, 5.212352e-002, -1.023945e+000, -2.867193e-001, 3.733660e+000, -2.572157e+000, -7.749675e+000, 3.927326e+000, -3.230666e-001, -4.260418e+000, 1.091761e+000, -1.100815e+000, -1.590204e-001, 1.413330e+000, 6.546557e+000, -2.407235e+000, -2.678587e-001, 2.367155e-001, 2.242596e+000, 5.273419e-001, // albedo 0, turbidity 3 -1.137271e+000, -1.838447e-001, -2.268731e+000, 3.013967e+000, -1.471213e-001, 9.047947e-001, 8.086373e-002, 4.834215e+000, 6.545047e-001, -1.136415e+000, -1.536696e-001, -1.821062e+000, 1.756804e+000, -9.313635e-002, 2.208938e-001, 2.021774e-001, 7.289664e+000, 4.997813e-001, -1.173214e+000, -3.202233e-001, 4.868221e+000, -2.485467e+000, -7.693969e-001, 3.027854e+000, -1.745243e-001, -4.896365e+000, 1.014186e+000, -1.021346e+000, 7.262425e-002, -2.940205e+000, 3.357462e+000, 1.150486e+000, -1.710207e+000, 7.381637e-001, 9.857427e+000, 3.036725e-001, -1.082107e+000, -2.721172e-001, 3.071962e+000, -7.058088e+000, -5.103538e+000, 3.852302e+000, -2.281911e-001, -2.565665e+000, 9.669584e-001, -1.076296e+000, -1.655466e-001, 1.323765e+000, 1.496892e+001, -3.773928e+000, -5.211752e-001, 2.583009e-001, 1.797906e+000, 5.888323e-001, // albedo 0, turbidity 4 -1.180432e+000, -2.327942e-001, -7.152650e-001, 1.078120e+000, -2.935788e-001, 6.977295e-001, 1.118530e-001, 4.270574e+000, 6.241267e-001, -1.260549e+000, -2.865438e-001, -2.736770e+000, 2.720969e+000, 1.291231e-001, 4.072562e-001, 4.510932e-002, 5.412464e+000, 6.781695e-001, -1.119712e+000, -2.521160e-001, 4.860527e+000, -1.950603e+000, -1.598805e+000, 2.556718e+000, 2.462723e-002, -2.059404e+000, 8.000995e-001, -1.056386e+000, 2.018258e-002, -3.728955e+000, 1.022270e+000, 1.722210e+000, -2.691554e+000, 8.329883e-001, 6.982450e+000, 4.746778e-001, -1.044811e+000, -2.531291e-001, 3.102204e+000, -3.662632e+000, -5.609358e+000, 4.574385e+000, -2.173600e-001, -1.646110e+000, 8.593305e-001, -1.090027e+000, -1.699462e-001, 7.118896e-001, 1.287572e+001, -2.747429e+000, -1.706223e+000, 4.483382e-001, 2.029605e+000, 6.366599e-001, // albedo 0, turbidity 5 -1.232266e+000, -2.905676e-001, -4.158347e-001, 5.285264e-001, -3.064312e-001, 5.569478e-001, 1.195289e-001, 3.788091e+000, 5.970680e-001, -1.451205e+000, -5.169964e-001, -2.018331e-001, 1.499655e+000, -1.575963e+000, 2.761459e-001, 5.184923e-002, 2.301119e+000, 6.177771e-001, -1.059832e+000, -7.658003e-002, 6.456894e-001, -4.398594e+000, 5.369604e+000, 2.121235e+000, 3.210869e-002, 3.542794e+000, 9.114953e-001, -1.040966e+000, -1.269405e-001, -3.751056e-001, 1.229395e+001, -1.977090e+001, -2.458488e+000, 7.711932e-001, 8.079227e-001, 3.865305e-001, -1.061923e+000, -1.981907e-001, 1.089854e+000, -3.414507e+000, 8.032592e+000, 3.459965e+000, -1.253984e-001, 1.188198e+000, 8.639277e-001, -1.070607e+000, -1.627049e-001, 7.012071e-001, 2.138780e+000, -5.006595e+000, -1.096698e+000, 6.658771e-001, 1.999430e+000, 6.557122e-001, // albedo 0, turbidity 6 -1.280090e+000, -3.357179e-001, -9.337154e-002, -5.075553e-003, -3.096112e+000, 4.001499e-001, 1.489818e-001, 3.515349e+000, 5.571477e-001, -1.648190e+000, -7.024227e-001, -2.925797e-002, 1.658094e+000, 4.229924e+000, 3.502683e-001, 3.180108e-002, 1.430955e+000, 5.739552e-001, -9.589189e-001, 2.559557e-002, 2.192186e-001, -5.276316e+000, -4.153922e+000, 1.855574e+000, 3.052317e-002, 4.323694e+000, 9.839497e-001, -1.076589e+000, -1.936109e-001, -4.162615e-001, 1.202609e+001, -9.327314e+000, -2.326508e+000, 7.983253e-001, 2.100845e-001, 3.135170e-001, -1.049437e+000, -1.694738e-001, 1.062110e+000, 5.575299e+000, 4.846701e-001, 3.089474e+000, -1.584214e-001, 1.369457e+000, 8.995377e-001, -1.069986e+000, -1.830827e-001, 5.006422e-001, -3.063835e-003, -2.768514e+000, -1.258027e+000, 6.679955e-001, 1.840288e+000, 6.498676e-001, // albedo 0, turbidity 7 -1.328971e+000, -3.853230e-001, -2.343098e-001, -6.505414e-003, -4.859294e+000, 3.752993e-001, 1.670718e-001, 3.474961e+000, 4.998573e-001, -2.023062e+000, -1.023840e+000, 4.308501e-001, 1.473146e+000, 6.112105e+000, 5.767265e-001, -3.107377e-002, 7.748759e-002, 5.016978e-001, -8.575747e-001, 1.580212e-001, -7.365004e-001, -4.007773e+000, -4.051657e+000, 8.889282e-001, 1.978413e-001, 6.282132e+000, 1.063928e+000, -1.073428e+000, -3.228761e-001, 4.793085e-001, 5.455778e+000, -7.830559e+000, -9.794478e-001, 5.370543e-001, -3.022750e+000, 2.818600e-001, -1.057120e+000, -1.266841e-001, 4.555368e-001, 1.201278e+001, -9.293773e-001, 1.439595e+000, 3.262182e-002, 2.890364e+000, 8.821540e-001, -1.060079e+000, -1.816680e-001, 3.541107e-001, -2.642196e-003, -2.588317e+000, -5.640010e-001, 6.643994e-001, 1.673077e+000, 6.658333e-001, // albedo 0, turbidity 8 -1.395409e+000, -4.658947e-001, -4.370597e-001, 1.342039e+000, -1.108674e+000, 6.439316e-001, 1.355229e-002, 3.241153e+000, 6.696079e-001, -2.418167e+000, -1.266061e+000, 3.287382e-001, -1.486721e+000, -6.770180e-001, 2.439008e-001, 1.703788e-001, 1.664559e-002, -6.330217e-003, -1.221212e+000, -1.072571e-001, -1.655914e+000, 2.659047e+000, 6.830770e+000, 4.984792e-001, 2.538158e-001, 6.500660e+000, 1.486576e+000, -7.182331e-001, -2.519055e-001, 1.641261e+000, -5.500375e+000, -1.253143e+001, -1.542672e-001, 1.741161e-001, -4.907497e+000, 7.968864e-002, -1.207117e+000, -1.635739e-001, -3.256308e-001, 1.409033e+001, 1.107883e+000, 7.217342e-001, 3.158860e-001, 3.537550e+000, 9.389751e-001, -1.015927e+000, -1.890895e-001, 4.180376e-001, 9.528535e+000, -4.073979e+000, -8.713087e-001, 4.899379e-001, 1.277831e+000, 6.519818e-001, // albedo 0, turbidity 9 -1.551242e+000, -6.400568e-001, -3.673011e-001, 1.623228e+000, -1.482572e+000, 5.625944e-001, -1.130924e-005, 2.792007e+000, 9.000924e-001, -1.971409e+000, -9.004995e-001, -2.337582e-001, -1.511905e+000, 6.645432e-002, 6.149087e-001, -3.184094e-002, 2.026210e+000, -2.799058e-001, -3.464015e+000, -1.604654e+000, -1.514516e+000, 2.768075e+000, 4.084166e+000, -4.287171e-001, 7.112107e-001, 2.896460e+000, 1.502031e+000, 4.069978e-001, 2.775394e-001, 1.525761e+000, -5.264056e+000, -7.108445e+000, 1.134996e+000, -4.122625e-001, -2.558151e+000, 2.009854e-001, -1.504217e+000, -3.618442e-001, -2.305374e-001, 1.434481e+001, -1.713254e+000, -5.670708e-001, 5.206848e-001, 1.704009e+000, 8.447497e-001, -9.753124e-001, -2.080868e-001, 2.450141e-001, -3.535206e-003, -2.121317e+000, -1.425634e-001, 4.670084e-001, 1.027875e+000, 6.735543e-001, // albedo 0, turbidity 10 -2.027207e+000, -1.003600e+000, -3.813114e-001, 9.357907e-001, -1.031886e+000, 5.523389e-001, -8.883940e-006, 2.339379e+000, 9.001659e-001, -1.506235e+000, -7.795241e-001, -4.313309e-001, 9.124054e-001, -7.484352e-001, -8.417756e-002, -1.426561e-002, 2.571178e+000, -2.504298e-001, -6.482777e+000, -2.700075e+000, -1.556622e+000, -2.978497e+000, 4.623255e+000, 1.953868e+000, 3.113178e-001, 2.311303e+000, 1.451021e+000, 9.357272e-001, -1.066566e-001, 1.476763e+000, 6.889797e+000, -1.038036e+001, -2.094856e+000, 1.330069e-001, -1.446404e+000, 1.121890e-001, -1.398229e+000, -3.167573e-001, -1.276866e-001, 1.239440e+000, 1.816678e+000, 1.586775e+000, 8.043533e-002, 3.219192e-001, 9.200620e-001, -1.070734e+000, -3.636167e-001, 2.426490e-001, 8.282765e+000, -3.588710e+000, -9.105402e-001, 3.760276e-001, 5.756358e-001, 6.508161e-001, // albedo 1, turbidity 1 -1.120757e+000, -1.756034e-001, -3.557732e+000, 5.117996e+000, -1.042960e-001, 1.269364e+000, 1.318834e-002, 3.718263e+000, 5.393663e-001, -1.170565e+000, -1.845093e-001, 1.081952e+000, 1.330153e+000, -2.486697e-001, 7.864550e-001, 3.709405e-003, 4.567181e+000, 4.998408e-001, -1.036564e+000, -2.605265e-001, 3.803752e+000, -3.585400e+000, -9.070196e-001, 2.380958e+000, -1.320996e-002, -4.210738e+000, 1.085121e+000, -1.193753e+000, -1.236733e-001, -2.036483e-001, 4.137855e+000, 1.566414e+000, 8.510543e-001, 1.652749e-002, 5.488784e+000, 2.335910e-001, -9.950796e-001, -2.103948e-001, 2.992004e+000, -4.050491e+000, -6.354208e+000, 2.250652e+000, -1.548996e-002, -1.876535e+000, 9.733518e-001, -1.106823e+000, -1.804388e-001, 1.960315e+000, 3.667064e+000, -2.460232e+000, 9.553451e-001, 1.237721e-002, 1.307692e+000, 5.564710e-001, // albedo 1, turbidity 2 -1.113356e+000, -1.560185e-001, -7.788803e+000, 8.963658e+000, -5.322872e-002, 1.116670e+000, 7.024842e-002, 4.886694e+000, 5.931909e-001, -1.134232e+000, -1.667475e-001, 4.176259e+000, -3.242194e+000, -7.889230e-002, 8.254326e-002, 1.400333e-001, 5.395289e+000, 4.862375e-001, -1.105040e+000, -2.389195e-001, 9.866260e-001, 1.271557e+000, -6.066849e-001, 3.599900e+000, -1.681445e-001, -2.812867e+000, 1.053791e+000, -1.078302e+000, -2.258635e-002, 7.407482e-001, 1.805864e-001, 9.070580e-001, -1.720820e+000, 4.256187e-001, 6.982502e+000, 3.350778e-001, -1.070883e+000, -2.752054e-001, 2.937203e+000, -2.246366e+000, -9.847865e+000, 3.104714e+000, -2.573859e-001, -2.816401e+000, 8.478900e-001, -1.090880e+000, -1.453755e-001, 2.046382e+000, 5.595795e+000, -2.809181e+000, -9.239576e-001, 1.783176e-001, 2.051350e+000, 5.815062e-001, // albedo 1, turbidity 3 -1.136641e+000, -1.825277e-001, -3.464338e+000, 4.413974e+000, -1.123917e-001, 1.009115e+000, 5.542918e-002, 4.702599e+000, 6.799974e-001, -1.146478e+000, -1.593833e-001, -9.055790e-001, 8.991902e-001, -4.711416e-002, -3.813573e-001, 2.290428e-001, 6.961903e+000, 4.206011e-001, -1.136317e+000, -3.103198e-001, 4.219694e+000, -2.031887e+000, -7.184952e-001, 3.795646e+000, -1.650547e-001, -5.402471e+000, 1.118561e+000, -1.044973e+000, 7.826651e-002, -2.043684e+000, 3.410720e+000, 1.974969e+000, -2.736513e+000, 6.828176e-001, 1.049084e+001, 1.894241e-001, -1.076125e+000, -2.930526e-001, 3.722784e+000, -7.364061e+000, -7.399428e+000, 4.034307e+000, -3.489831e-001, -3.438955e+000, 1.077145e+000, -1.100551e+000, -1.533449e-001, 1.767589e+000, 1.479022e+001, -2.910058e+000, -1.732923e+000, 2.193598e-001, 1.880974e+000, 4.999331e-001, // albedo 1, turbidity 4 -1.175282e+000, -2.274651e-001, -8.788053e-001, 1.446934e+000, -2.568124e-001, 7.201567e-001, 1.054963e-001, 4.149007e+000, 6.084060e-001, -1.224868e+000, -2.528005e-001, -2.861303e+000, 3.033667e+000, 1.405049e-001, 2.481768e-001, 6.435189e-002, 5.409907e+000, 6.372238e-001, -1.144647e+000, -3.063749e-001, 4.347579e+000, -2.473291e+000, -1.180139e+000, 2.550631e+000, 3.833967e-002, -3.231444e+000, 8.737219e-001, -1.028428e+000, 8.888974e-002, -2.431225e+000, 2.811511e+000, 2.400771e+000, -2.380403e+000, 7.114868e-001, 8.190106e+000, 4.166861e-001, -1.076730e+000, -3.129260e-001, 3.582560e+000, -5.902417e+000, -6.959342e+000, 3.528030e+000, -2.613596e-001, -2.993803e+000, 8.934226e-001, -1.107957e+000, -1.728652e-001, 1.679540e+000, 1.238391e+001, -2.945620e+000, -1.568811e+000, 2.418421e-001, 1.360652e+000, 6.182405e-001, // albedo 1, turbidity 5 -1.215034e+000, -2.755459e-001, -1.477751e-001, 4.448730e-001, -4.027817e-001, 4.787013e-001, 1.200617e-001, 3.613995e+000, 5.999756e-001, -1.443500e+000, -5.194350e-001, 1.588243e-001, 1.429114e+000, -2.310655e+000, 3.033213e-001, 2.308566e-002, 1.894189e+000, 6.066576e-001, -1.051421e+000, -9.990731e-002, 5.187710e-001, -3.890856e+000, 7.794599e+000, 1.810628e+000, 6.532073e-002, 2.564480e+000, 9.334916e-001, -1.034548e+000, -6.777012e-002, -2.587520e-002, 1.062675e+001, -2.266196e+001, -2.002081e+000, 7.508804e-001, 2.022771e+000, 3.517577e-001, -1.090576e+000, -2.542157e-001, 2.213560e+000, -3.563890e+000, 9.180955e+000, 2.780121e+000, -2.656654e-001, -5.012514e-002, 8.968751e-001, -1.104356e+000, -1.955634e-001, 1.782217e+000, 1.085584e+000, -5.011522e+000, -1.075140e+000, 3.828238e-001, 6.133363e-001, 6.448312e-001, // albedo 1, turbidity 6 -1.261147e+000, -3.271435e-001, 1.136430e-001, -3.464762e-003, -3.025565e+000, 3.660675e-001, 1.337332e-001, 3.190374e+000, 5.655627e-001, -1.611753e+000, -6.914768e-001, 2.911405e-001, 1.806475e+000, 2.823240e+000, 3.320241e-001, 2.606391e-002, 9.946717e-001, 5.581393e-001, -9.491151e-001, 9.848038e-003, 2.711804e-001, -5.319331e+000, 1.135835e-001, 1.669815e+000, 3.604115e-002, 3.506230e+000, 1.008650e+000, -1.109597e+000, -1.650703e-001, -3.529912e-001, 1.209251e+001, -1.435008e+001, -2.085063e+000, 7.955493e-001, 1.240407e+000, 2.856509e-001, -1.035803e+000, -1.963707e-001, 2.407913e+000, -1.564693e+000, 4.483717e+000, 2.795295e+000, -2.799711e-001, 6.851892e-002, 9.312311e-001, -1.132687e+000, -2.383551e-001, 1.590132e+000, 1.025733e+000, -4.837236e+000, -1.334195e+000, 4.022060e-001, 4.281273e-001, 6.334802e-001, // albedo 1, turbidity 7 -1.310240e+000, -3.819813e-001, 2.469845e-002, -7.043983e-003, -5.009925e+000, 3.560980e-001, 1.582176e-001, 2.966421e+000, 4.998910e-001, -1.993638e+000, -1.029241e+000, 7.780588e-001, 1.080741e+000, 7.179598e+000, 2.478857e-001, 1.935012e-002, -3.434240e-001, 4.813586e-001, -8.209344e-001, 1.728853e-001, -7.045676e-001, -3.384688e+000, -4.855111e+000, 1.661563e+000, 4.252574e-002, 5.701648e+000, 1.110774e+000, -1.130678e+000, -3.273624e-001, 5.555549e-001, 5.800793e+000, -8.817085e+000, -2.344445e+000, 7.532869e-001, -2.418368e+000, 2.201826e-001, -1.032417e+000, -1.335568e-001, 1.707051e+000, 8.168228e+000, -5.151972e-003, 2.785504e+000, -2.123703e-001, 1.770173e+000, 9.064082e-001, -1.125604e+000, -2.328530e-001, 1.537245e+000, 4.347312e+000, -4.368526e+000, -1.527321e+000, 3.574251e-001, 5.982159e-001, 6.705880e-001, // albedo 1, turbidity 8 -1.381743e+000, -4.607543e-001, -2.754732e-001, 9.134243e-001, -7.581174e-001, 6.220814e-001, 2.353878e-002, 2.891536e+000, 6.426078e-001, -2.362341e+000, -1.306326e+000, 6.909936e-001, -7.196658e-001, -4.501812e-001, -5.219928e-002, 2.111683e-001, -9.499603e-001, 3.301774e-002, -1.218829e+000, -6.834768e-002, -1.241760e+000, 1.122890e+000, 5.750762e+000, 1.231058e+000, 6.884716e-003, 6.801032e+000, 1.512485e+000, -6.781560e-001, -2.446588e-001, 1.302166e+000, -2.334650e+000, -1.218960e+001, -1.257952e+000, 5.387955e-001, -5.559859e+000, -1.209718e-002, -1.270037e+000, -1.870204e-001, 9.650201e-001, 9.976613e+000, 1.444014e+000, 1.523442e+000, -2.753646e-002, 3.415790e+000, 1.017645e+000, -1.046712e+000, -2.173979e-001, 1.473981e+000, 4.368847e+000, -4.642506e+000, -1.049951e+000, 3.511771e-001, 2.379457e-001, 6.307946e-001, // albedo 1, turbidity 9 -1.532302e+000, -6.390752e-001, -1.369123e-001, 1.480171e+000, -1.313391e+000, 5.210118e-001, -1.053608e-005, 2.352090e+000, 9.000581e-001, -2.042866e+000, -1.015386e+000, 1.750126e-001, -9.921800e-001, -9.449241e-002, 4.791921e-001, -2.744712e-002, 9.337925e-001, -2.902902e-001, -3.413474e+000, -1.485380e+000, -1.301300e+000, 1.266203e+000, 3.869657e+000, -1.405606e-002, 6.109944e-001, 3.883967e+000, 1.540321e+000, 5.838664e-001, 2.370098e-001, 1.420200e+000, -1.803001e+000, -6.672775e+000, 2.866921e-001, -2.599250e-001, -4.162164e+000, 1.296901e-001, -1.654226e+000, -3.296843e-001, 6.245723e-001, 7.899655e+000, -1.079857e+000, 3.145485e-001, 4.085894e-001, 2.258895e+000, 9.071309e-001, -9.748612e-001, -2.545963e-001, 1.374064e+000, -2.816107e-003, -2.589259e+000, -5.960628e-001, 2.656787e-001, -1.458520e-001, 6.529731e-001, // albedo 1, turbidity 10 -1.944006e+000, -9.776516e-001, -2.425412e-001, 8.187180e-001, -6.620102e-001, 5.676187e-001, -7.857556e-006, 1.944153e+000, 9.001463e-001, -1.294455e+000, -7.294996e-001, -1.718682e-002, 1.261264e+000, -1.170104e+000, -2.029198e-001, -1.306023e-002, 1.821821e+000, -2.533820e-001, -6.849943e+000, -2.937611e+000, -1.107710e+000, -3.923478e+000, 5.018293e+000, 2.040419e+000, 2.845113e-001, 2.080902e+000, 1.460328e+000, 1.445166e+000, 1.641979e-001, 9.591325e-001, 8.676572e+000, -1.098801e+001, -2.274573e+000, 1.340040e-001, -1.166380e+000, 1.014270e-001, -1.596800e+000, -4.130457e-001, 9.250919e-001, -1.406592e+000, 2.474727e+000, 1.748285e+000, 9.929937e-002, -6.705073e-001, 9.210646e-001, -1.035617e+000, -3.537996e-001, 1.073337e+000, 6.090616e+000, -3.710420e+000, -9.390485e-001, 2.233788e-001, -3.213961e-004, 6.545784e-001, }; static float datasetRad600[] = { // albedo 0, turbidity 1 1.605147e-002, 1.028116e-002, 2.949675e-002, 7.265851e-002, 4.608279e-002, 5.069475e-002, // albedo 0, turbidity 2 1.569474e-002, 1.190744e-002, 1.996322e-002, 1.044303e-001, 3.746120e-002, 5.764085e-002, // albedo 0, turbidity 3 1.507252e-002, 1.350309e-002, 7.291417e-003, 1.433035e-001, 3.625213e-002, 6.291384e-002, // albedo 0, turbidity 4 1.383183e-002, 1.670171e-002, -1.576321e-002, 1.993796e-001, 3.837478e-002, 7.063028e-002, // albedo 0, turbidity 5 1.253723e-002, 2.261520e-002, -4.847485e-002, 2.646653e-001, 2.855366e-002, 8.568437e-002, // albedo 0, turbidity 6 1.179552e-002, 2.546904e-002, -6.503150e-002, 2.924065e-001, 3.516626e-002, 9.101182e-002, // albedo 0, turbidity 7 1.070809e-002, 3.005971e-002, -8.793572e-002, 3.255182e-001, 4.780714e-002, 1.014896e-001, // albedo 0, turbidity 8 9.466972e-003, 3.330913e-002, -1.028545e-001, 3.284098e-001, 9.602966e-002, 1.103224e-001, // albedo 0, turbidity 9 8.190696e-003, 3.248675e-002, -9.882934e-002, 2.798409e-001, 1.829752e-001, 1.263322e-001, // albedo 0, turbidity 10 7.225549e-003, 2.433471e-002, -6.029571e-002, 1.468935e-001, 3.282492e-001, 1.441367e-001, // albedo 1, turbidity 1 1.676204e-002, 1.269480e-002, 2.674342e-002, 7.380770e-002, 1.072658e-001, 1.211512e-001, // albedo 1, turbidity 2 1.649305e-002, 1.445974e-002, 1.662432e-002, 1.056364e-001, 1.002831e-001, 1.317330e-001, // albedo 1, turbidity 3 1.577677e-002, 1.637005e-002, 2.821156e-003, 1.465189e-001, 9.971575e-002, 1.424798e-001, // albedo 1, turbidity 4 1.469049e-002, 1.969668e-002, -2.105278e-002, 2.024104e-001, 1.062768e-001, 1.557134e-001, // albedo 1, turbidity 5 1.339480e-002, 2.402713e-002, -4.671234e-002, 2.518382e-001, 1.135974e-001, 1.711111e-001, // albedo 1, turbidity 6 1.274349e-002, 2.648472e-002, -6.068209e-002, 2.720113e-001, 1.285128e-001, 1.776298e-001, // albedo 1, turbidity 7 1.165402e-002, 2.958682e-002, -7.746524e-002, 2.912132e-001, 1.536569e-001, 1.896419e-001, // albedo 1, turbidity 8 1.048769e-002, 3.115400e-002, -8.550235e-002, 2.769964e-001, 2.173505e-001, 1.991057e-001, // albedo 1, turbidity 9 9.312926e-003, 2.881725e-002, -7.387358e-002, 2.079818e-001, 3.221838e-001, 2.120657e-001, // albedo 1, turbidity 10 8.151793e-003, 1.998414e-002, -3.316224e-002, 6.957927e-002, 4.654511e-001, 2.260782e-001, }; static float dataset640[] = { // albedo 0, turbidity 1 -1.113346e+000, -1.715076e-001, -2.657094e+000, 4.632520e+000, -1.092310e-001, 1.421516e+000, 3.230348e-003, 2.697889e+000, 6.262031e-001, -1.193355e+000, -2.074379e-001, 1.431777e+000, 8.245570e-001, -1.936967e-001, 9.392137e-001, 1.972523e-002, 3.001209e+000, 4.415825e-001, -9.337792e-001, -2.037239e-001, 3.943675e+000, -2.487730e+000, -9.876315e-001, 2.772411e+000, -4.919462e-002, -4.176827e+000, 1.026227e+000, -1.297623e+000, -1.296758e-001, -3.144502e-001, 2.454199e+000, 2.433614e+000, 5.298928e-001, 7.814939e-002, 6.564581e+000, 5.587597e-001, -9.325270e-001, -1.997966e-001, 3.363315e+000, -1.887198e+000, -8.905212e+000, 2.808597e+000, -9.537165e-002, -3.059702e+000, 5.403718e-001, -1.125650e+000, -1.904795e-001, 2.099998e+000, 1.251930e+000, -1.899312e+000, 5.255919e-001, 9.848260e-002, 9.627433e-001, 6.251236e-001, // albedo 0, turbidity 2 -1.104956e+000, -1.372068e-001, -2.996624e+000, 4.260021e+000, -1.263137e-001, 1.327775e+000, 7.595887e-002, 5.301229e+000, 6.478109e-001, -1.158426e+000, -1.921879e-001, 3.371987e-001, 8.543727e-001, -1.195421e-001, 2.178871e-001, 1.573997e-001, 3.059646e+000, 5.355391e-001, -1.012076e+000, -1.456275e-001, 3.857821e+000, -1.137640e+000, -7.400821e-001, 4.132381e+000, -2.101470e-001, -1.704290e-001, 1.094519e+000, -1.200085e+000, -9.008631e-002, -1.764929e+000, 4.584027e-001, 8.033799e-001, -1.730728e+000, 5.892683e-001, 6.438112e+000, 2.141131e-001, -9.836248e-001, -1.983419e-001, 3.519957e+000, -9.777763e-001, -5.727911e+000, 4.397457e+000, -2.864495e-001, -2.511187e+000, 9.881415e-001, -1.111842e+000, -1.992363e-001, 1.746814e+000, 5.036170e+000, -2.993753e+000, -5.348114e-001, 2.332738e-001, 8.970344e-001, 5.806194e-001, // albedo 0, turbidity 3 -1.120087e+000, -1.577355e-001, -1.165606e+000, 1.782016e+000, -1.771264e-001, 8.928578e-001, 1.613110e-001, 4.975693e+000, 6.258796e-001, -1.182069e+000, -2.047357e-001, -4.041517e-001, 1.732659e+000, -4.322749e-001, 6.549554e-001, 5.392767e-002, 4.838218e+000, 6.441461e-001, -1.071518e+000, -2.057500e-001, 2.808685e+000, -1.990080e+000, -8.491815e-001, 2.193915e+000, 2.411077e-001, -3.251587e+000, 7.470978e-001, -1.113379e+000, -6.708322e-003, -2.181109e+000, 2.107674e+000, 2.216970e+000, -6.233552e-001, 3.558080e-001, 9.251876e+000, 6.319555e-001, -1.026698e+000, -2.260748e-001, 3.031659e+000, -1.615765e+000, -1.323341e+000, 2.835147e+000, 1.186568e-001, -3.366247e+000, 6.850407e-001, -1.088223e+000, -1.817555e-001, 1.435855e+000, 1.845164e+000, -3.488539e+000, 2.554837e-001, 2.144895e-001, 1.558895e+000, 7.315398e-001, // albedo 0, turbidity 4 -1.164089e+000, -2.003003e-001, -2.998423e-001, 2.713689e-001, -1.828861e-001, 5.800779e-001, 1.968402e-001, 4.650130e+000, 6.156174e-001, -1.209796e+000, -2.733887e-001, -9.360003e-001, 2.769100e+000, -1.870929e+000, 7.049322e-001, -8.477045e-002, 4.120960e+000, 7.444509e-001, -1.232839e+000, -2.622151e-001, 2.857050e+000, -2.866256e+000, 3.128232e+000, 1.897877e+000, 4.581244e-001, -2.112943e+000, 6.384882e-001, -9.291113e-001, 4.110508e-002, -2.235781e+000, 2.969741e+000, -9.758544e+000, -1.941571e+000, 3.426656e-001, 6.907158e+000, 6.945892e-001, -1.103614e+000, -2.279953e-001, 2.314490e+000, -6.307971e-001, 3.369674e+000, 3.787928e+000, 2.456513e-001, -1.776073e+000, 6.864316e-001, -1.072160e+000, -1.984678e-001, 1.092192e+000, 8.472734e-001, -3.126637e+000, -1.076607e+000, 3.908469e-001, 1.205671e+000, 7.035925e-001, // albedo 0, turbidity 5 -1.222416e+000, -2.654298e-001, -1.149975e-001, -6.277756e-003, -1.369463e+000, 4.402179e-001, 1.881320e-001, 3.896722e+000, 6.037946e-001, -1.407746e+000, -4.603243e-001, -3.071475e-001, 2.937390e+000, -9.164938e-001, 6.696693e-001, -6.608327e-002, 2.444782e+000, 6.905594e-001, -1.120454e+000, -1.466269e-001, 7.829076e-001, -7.009271e+000, 5.364470e+000, 1.294280e+000, 4.109552e-001, 1.525889e+000, 7.709564e-001, -9.792886e-001, -4.325464e-002, -4.059461e-001, 1.522559e+001, -1.867598e+001, -1.169367e+000, 3.589556e-001, 2.368951e+000, 5.526839e-001, -1.091118e+000, -2.286983e-001, 9.896666e-001, -6.655971e+000, 8.168041e+000, 1.923773e+000, 3.116805e-001, 1.852611e-001, 7.524175e-001, -1.053081e+000, -1.598496e-001, 9.684194e-001, 3.620674e+000, -5.015769e+000, 8.125082e-002, 4.669502e-001, 1.415221e+000, 7.044272e-001, // albedo 0, turbidity 6 -1.267172e+000, -3.101221e-001, -8.556526e-002, -3.602153e-003, -4.988229e+000, 4.099753e-001, 1.555248e-001, 3.585489e+000, 6.128833e-001, -1.613116e+000, -6.560485e-001, 9.250270e-002, 2.119268e+000, 8.031058e+000, 4.019483e-001, 4.526662e-002, 1.362051e+000, 5.999628e-001, -1.012405e+000, -2.251592e-002, 2.836289e-001, -7.904006e+000, -9.544755e+000, 1.754891e+000, 1.283266e-001, 3.042478e+000, 9.234755e-001, -1.022835e+000, -1.361070e-001, -4.207218e-001, 1.947050e+001, -5.511234e+000, -2.417169e+000, 7.837822e-001, 8.288902e-001, 3.509734e-001, -1.068370e+000, -1.806143e-001, 1.059217e+000, 7.087518e-001, -1.671865e+000, 3.098645e+000, -9.859822e-002, 9.336021e-001, 8.929147e-001, -1.065467e+000, -1.928982e-001, 6.159162e-001, -4.157538e-003, -9.397621e-001, -1.193139e+000, 6.979501e-001, 1.118894e+000, 6.467115e-001, // albedo 0, turbidity 7 -1.345697e+000, -3.906019e-001, -1.921159e-001, -7.410201e-003, -4.683006e+000, 4.591917e-001, 1.919817e-001, 3.158844e+000, 5.319014e-001, -2.096314e+000, -1.056514e+000, 7.665515e-001, 1.602483e+000, 6.290779e+000, 4.693208e-001, -6.258855e-002, -3.745685e-001, 5.853677e-001, -7.573573e-001, 2.265213e-001, -1.283398e+000, -4.696984e+000, -4.261986e+000, 1.197826e+000, 3.444468e-001, 6.004387e+000, 9.413954e-001, -1.140929e+000, -3.489820e-001, 1.095429e+000, 7.531589e+000, -8.153320e+000, -1.722207e+000, 4.427477e-001, -3.072440e+000, 3.874398e-001, -1.009003e+000, -9.087616e-002, 4.181128e-002, 1.154023e+001, -5.092155e-001, 2.166116e+000, 1.620893e-001, 2.824826e+000, 8.289491e-001, -1.080842e+000, -2.166745e-001, 6.939662e-001, -2.316636e-003, -2.616711e+000, -1.012238e+000, 6.132021e-001, 7.579828e-001, 6.813755e-001, // albedo 0, turbidity 8 -1.394668e+000, -4.508268e-001, -2.615024e-001, -7.412740e-003, -4.811648e+000, 4.235635e-001, 1.627041e-001, 3.134174e+000, 5.225016e-001, -2.715734e+000, -1.409574e+000, 6.485110e-001, 6.307101e-001, 8.120123e+000, 3.677567e-001, 6.430919e-002, -3.729191e-001, 3.463130e-001, -8.973624e-001, 2.859206e-002, -1.610007e+000, -1.483136e+000, -5.613288e+000, 7.093329e-001, 2.936945e-001, 5.541210e+000, 1.143952e+000, -8.450858e-001, -1.969825e-001, 1.399585e+000, 1.418708e-001, -4.532026e+000, -7.432040e-001, 3.410858e-001, -3.386293e+000, 2.885614e-001, -1.180533e+000, -2.469972e-001, -2.694505e-002, 1.635998e+001, -2.378676e+000, 9.477733e-001, 1.105776e-001, 1.954485e+000, 8.559872e-001, -1.022908e+000, -1.650807e-001, 3.812483e-001, -2.139201e-003, -2.300711e+000, -5.917998e-001, 6.793527e-001, 1.248273e+000, 6.747565e-001, // albedo 0, turbidity 9 -1.557922e+000, -6.294681e-001, -2.355549e-001, -8.743568e-003, -5.017111e+000, 4.034446e-001, 1.005643e-001, 2.735289e+000, 5.667004e-001, -3.061673e+000, -1.398157e+000, 1.597008e-001, 1.066059e+000, 8.207018e+000, 4.785780e-001, 4.629487e-002, 1.324020e+000, 2.540204e-001, -2.371583e+000, -1.100187e+000, -1.279309e+000, -3.340819e+000, -6.556706e+000, 2.636750e-001, 4.298705e-001, 2.649782e+000, 1.060950e+000, -5.315727e-002, 2.306821e-001, 1.091037e+000, 5.297610e+000, -2.412315e+000, -7.083157e-002, 7.256586e-002, -1.330891e+000, 4.168205e-001, -1.375983e+000, -4.677570e-001, 2.271650e-001, 8.771601e+000, -2.511780e+000, 1.487082e-001, 8.542210e-002, 5.509707e-003, 7.821447e-001, -1.006483e+000, -1.435513e-001, 5.802646e-002, -3.181899e-003, -2.010861e+000, -1.746922e-001, 7.487809e-001, 1.623209e+000, 6.848148e-001, // albedo 0, turbidity 10 -1.919035e+000, -9.396362e-001, -3.059418e-001, 1.542398e+000, -1.488273e+000, 5.133825e-001, -7.992185e-006, 2.276361e+000, 8.334381e-001, -2.470138e+000, -1.108577e+000, -5.521438e-001, -9.047033e-001, 6.905739e-001, 3.774300e-001, -2.801883e-002, 2.413470e+000, -8.986266e-002, -5.532450e+000, -2.346497e+000, -1.734654e+000, 1.461689e+000, 1.765938e+000, 4.969811e-001, 6.205943e-001, 2.112232e+000, 1.159488e+000, 4.159150e-001, -2.306809e-001, 1.540502e+000, -1.006923e+000, -5.275092e+000, -2.776202e-002, -1.632884e-001, -1.467491e+000, 4.177919e-001, -1.248112e+000, -3.080519e-001, -1.229235e-001, 8.972757e+000, -1.532948e+000, -8.283794e-002, 1.561573e-001, 1.856113e-001, 7.696948e-001, -1.054499e+000, -2.660558e-001, 1.307025e-001, -2.167883e-003, -1.531056e+000, 1.525856e-001, 5.356892e-001, 7.181428e-001, 6.837654e-001, // albedo 1, turbidity 1 -1.113347e+000, -1.715068e-001, -2.657094e+000, 4.632520e+000, -1.092308e-001, 1.421516e+000, 3.229759e-003, 2.697889e+000, 6.262031e-001, -1.193355e+000, -2.074367e-001, 1.431777e+000, 8.245569e-001, -1.936966e-001, 9.392136e-001, 1.972263e-002, 3.001209e+000, 4.415825e-001, -9.337795e-001, -2.037221e-001, 3.943675e+000, -2.487730e+000, -9.876315e-001, 2.772410e+000, -4.919872e-002, -4.176827e+000, 1.026227e+000, -1.297624e+000, -1.296733e-001, -3.144502e-001, 2.454199e+000, 2.433614e+000, 5.298925e-001, 7.814503e-002, 6.564581e+000, 5.587597e-001, -9.325285e-001, -1.997939e-001, 3.363316e+000, -1.887198e+000, -8.905212e+000, 2.808596e+000, -9.537523e-002, -3.059702e+000, 5.403717e-001, -1.125653e+000, -1.904767e-001, 2.099998e+000, 1.251930e+000, -1.899312e+000, 5.255917e-001, 9.848033e-002, 9.627434e-001, 6.251233e-001, // albedo 1, turbidity 2 -1.115892e+000, -1.571450e-001, -5.361081e+000, 6.833528e+000, -6.891479e-002, 1.309709e+000, 6.046362e-002, 3.972373e+000, 6.651606e-001, -1.147479e+000, -1.855896e-001, 2.239259e+000, -5.937930e-001, -1.005125e-001, 2.773971e-001, 1.337105e-001, 3.136906e+000, 5.194230e-001, -1.030450e+000, -1.533626e-001, 2.268967e+000, -4.886576e-001, -6.336865e-001, 3.911080e+000, -1.602643e-001, 1.513730e-001, 1.130153e+000, -1.159297e+000, -5.818314e-002, -1.488690e-001, 1.358829e+000, 1.208889e+000, -1.827456e+000, 4.867277e-001, 6.185880e+000, 1.951064e-001, -1.023581e+000, -2.517540e-001, 3.635148e+000, -2.375150e+000, -9.409992e+000, 3.209554e+000, -3.006489e-001, -3.235953e+000, 9.969505e-001, -1.102864e+000, -1.644399e-001, 2.160645e+000, 5.685422e+000, -2.867248e+000, -1.020916e+000, 2.064591e-001, 1.192668e+000, 5.029621e-001, // albedo 1, turbidity 3 -1.120417e+000, -1.543428e-001, -2.173869e+000, 2.965267e+000, -1.062190e-001, 8.112859e-001, 1.448682e-001, 4.993622e+000, 6.373394e-001, -1.168618e+000, -1.948508e-001, -6.247560e-001, 2.203402e+000, -2.724794e-001, 8.364691e-001, 5.608377e-002, 4.262497e+000, 6.310098e-001, -1.080229e+000, -2.282841e-001, 2.194035e+000, -1.203336e+000, -3.861545e-001, 2.234045e+000, 1.553866e-001, -3.266039e+000, 8.246847e-001, -1.101698e+000, 2.182410e-002, -1.179116e+000, 8.533844e-001, 8.777171e-001, -1.222988e+000, 5.021882e-001, 9.364642e+000, 4.790363e-001, -1.047144e+000, -2.539571e-001, 3.684827e+000, 9.827861e-002, -2.297266e-001, 3.038327e+000, -2.609445e-001, -3.685112e+000, 8.596057e-001, -1.103227e+000, -1.861499e-001, 2.098952e+000, 1.030900e-001, -4.268311e+000, -1.120060e+000, 2.879792e-001, 7.160893e-001, 6.213207e-001, // albedo 1, turbidity 4 -1.155288e+000, -2.006105e-001, -5.822630e-002, 3.970794e-001, -2.828885e-001, 5.093569e-001, 1.631119e-001, 4.152479e+000, 6.357376e-001, -1.241627e+000, -2.673712e-001, -6.444494e-001, 2.257014e+000, -1.630843e+000, 5.967071e-001, 9.888683e-003, 4.308732e+000, 6.751366e-001, -1.136812e+000, -2.811418e-001, 2.220215e+000, -1.535870e+000, 2.354743e+000, 2.041362e+000, 2.387976e-001, -3.453756e+000, 7.672245e-001, -1.028322e+000, 9.134962e-002, -1.151053e+000, 6.511620e-001, -5.683098e+000, -2.001006e+000, 6.430642e-001, 8.523367e+000, 5.422240e-001, -1.076830e+000, -3.101207e-001, 3.052794e+000, 3.177593e-001, 3.054756e+000, 3.386727e+000, -2.312489e-001, -3.908802e+000, 7.978614e-001, -1.107083e+000, -1.880372e-001, 2.001810e+000, -3.352202e-003, -1.526356e+000, -1.480550e+000, 3.486524e-001, 7.220325e-001, 6.581821e-001, // albedo 1, turbidity 5 -1.214879e+000, -2.719222e-001, 2.247747e-001, 1.509740e-002, -5.438281e-001, 3.728351e-001, 1.749880e-001, 3.132220e+000, 6.001432e-001, -1.424202e+000, -4.768943e-001, -6.396040e-001, 2.060101e+000, -1.113780e+000, 6.993089e-001, -2.098291e-002, 2.504826e+000, 6.757213e-001, -1.048548e+000, -1.173837e-001, 1.885902e+000, -3.700301e+000, 4.667326e+000, 1.344798e+000, 2.140261e-001, 1.525414e-001, 8.450168e-001, -1.056271e+000, -5.272364e-002, -1.391708e+000, 9.711492e+000, -1.742761e+001, -1.677628e+000, 6.906304e-001, 4.107662e+000, 4.268005e-001, -1.072328e+000, -2.450563e-001, 3.125155e+000, -2.470389e+000, 6.794968e+000, 2.678049e+000, -2.092059e-001, -1.651858e+000, 8.708740e-001, -1.107628e+000, -2.089585e-001, 1.799168e+000, 4.621596e-001, -5.008181e+000, -1.121127e+000, 3.917217e-001, 2.703209e-001, 6.449597e-001, // albedo 1, turbidity 6 -1.249741e+000, -3.073987e-001, 1.398829e-001, -2.878563e-003, -5.008845e+000, 4.535605e-001, 1.447766e-001, 3.091173e+000, 6.138128e-001, -1.577209e+000, -6.213162e-001, 2.895282e-001, 1.670732e+000, 8.708786e+000, 2.480283e-001, 7.326386e-002, 1.395638e+000, 5.814691e-001, -1.015394e+000, -9.306378e-002, 4.870291e-001, -6.558243e+000, -1.073347e+001, 1.842159e+000, 2.135043e-002, 1.655269e+000, 9.750505e-001, -1.030222e+000, -3.712071e-002, -4.565649e-001, 1.827249e+001, -4.505703e+000, -2.635230e+000, 9.447498e-001, 2.450865e+000, 2.757082e-001, -1.086063e+000, -2.709359e-001, 2.527868e+000, -1.786375e+000, -2.329338e+000, 3.367729e+000, -4.201670e-001, -9.372873e-001, 9.570917e-001, -1.113156e+000, -2.162986e-001, 1.815038e+000, 1.036606e-001, -1.106537e+000, -1.657558e+000, 4.923976e-001, -1.768985e-002, 6.218745e-001, // albedo 1, turbidity 7 -1.345662e+000, -4.038158e-001, 1.601105e-001, -6.892546e-003, -5.010308e+000, 3.903794e-001, 1.543535e-001, 2.538245e+000, 5.555141e-001, -1.998866e+000, -9.786972e-001, 5.763250e-001, 1.007104e+000, 8.983795e+000, 3.752110e-001, 7.375525e-002, 1.792659e-001, 4.969463e-001, -7.854213e-001, 1.186171e-001, -1.925047e-001, -3.567464e+000, -8.901606e+000, 1.181923e+000, 4.049067e-002, 3.603602e+000, 1.081550e+000, -1.113558e+000, -1.964692e-001, -6.175963e-002, 7.345047e+000, -5.293662e+000, -1.720046e+000, 8.863695e-001, -1.699694e-001, 2.184709e-001, -1.077319e+000, -2.429937e-001, 2.226652e+000, 8.082352e+000, -5.647382e-001, 2.187018e+000, -3.571678e-001, -2.370890e-001, 9.528157e-001, -1.101702e+000, -2.020333e-001, 1.637670e+000, 5.276716e-001, -4.006007e+000, -1.066501e+000, 4.548015e-001, 4.055769e-001, 6.485706e-001, // albedo 1, turbidity 8 -1.411469e+000, -4.870956e-001, 1.017578e-001, -8.806763e-003, -5.014847e+000, 4.306981e-001, 1.278033e-001, 2.361142e+000, 5.472925e-001, -2.735007e+000, -1.453253e+000, 5.783189e-001, 5.673243e-001, 9.968637e+000, 2.236397e-001, 1.860109e-001, -3.781953e-001, 2.505082e-001, -7.371503e-001, 1.290592e-001, -5.349577e-001, -1.885854e+000, -8.623054e+000, 1.078614e+000, -5.694996e-002, 4.526279e+000, 1.347569e+000, -9.678370e-001, -2.562830e-001, 2.961987e-001, 2.461144e+000, -4.753928e+000, -1.657373e+000, 8.388825e-001, -2.440974e+000, 1.816225e-002, -1.148918e+000, -2.271366e-001, 1.817890e+000, 1.097345e+001, -1.126160e+000, 1.993895e+000, -2.870862e-001, 7.269217e-001, 1.032783e+000, -1.090291e+000, -2.315314e-001, 1.491197e+000, 9.632479e+000, -4.323932e+000, -1.326631e+000, 3.604933e-001, 1.905995e-001, 6.312241e-001, // albedo 1, turbidity 9 -1.552618e+000, -6.336918e-001, 4.605315e-002, -8.452985e-003, -4.979015e+000, 3.484674e-001, 8.791637e-002, 2.297399e+000, 5.705230e-001, -2.770597e+000, -1.302036e+000, 3.421676e-001, 1.220769e+000, 7.584372e+000, 4.050789e-001, 4.478808e-002, 9.435710e-001, 2.393878e-001, -2.631791e+000, -1.247576e+000, -8.423940e-001, -3.955998e+000, -5.341100e+000, 6.385142e-001, 3.872948e-001, 2.279807e+000, 1.101259e+000, 1.875824e-001, 3.564184e-001, 7.973268e-001, 7.159160e+000, -3.857340e+000, -9.227702e-001, 8.283793e-002, -1.444145e+000, 3.654244e-001, -1.489693e+000, -4.947623e-001, 1.253918e+000, 3.949282e+000, -1.320903e+000, 1.088652e+000, 1.489763e-001, -3.855853e-001, 8.130960e-001, -1.042349e+000, -2.134514e-001, 1.289359e+000, -3.129206e-003, -2.385397e+000, -7.642278e-001, 3.772293e-001, 3.683001e-001, 6.811674e-001, // albedo 1, turbidity 10 -1.924886e+000, -9.354584e-001, -1.879067e-001, 1.267892e+000, -1.174622e+000, 5.570232e-001, -1.060836e-005, 2.002481e+000, 9.001398e-001, -1.556107e+000, -8.200410e-001, -1.065249e-001, -3.241942e-001, 1.552504e-001, 7.662815e-002, -2.568474e-002, 1.738474e+000, -2.100942e-001, -7.169297e+000, -2.972878e+000, -1.324108e+000, 7.276378e-003, 2.638975e+000, 1.186150e+000, 5.695709e-001, 2.027718e+000, 1.328077e+000, 1.889259e+000, 2.600110e-001, 1.309033e+000, 1.187864e+000, -6.905754e+000, -1.163025e+000, -1.642758e-001, -1.774036e+000, 2.566466e-001, -1.816439e+000, -3.601966e-001, 6.367922e-001, 6.798160e+000, -6.431562e-001, 9.014269e-001, 2.490693e-001, -6.685128e-003, 8.542883e-001, -9.684886e-001, -3.866519e-001, 1.268224e+000, -4.187273e-003, -1.833316e+000, -4.626197e-001, 2.263859e-001, -5.583963e-001, 6.650112e-001, }; static float datasetRad640[] = { // albedo 0, turbidity 1 1.479989e-002, 9.575884e-003, 2.973854e-002, 4.822245e-002, 3.622965e-002, 3.714381e-002, // albedo 0, turbidity 2 1.494233e-002, 1.021187e-002, 2.574697e-002, 7.232352e-002, 3.290719e-002, 4.167409e-002, // albedo 0, turbidity 3 1.434641e-002, 1.147574e-002, 1.506677e-002, 1.142492e-001, 2.532042e-002, 4.995278e-002, // albedo 0, turbidity 4 1.326292e-002, 1.444403e-002, -7.612369e-003, 1.768500e-001, 1.846871e-002, 6.093428e-002, // albedo 0, turbidity 5 1.210064e-002, 1.800376e-002, -3.160469e-002, 2.285807e-001, 2.227077e-002, 6.824549e-002, // albedo 0, turbidity 6 1.130890e-002, 2.150486e-002, -5.124749e-002, 2.648020e-001, 2.123060e-002, 7.588774e-002, // albedo 0, turbidity 7 1.023130e-002, 2.633945e-002, -7.626006e-002, 3.042057e-001, 3.007536e-002, 8.597681e-002, // albedo 0, turbidity 8 8.913856e-003, 3.088076e-002, -9.896179e-002, 3.274618e-001, 6.060024e-002, 9.959796e-002, // albedo 0, turbidity 9 7.548425e-003, 3.088764e-002, -9.837988e-002, 2.862874e-001, 1.450480e-001, 1.121877e-001, // albedo 0, turbidity 10 6.525594e-003, 2.429771e-002, -6.656565e-002, 1.679199e-001, 2.792664e-001, 1.313366e-001, // albedo 1, turbidity 1 1.534297e-002, 1.199131e-002, 2.491229e-002, 5.492441e-002, 7.679650e-002, 9.300994e-002, // albedo 1, turbidity 2 1.542409e-002, 1.237811e-002, 2.235351e-002, 7.606092e-002, 7.888526e-002, 9.886009e-002, // albedo 1, turbidity 3 1.501351e-002, 1.379279e-002, 1.162514e-002, 1.159528e-001, 7.784537e-002, 1.097624e-001, // albedo 1, turbidity 4 1.398757e-002, 1.622679e-002, -9.033929e-003, 1.740587e-001, 8.042195e-002, 1.246928e-001, // albedo 1, turbidity 5 1.276036e-002, 2.055104e-002, -3.597123e-002, 2.310287e-001, 8.109251e-002, 1.421324e-001, // albedo 1, turbidity 6 1.198617e-002, 2.326685e-002, -5.243143e-002, 2.599544e-001, 8.840775e-002, 1.517899e-001, // albedo 1, turbidity 7 1.092344e-002, 2.669375e-002, -7.074274e-002, 2.830300e-001, 1.143047e-001, 1.610563e-001, // albedo 1, turbidity 8 9.699402e-003, 2.953350e-002, -8.582613e-002, 2.867195e-001, 1.638123e-001, 1.760228e-001, // albedo 1, turbidity 9 8.432894e-003, 2.784449e-002, -7.740437e-002, 2.250221e-001, 2.667103e-001, 1.889583e-001, // albedo 1, turbidity 10 7.395069e-003, 2.031820e-002, -4.154554e-002, 9.577204e-002, 4.084819e-001, 2.043633e-001, }; static float dataset680[] = { // albedo 0, turbidity 1 -1.112655e+000, -1.844098e-001, -3.170582e+000, 5.334685e+000, -6.690891e-002, 1.561122e+000, -2.792088e-006, 1.400688e+000, 6.639418e-001, -1.138469e+000, -1.797086e-001, 1.271179e+000, 1.158372e+000, -1.687824e-001, 1.414051e+000, 4.258569e-003, 2.135675e+000, 5.322718e-001, -1.026337e+000, -1.861539e-001, 2.119648e+000, -6.753200e-001, -1.972700e-001, 2.384659e+000, -1.304972e-002, -1.804518e+000, 1.207802e+000, -1.198321e+000, -1.585305e-001, 1.339219e+000, 5.796904e-001, -5.143433e-002, 1.107455e+000, 2.551349e-002, 3.346946e+000, -3.387602e-002, -9.935091e-001, -1.747698e-001, 2.816779e+000, -3.496148e-001, 1.832218e+000, 2.324658e+000, -3.408305e-002, -1.618451e+000, 1.189512e+000, -1.092682e+000, -1.840784e-001, 2.455887e+000, 1.441429e-001, -4.002347e+000, 1.186375e+000, 3.634755e-002, 3.070963e-001, 5.512501e-001, // albedo 0, turbidity 2 -1.104975e+000, -1.425541e-001, -1.889148e+000, 3.408593e+000, -1.252648e-001, 1.396095e+000, 8.358812e-002, 3.814297e+000, 6.848154e-001, -1.131570e+000, -1.500053e-001, -1.048539e+000, 3.133642e+000, -2.651219e-001, 1.193999e+000, 7.013543e-002, 4.592749e+000, 6.857750e-001, -1.030016e+000, -1.667752e-001, 6.179600e+000, -5.163198e+000, -4.084328e-001, 2.617798e+000, 1.966627e-003, -2.417731e+000, 8.402310e-001, -1.167563e+000, -3.644294e-002, -4.501893e+000, 4.471663e+000, -5.377956e-001, 4.971351e-002, 4.621337e-001, 1.014187e+001, 4.411276e-001, -1.018402e+000, -2.068288e-001, 4.710566e+000, -1.425858e+000, 1.287815e-001, 3.605281e+000, -2.164599e-001, -4.336932e+000, 9.051639e-001, -1.078985e+000, -1.995548e-001, 1.678948e+000, 3.074167e-001, -1.642830e+000, -1.235470e-001, 2.735898e-001, 6.360197e-001, 5.870665e-001, // albedo 0, turbidity 3 -1.132881e+000, -1.676238e-001, -1.179974e+000, 1.902080e+000, -7.980402e-002, 8.946611e-001, 1.939671e-001, 3.793414e+000, 6.357246e-001, -1.138356e+000, -1.681053e-001, 1.548320e+000, -6.001024e-001, -4.138892e-001, 2.586807e-001, 2.126762e-001, 4.742849e+000, 5.910253e-001, -1.093982e+000, -1.847904e-001, 1.234133e+000, -4.707125e-001, 1.076579e+000, 3.355751e+000, 5.394600e-002, -2.314910e+000, 8.900752e-001, -1.117812e+000, -6.182272e-002, -4.681118e-001, 5.075227e+000, -1.561122e+001, -2.343845e+000, 5.618788e-001, 7.005713e+000, 4.622191e-001, -1.013135e+000, -1.529086e-001, 1.960772e+000, -3.022528e+000, 8.938126e+000, 4.411437e+000, 3.156643e-002, -1.449180e+000, 8.181914e-001, -1.087086e+000, -2.231900e-001, 1.871061e+000, 1.830836e+000, -4.397140e+000, -5.441402e-001, 2.728682e-001, -5.607736e-002, 6.741811e-001, // albedo 0, turbidity 4 -1.176035e+000, -2.099056e-001, -8.221907e-001, 1.520994e+000, -2.507738e-001, 9.100863e-001, 1.507234e-001, 3.661138e+000, 6.726424e-001, -1.140180e+000, -1.918480e-001, 2.844393e-001, -3.842927e-001, -5.520764e-001, -1.868484e-001, 2.247948e-001, 5.381202e+000, 6.059726e-001, -1.282085e+000, -3.059464e-001, 1.619956e+000, -1.362117e+000, 2.324649e+000, 3.350678e+000, 2.102082e-001, -4.028753e+000, 8.172091e-001, -9.092985e-001, 4.843416e-002, -1.076741e+000, 8.143038e+000, -1.618418e+001, -3.681285e+000, 5.217800e-001, 7.307672e+000, 5.312006e-001, -1.110248e+000, -2.047143e-001, 1.565253e+000, -4.575474e+000, 8.737741e+000, 5.023419e+000, 2.469230e-001, -1.716906e+000, 7.856742e-001, -1.054900e+000, -2.018466e-001, 1.352034e+000, 2.656066e+000, -4.403444e+000, -1.479998e+000, 3.939305e-001, 6.455032e-001, 6.775162e-001, // albedo 0, turbidity 5 -1.237521e+000, -2.734963e-001, -4.554763e-001, 3.417711e-001, 2.054204e-001, 3.954470e-001, 2.366979e-001, 3.239693e+000, 6.083737e-001, -1.354583e+000, -4.251172e-001, -3.241668e-001, 2.077967e+000, -1.910410e+000, 8.755633e-001, -8.365829e-002, 2.443727e+000, 7.260119e-001, -1.152500e+000, -1.277879e-001, 1.089367e+000, -4.497520e+000, 5.636501e+000, 1.249272e+000, 5.829396e-001, 9.198423e-001, 7.039872e-001, -9.782313e-001, -8.253891e-002, -5.673470e-001, 1.098032e+001, -1.689550e+001, -1.619205e+000, 2.125660e-001, 2.080566e+000, 6.315535e-001, -1.064286e+000, -1.710957e-001, 9.336921e-001, -5.525059e+000, 8.053084e+000, 2.664602e+000, 4.815015e-001, 4.884965e-001, 7.093015e-001, -1.067798e+000, -1.817268e-001, 1.095720e+000, 3.551145e+000, -5.009504e+000, -4.802047e-001, 4.854159e-001, 8.021585e-001, 7.133339e-001, // albedo 0, turbidity 6 -1.251896e+000, -2.936510e-001, -3.090944e-002, -5.488869e-003, -6.577788e-001, 4.577691e-001, 1.780002e-001, 3.335561e+000, 6.394482e-001, -1.615603e+000, -6.405318e-001, -4.651954e-001, 2.332689e+000, -1.893131e-001, 3.391170e-001, 3.495888e-002, 1.058634e+000, 6.310524e-001, -9.703572e-001, 1.437971e-002, 6.532383e-001, -6.450045e+000, 4.026380e+000, 2.198628e+000, 2.684967e-001, 2.873804e+000, 8.626816e-001, -1.053437e+000, -1.577255e-001, -2.354526e-001, 1.753047e+001, -1.802766e+001, -3.193379e+000, 6.264380e-001, 3.733714e-001, 4.466776e-001, -1.051388e+000, -1.690749e-001, 6.925698e-001, -7.450365e+000, 7.747780e+000, 3.681960e+000, 1.688173e-001, 9.054528e-001, 8.229209e-001, -1.060369e+000, -1.751603e-001, 8.678290e-001, 5.136962e+000, -5.014566e+000, -1.283438e+000, 6.547844e-001, 9.420523e-001, 6.738511e-001, // albedo 0, turbidity 7 -1.358251e+000, -3.909003e-001, -7.590093e-002, -8.010253e-003, -2.417641e-001, 5.031789e-001, 1.882499e-001, 2.807060e+000, 5.884485e-001, -2.043506e+000, -9.923881e-001, -4.530797e-001, 1.750575e+000, -4.362236e-001, 2.997323e-001, 2.328504e-002, 1.626543e-001, 5.806819e-001, -7.280672e-001, 2.228069e-001, 2.169765e-001, -3.681736e+000, 4.308793e+000, 1.308622e+000, 3.451835e-001, 4.037459e+000, 9.113772e-001, -1.155299e+000, -3.079453e-001, -1.640569e-001, 7.663297e+000, -1.327817e+001, -1.431157e+000, 4.096359e-001, -9.185502e-001, 4.578034e-001, -1.006427e+000, -1.250087e-001, 7.477012e-001, 2.612704e+000, 2.531799e+000, 1.565371e+000, 3.452604e-001, 9.129266e-001, 7.684386e-001, -1.068759e+000, -1.729191e-001, 5.265652e-001, 7.074812e+000, -4.259958e+000, -4.833255e-001, 6.043380e-001, 1.489203e+000, 7.089074e-001, // albedo 0, turbidity 8 -1.398983e+000, -4.500153e-001, -5.189309e-001, 1.546325e-001, 4.187327e-001, 2.811516e-001, 2.379667e-001, 2.801040e+000, 5.198375e-001, -2.970455e+000, -1.529948e+000, 1.094532e-001, 7.382263e-001, -1.024683e+000, 2.074091e-001, 1.397605e-001, -6.743828e-001, 3.496944e-001, -3.942086e-001, 3.424842e-001, -1.253259e+000, -9.268654e-001, 5.636065e+000, 8.224289e-001, 2.452235e-001, 5.864258e+000, 1.202820e+000, -1.181174e+000, -4.197175e-001, 1.429102e+000, -7.894317e-003, -1.239152e+001, -5.753431e-001, 3.552180e-001, -4.495555e+000, 2.141883e-001, -1.060281e+000, -1.080598e-001, -3.276480e-001, 1.369250e+001, 1.504389e+000, 6.401191e-001, 2.437501e-001, 3.212918e+000, 9.172133e-001, -1.037564e+000, -2.018083e-001, 6.250668e-001, -2.525843e-003, -3.269998e+000, -2.649814e-001, 6.600589e-001, 3.337508e-001, 6.516131e-001, // albedo 0, turbidity 9 -1.610481e+000, -6.353902e-001, -5.968977e-001, 1.414037e+000, -7.941453e-001, 7.888684e-001, 2.209045e-002, 2.615106e+000, 6.870260e-001, -3.073343e+000, -1.365905e+000, -2.651943e-001, -1.685310e+000, 4.755874e-001, -1.110669e-001, 2.561961e-001, 1.222045e+000, 3.362780e-002, -2.207768e+000, -1.009608e+000, -1.329601e+000, 3.393091e+000, 3.419104e+000, -4.733375e-002, 5.989185e-001, 2.814641e+000, 1.245189e+000, -1.981173e-002, 2.018414e-001, 1.457765e+000, -6.316169e+000, -6.640569e+000, 7.150646e-001, -2.993748e-001, -2.703376e+000, 3.218596e-001, -1.435873e+000, -3.390505e-001, -3.859047e-001, 1.457464e+001, -1.121591e+000, -6.089868e-002, 5.319220e-001, 1.852395e+000, 8.379521e-001, -9.812568e-001, -2.273751e-001, 5.108069e-001, -3.735693e-003, -2.547988e+000, -4.492561e-001, 5.069199e-001, 2.977910e-001, 6.639273e-001, // albedo 0, turbidity 10 -2.056405e+000, -9.703512e-001, -3.731953e-001, 2.052022e+000, -1.445283e+000, 6.103743e-001, -9.389644e-006, 2.198652e+000, 8.567335e-001, -2.105651e+000, -8.924283e-001, -6.868702e-001, -1.665838e+000, 4.795702e-001, 5.228080e-001, -4.272483e-002, 2.661317e+000, -1.154062e-001, -6.179767e+000, -2.651580e+000, -1.527652e+000, 2.692054e+000, 2.293427e+000, -1.005611e-001, 9.545323e-001, 1.367438e+000, 1.169193e+000, 1.240848e+000, 1.126706e-001, 1.620422e+000, -3.384604e+000, -5.545532e+000, 4.928203e-001, -5.999585e-001, -1.407078e+000, 4.193816e-001, -1.539149e+000, -2.081890e-001, -4.552234e-001, 1.056410e+001, -1.048637e+000, -2.780921e-001, 5.682296e-001, 6.785092e-001, 7.729892e-001, -1.036841e+000, -4.359099e-001, 4.767834e-001, -3.794262e-003, -1.980492e+000, 9.954067e-002, 3.037557e-001, 2.156592e-002, 6.845201e-001, // albedo 1, turbidity 1 -1.110980e+000, -1.799491e-001, -3.168600e+000, 5.336662e+000, -6.318131e-002, 1.559251e+000, 3.204341e-003, 1.401140e+000, 6.638144e-001, -1.132332e+000, -1.786787e-001, 1.272954e+000, 1.160211e+000, -1.685885e-001, 1.409550e+000, 7.140682e-003, 2.136473e+000, 5.320908e-001, -1.015776e+000, -1.825058e-001, 2.122848e+000, -6.725506e-001, -1.976294e-001, 2.376807e+000, -1.859856e-002, -1.803033e+000, 1.207528e+000, -1.189845e+000, -1.509036e-001, 1.345709e+000, 5.832609e-001, -5.130839e-002, 1.097035e+000, 2.686911e-002, 3.349361e+000, -3.431297e-002, -1.000281e+000, -1.696328e-001, 2.829408e+000, -3.466041e-001, 1.832532e+000, 2.314637e+000, -2.721994e-002, -1.614939e+000, 1.188720e+000, -1.120411e+000, -1.974172e-001, 2.474172e+000, 1.453506e-001, -4.002206e+000, 1.180333e+000, 2.229171e-002, 3.112615e-001, 5.505539e-001, // albedo 1, turbidity 2 -1.112667e+000, -1.574855e-001, -2.284814e+000, 4.255050e+000, -1.386097e-001, 1.459506e+000, 4.508931e-002, 2.944474e+000, 7.339984e-001, -1.113577e+000, -1.331062e-001, -1.828757e+000, 3.910596e+000, -2.095519e-001, 1.159335e+000, 9.311608e-002, 4.517295e+000, 6.365313e-001, -1.061651e+000, -2.007134e-001, 5.907472e+000, -4.808769e+000, -2.120206e-001, 2.727568e+000, -4.222666e-002, -2.599674e+000, 9.265659e-001, -1.136633e+000, -4.281875e-003, -3.407541e+000, 4.132332e+000, -3.866153e-001, -5.082717e-001, 4.828348e-001, 9.797167e+000, 3.325034e-001, -1.027909e+000, -2.334388e-001, 4.972147e+000, -1.499736e+000, 9.598438e-002, 2.744895e+000, -3.558702e-001, -4.288054e+000, 1.000138e+000, -1.102843e+000, -1.875642e-001, 2.087760e+000, 3.692600e-001, -6.520835e-001, -9.598766e-001, 2.984231e-001, 4.045786e-001, 5.091931e-001, // albedo 1, turbidity 3 -1.117485e+000, -1.492968e-001, -2.639425e+000, 3.672106e+000, -1.058342e-001, 1.098101e+000, 1.544782e-001, 4.496691e+000, 6.582312e-001, -1.123872e+000, -1.467158e-001, 3.049045e+000, -2.607634e+000, -2.505495e-001, -8.310458e-002, 3.333822e-001, 4.631418e+000, 5.120491e-001, -1.118262e+000, -2.462050e-001, -8.333919e-002, 2.438788e+000, 6.143236e-001, 3.745903e+000, -2.043295e-001, -3.451983e+000, 1.056003e+000, -1.095394e+000, 2.009680e-002, 8.468659e-001, 1.230624e-002, -8.638525e+000, -2.989487e+000, 8.735734e-001, 8.533740e+000, 2.548062e-001, -1.035035e+000, -2.296018e-001, 2.722309e+000, 1.849369e-001, 3.440975e+000, 4.372083e+000, -4.747494e-001, -2.984092e+000, 1.009737e+000, -1.113497e+000, -1.931400e-001, 2.288509e+000, 4.973129e-002, -1.353292e-001, -1.587772e+000, 4.073801e-001, -8.180513e-003, 5.682569e-001, // albedo 1, turbidity 4 -1.172242e+000, -2.084847e-001, -1.212027e+000, 1.991627e+000, -1.403495e-001, 7.684996e-001, 1.582914e-001, 3.407597e+000, 6.659386e-001, -1.167834e+000, -2.117291e-001, 1.196578e+000, -1.438719e+000, -3.137939e-001, -4.537552e-002, 2.260096e-001, 4.659389e+000, 5.776369e-001, -1.222298e+000, -2.893306e-001, 9.080116e-001, 1.413518e+000, 1.709237e+000, 2.915962e+000, 8.464584e-002, -3.867076e+000, 9.110543e-001, -9.554071e-001, 6.610246e-002, -3.323811e-001, 2.702543e+000, -1.345592e+001, -3.119309e+000, 7.740473e-001, 7.452516e+000, 3.929172e-001, -1.119763e+000, -2.579942e-001, 2.830634e+000, -1.333418e+000, 6.825773e+000, 4.230596e+000, -2.654108e-001, -2.669457e+000, 9.126183e-001, -1.084261e+000, -2.086570e-001, 2.248616e+000, 6.993871e-001, -2.391760e+000, -1.738827e+000, 3.674794e-001, -5.324741e-001, 6.183292e-001, // albedo 1, turbidity 5 -1.226325e+000, -2.688667e-001, -1.462040e-001, 4.749868e-001, -8.718681e-002, 4.956704e-001, 1.752427e-001, 2.933911e+000, 6.470198e-001, -1.359737e+000, -3.985716e-001, -1.570034e-001, 1.277905e+000, -1.314322e+000, 4.320873e-001, 8.532731e-002, 2.774395e+000, 6.318556e-001, -1.088212e+000, -1.688766e-001, 1.399098e+000, -3.254950e+000, 4.733557e+000, 2.079183e+000, 1.907990e-001, -9.540048e-001, 8.714774e-001, -1.034524e+000, -1.050729e-002, -8.054376e-001, 1.166351e+001, -1.879498e+001, -3.021428e+000, 7.755251e-001, 4.516574e+000, 4.092690e-001, -1.076150e+000, -2.551781e-001, 2.797790e+000, -5.437950e+000, 9.156159e+000, 3.988462e+000, -2.324172e-001, -2.124766e+000, 8.863276e-001, -1.103432e+000, -2.058047e-001, 2.117130e+000, 2.401558e+000, -5.015370e+000, -1.829480e+000, 4.046378e-001, -2.078794e-001, 6.449045e-001, // albedo 1, turbidity 6 -1.263516e+000, -3.133966e-001, 3.174560e-001, -4.989246e-003, -2.317630e+000, 3.963746e-001, 1.677262e-001, 2.563898e+000, 6.335899e-001, -1.577927e+000, -5.893907e-001, -2.991531e-001, 1.783728e+000, 3.693827e+000, 5.704918e-001, 6.768069e-002, 2.215180e+000, 6.196162e-001, -9.191335e-001, -4.529201e-002, 1.577262e+000, -6.455191e+000, -4.020064e+000, 1.309911e+000, 1.373281e-001, -7.178508e-001, 9.243738e-001, -1.144508e+000, -9.289247e-002, -1.606387e+000, 2.061805e+001, -1.051527e+001, -2.077164e+000, 8.328239e-001, 4.729795e+000, 3.298487e-001, -1.018834e+000, -2.186851e-001, 3.321767e+000, -7.887012e+000, 3.374834e+000, 3.005232e+000, -2.515037e-001, -2.656610e+000, 9.316017e-001, -1.125230e+000, -2.422532e-001, 1.850916e+000, 6.213105e+000, -5.017914e+000, -1.644457e+000, 3.811828e-001, -1.772362e-001, 6.297360e-001, // albedo 1, turbidity 7 -1.365631e+000, -4.017085e-001, 1.942501e-001, -7.073927e-003, -1.461125e-001, 4.898017e-001, 1.623346e-001, 2.330174e+000, 5.983242e-001, -1.957177e+000, -9.640834e-001, -2.217521e-001, 1.316645e+000, -1.907085e-001, 1.134191e-002, 9.704476e-002, 3.828565e-002, 5.538419e-001, -7.832629e-001, 1.949904e-001, 6.232354e-001, -2.947737e+000, 3.702377e+000, 2.212239e+000, 9.128296e-002, 3.131504e+000, 9.923939e-001, -1.121562e+000, -2.704893e-001, -5.161748e-001, 8.115427e+000, -1.443497e+001, -3.292676e+000, 8.232212e-001, -1.548451e-002, 3.199244e-001, -1.059207e+000, -1.613941e-001, 2.375866e+000, -9.517705e-002, 4.514722e+000, 3.755824e+000, -1.696953e-001, -2.539157e-001, 8.992553e-001, -1.108877e+000, -2.404852e-001, 1.830175e+000, 2.808956e+000, -4.932362e+000, -2.042775e+000, 4.168739e-001, -2.534590e-001, 6.533212e-001, // albedo 1, turbidity 8 -1.405398e+000, -4.540068e-001, -4.766512e-001, 1.871207e-001, 5.535070e-001, -4.467365e-002, 2.846366e-001, 2.443422e+000, 5.035706e-001, -2.843953e+000, -1.562366e+000, 8.527921e-001, 5.991182e-001, -9.984088e-001, 7.599314e-001, -2.025184e-002, -1.515050e+000, 4.397429e-001, -5.156586e-001, 3.789775e-001, -1.194407e+000, -7.591558e-001, 4.515532e+000, 4.795814e-001, 3.163186e-001, 5.993132e+000, 1.096327e+000, -1.070353e+000, -4.037269e-001, 1.108932e+000, 1.269159e+000, -1.099135e+001, -1.049849e+000, 4.644725e-001, -4.387074e+000, 2.704008e-001, -1.136211e+000, -1.473182e-001, 1.235769e+000, 5.725364e+000, 1.712036e+000, 1.630777e+000, 3.656685e-002, 2.082798e+000, 9.036801e-001, -1.083101e+000, -2.468910e-001, 1.894919e+000, 6.574012e+000, -4.949098e+000, -1.132033e+000, 3.336584e-001, -7.321133e-001, 6.606587e-001, // albedo 1, turbidity 9 -1.609910e+000, -6.550380e-001, -5.773346e-001, 1.426156e+000, -5.000686e-001, 8.257866e-001, 1.839148e-002, 2.106656e+000, 6.957214e-001, -3.047283e+000, -1.421592e+000, -4.003615e-001, -6.531692e-001, 5.643821e-001, -2.693762e-001, 2.295553e-001, 5.533910e-001, 2.751822e-002, -2.160824e+000, -9.212504e-001, -8.438420e-001, 1.466021e+000, 1.124686e+000, -6.848173e-002, 6.224893e-001, 3.137662e+000, 1.224147e+000, 1.444817e-002, 1.418426e-001, 7.055176e-001, -1.787432e+000, -1.625625e+000, 7.638401e-001, -3.309940e-001, -3.414755e+000, 3.580691e-001, -1.480512e+000, -3.141638e-001, 1.193403e+000, 6.152773e+000, -3.314867e+000, 1.345353e-001, 5.359935e-001, 1.409582e+000, 8.072343e-001, -1.016066e+000, -2.346375e-001, 1.457587e+000, -2.761458e-003, -2.546952e+000, -6.058542e-001, 3.134230e-001, -2.232281e-001, 6.760089e-001, // albedo 1, turbidity 10 -2.019395e+000, -9.550942e-001, -1.187885e-001, 1.995372e+000, -1.604228e+000, 4.995785e-001, -9.647137e-006, 1.929333e+000, 8.659254e-001, -2.071307e+000, -9.485438e-001, -3.817151e-001, -1.657017e+000, 9.488626e-001, 5.816145e-001, -3.856514e-002, 1.677756e+000, -1.262572e-001, -6.388445e+000, -2.738739e+000, -9.872469e-001, 2.450058e+000, 1.075999e+000, 2.305434e-002, 8.598771e-001, 1.853582e+000, 1.180017e+000, 1.742851e+000, 2.950102e-001, 1.015937e+000, -2.511194e+000, -3.829361e+000, -1.126698e-001, -4.564605e-001, -2.097128e+000, 4.012648e-001, -1.845177e+000, -3.242819e-001, 7.060963e-001, 7.747868e+000, -1.721532e+000, 6.057347e-001, 4.266212e-001, 3.153697e-001, 7.958222e-001, -9.599955e-001, -3.732025e-001, 1.381129e+000, -3.983023e-003, -1.941446e+000, -5.943490e-001, 2.269207e-001, -7.249738e-001, 6.710888e-001, }; static float datasetRad680[] = { // albedo 0, turbidity 1 1.320908e-002, 9.179272e-003, 2.540842e-002, 3.413687e-002, 2.736575e-002, 2.799241e-002, // albedo 0, turbidity 2 1.364418e-002, 9.639315e-003, 2.455688e-002, 5.468867e-002, 2.423200e-002, 3.240293e-002, // albedo 0, turbidity 3 1.356642e-002, 9.864007e-003, 2.017166e-002, 8.738638e-002, 2.138981e-002, 3.828822e-002, // albedo 0, turbidity 4 1.274664e-002, 1.046958e-002, 7.076299e-003, 1.378101e-001, 2.058352e-002, 4.607358e-002, // albedo 0, turbidity 5 1.151617e-002, 1.429568e-002, -1.804673e-002, 1.974118e-001, 1.313176e-002, 5.733295e-002, // albedo 0, turbidity 6 1.089311e-002, 1.719127e-002, -3.582843e-002, 2.315641e-001, 1.402940e-002, 6.289477e-002, // albedo 0, turbidity 7 9.705879e-003, 2.218462e-002, -6.221073e-002, 2.771148e-001, 1.651339e-002, 7.346287e-002, // albedo 0, turbidity 8 8.356372e-003, 2.724501e-002, -8.836051e-002, 3.099528e-001, 4.114206e-002, 8.518889e-002, // albedo 0, turbidity 9 7.026434e-003, 2.944084e-002, -9.824183e-002, 2.940735e-001, 1.048477e-001, 1.012199e-001, // albedo 0, turbidity 10 5.935885e-003, 2.429070e-002, -7.239967e-002, 1.895904e-001, 2.306596e-001, 1.177261e-001, // albedo 1, turbidity 1 1.370741e-002, 1.011873e-002, 2.499587e-002, 3.362880e-002, 6.416750e-002, 6.673258e-002, // albedo 1, turbidity 2 1.417558e-002, 1.065771e-002, 2.402602e-002, 5.330606e-002, 6.505571e-002, 7.324558e-002, // albedo 1, turbidity 3 1.406012e-002, 1.182138e-002, 1.636956e-002, 9.161153e-002, 6.031840e-002, 8.638638e-002, // albedo 1, turbidity 4 1.321071e-002, 1.310944e-002, 1.017467e-003, 1.450040e-001, 6.291618e-002, 1.003625e-001, // albedo 1, turbidity 5 1.194910e-002, 1.687076e-002, -2.332212e-002, 2.021394e-001, 6.093196e-002, 1.177929e-001, // albedo 1, turbidity 6 1.126778e-002, 1.905450e-002, -3.804088e-002, 2.298767e-001, 7.038318e-002, 1.240367e-001, // albedo 1, turbidity 7 1.025282e-002, 2.337214e-002, -6.236283e-002, 2.708195e-001, 7.801793e-002, 1.406577e-001, // albedo 1, turbidity 8 9.018216e-003, 2.718840e-002, -8.215497e-002, 2.866465e-001, 1.194106e-001, 1.556975e-001, // albedo 1, turbidity 9 7.747698e-003, 2.701679e-002, -8.076599e-002, 2.419548e-001, 2.126954e-001, 1.683085e-001, // albedo 1, turbidity 10 6.701188e-003, 2.085440e-002, -5.068221e-002, 1.256935e-001, 3.480598e-001, 1.851691e-001, }; static float dataset720[] = { // albedo 0, turbidity 1 -1.110553e+000, -1.675726e-001, -2.349324e-001, 2.433790e+000, -1.342878e-001, 1.755516e+000, -1.879493e-006, 1.509217e+000, 7.216495e-001, -1.149960e+000, -2.418229e-001, 2.341927e+000, 1.486508e-001, -4.333388e-001, 9.028740e-001, 9.450710e-003, -3.134790e-001, 5.923234e-001, -9.702430e-001, -5.384657e-002, 3.025898e+000, -6.450284e-001, 9.728166e-001, 3.532967e+000, -2.429753e-002, 1.343614e+000, 1.067807e+000, -1.278773e+000, -2.072018e-001, -2.458359e-001, 3.749133e-001, -9.580484e+000, 3.066020e-001, 4.056471e-002, 4.343208e+000, 1.865704e-001, -9.511618e-001, -1.674143e-001, 4.195842e+000, -1.205785e-001, 2.160133e+000, 3.048813e+000, -4.826924e-002, -3.779096e+000, 1.024834e+000, -1.095577e+000, -1.855865e-001, 1.973593e+000, 7.894097e-002, 9.578182e-001, 8.565674e-001, 4.663966e-002, 7.375811e-001, 5.577192e-001, // albedo 0, turbidity 2 -1.099352e+000, -1.338612e-001, -8.419373e-001, 2.710346e+000, -2.241044e-001, 1.645463e+000, 7.621625e-002, 3.548772e+000, 7.268231e-001, -1.140694e+000, -1.723890e-001, 1.413194e+000, 3.429051e-001, -4.431396e-001, 9.757402e-001, 1.248306e-001, 1.780103e+000, 6.637254e-001, -9.861499e-001, -8.032931e-002, 2.396682e+000, 7.281382e-001, 1.472495e-001, 3.316479e+000, -1.028439e-001, 3.729469e+000, 9.059004e-001, -1.233397e+000, -9.896833e-002, -1.679568e+000, 1.542653e+000, -9.977726e+000, -6.579124e-001, 6.386315e-001, 6.157752e+000, 3.985939e-001, -9.438092e-001, -1.629239e-001, 4.213446e+000, -3.419684e-001, 2.110121e+000, 3.552183e+000, -2.817116e-001, -3.323718e+000, 8.785077e-001, -1.120794e+000, -2.121477e-001, 1.326767e+000, 2.317528e-001, 5.648291e-001, 4.155089e-001, 3.048162e-001, 3.186797e-001, 6.285665e-001, // albedo 0, turbidity 3 -1.117191e+000, -1.510453e-001, -3.511136e-001, 1.706946e+000, -3.820460e-001, 1.228101e+000, 1.641555e-001, 3.663544e+000, 6.846104e-001, -1.130950e+000, -1.622534e-001, 1.197076e+000, -1.342532e+000, 6.608991e-002, -1.955817e-001, 3.515286e-001, 3.237403e+000, 5.732364e-001, -1.103903e+000, -1.810472e-001, 1.254237e+000, 3.367565e+000, -1.746589e+000, 4.464939e+000, -2.831757e-001, -2.424241e-001, 9.961252e-001, -1.107818e+000, -2.407723e-002, -7.518594e-001, 7.115830e+000, -1.603375e+001, -4.077248e+000, 1.210904e+000, 6.281392e+000, 2.496837e-001, -1.012153e+000, -1.911658e-001, 2.357463e+000, -2.392720e+000, 7.080581e+000, 6.002768e+000, -5.120158e-001, -2.039879e+000, 1.008071e+000, -1.083766e+000, -1.889743e-001, 1.669813e+000, 1.205140e+000, -2.973102e+000, -1.420288e+000, 5.838643e-001, 1.338574e-001, 5.902153e-001, // albedo 0, turbidity 4 -1.176390e+000, -2.045914e-001, -1.035177e+000, 1.521425e+000, -9.698257e-002, 7.561111e-001, 2.338582e-001, 3.264500e+000, 6.520267e-001, -1.132876e+000, -1.921539e-001, 9.661015e-001, -2.470184e-001, -5.825797e-001, 5.044517e-001, 1.418233e-001, 4.416172e+000, 6.580570e-001, -1.296062e+000, -2.855719e-001, 1.143329e+000, -1.640682e+000, 1.921828e+000, 1.625086e+000, 5.248871e-001, -3.757434e+000, 7.293814e-001, -9.026255e-001, 2.670242e-002, -8.632572e-001, 7.076787e+000, -1.407525e+001, -1.251814e+000, 1.806495e-001, 6.575978e+000, 6.367149e-001, -1.103623e+000, -1.818983e-001, 1.490037e+000, -3.276017e+000, 6.936153e+000, 2.689183e+000, 5.705211e-001, -1.354153e+000, 7.095230e-001, -1.049370e+000, -1.854814e-001, 1.385509e+000, 1.714977e+000, -3.205204e+000, -1.161420e-001, 3.453320e-001, 4.355508e-001, 7.115006e-001, // albedo 0, turbidity 5 -1.225291e+000, -2.574996e-001, -4.766919e-001, 4.951357e-001, 5.242961e-002, 4.702062e-001, 2.428653e-001, 3.095075e+000, 6.424221e-001, -1.318856e+000, -3.713082e-001, -4.987985e-001, 2.026237e+000, -1.457426e+000, 7.809557e-001, 1.419197e-003, 2.776845e+000, 7.058454e-001, -1.168038e+000, -1.572586e-001, 1.786834e+000, -4.594005e+000, 4.780600e+000, 1.639416e+000, 5.324063e-001, -1.000719e+000, 7.325083e-001, -9.862998e-001, -7.482649e-002, -1.332445e+000, 1.329260e+001, -1.803019e+001, -2.669936e+000, 3.591475e-001, 3.852972e+000, 5.714399e-001, -1.049025e+000, -1.404280e-001, 1.342894e+000, -5.633938e+000, 8.396123e+000, 3.809869e+000, 4.313231e-001, -5.373938e-001, 7.693298e-001, -1.069033e+000, -2.091865e-001, 1.088280e+000, 3.125506e+000, -4.664580e+000, -1.191484e+000, 5.195344e-001, 3.961673e-001, 6.817393e-001, // albedo 0, turbidity 6 -1.267895e+000, -3.004228e-001, -5.149611e-001, 4.302967e-001, 1.504018e-001, 3.700643e-001, 2.354209e-001, 2.887788e+000, 6.298388e-001, -1.551925e+000, -5.917820e-001, -5.915642e-001, 2.016019e+000, -1.252286e+000, 8.651065e-001, 7.721402e-003, 1.148828e+000, 6.589887e-001, -9.782795e-001, 3.652455e-002, 1.331304e+000, -4.804135e+000, 5.130801e+000, 1.052586e+000, 4.439877e-001, 2.100157e+000, 8.308236e-001, -1.077598e+000, -2.015253e-001, -1.037818e+000, 1.307045e+001, -1.715211e+001, -1.607252e+000, 4.472382e-001, 6.802371e-001, 4.848934e-001, -1.025969e+000, -1.170376e-001, 1.139546e+000, -3.374680e+000, 6.330035e+000, 2.199093e+000, 3.928627e-001, 8.428666e-001, 7.960910e-001, -1.062382e+000, -1.881842e-001, 8.863153e-001, 4.266858e+000, -5.011692e+000, -4.086830e-001, 5.889147e-001, 5.341939e-001, 6.866073e-001, // albedo 0, turbidity 7 -1.352417e+000, -3.836953e-001, -5.951560e-001, 4.053297e-001, 2.468304e-001, 2.565711e-001, 2.321365e-001, 2.512376e+000, 6.089904e-001, -1.976438e+000, -9.152777e-001, -4.417666e-001, 1.790189e+000, -1.085567e+000, 4.562228e-001, 2.133332e-002, 4.989856e-001, 6.257100e-001, -7.197412e-001, 2.165210e-001, 6.233215e-001, -3.960686e+000, 4.694083e+000, 2.062797e+000, 3.121864e-001, 2.942681e+000, 8.846033e-001, -1.189984e+000, -3.151612e-001, -5.020073e-001, 1.015136e+001, -1.483684e+001, -3.476730e+000, 6.049863e-001, -1.941153e-001, 4.281015e-001, -9.781383e-001, -8.764833e-002, 8.290915e-001, 1.086960e-001, 4.467570e+000, 3.905633e+000, 1.975895e-001, 6.964295e-001, 8.333166e-001, -1.081242e+000, -2.051949e-001, 6.056482e-001, 5.219268e+000, -4.410608e+000, -1.963212e+000, 7.277904e-001, 8.509624e-001, 6.689251e-001, // albedo 0, turbidity 8 -1.443212e+000, -4.725757e-001, -9.477961e-001, 2.671049e-001, 6.163577e-001, -3.965036e-001, 4.071134e-001, 2.464218e+000, 4.997820e-001, -3.021428e+000, -1.558459e+000, 1.389763e-001, 1.122031e+000, -1.014816e+000, 1.265687e+000, -1.649604e-001, -6.627923e-001, 5.494665e-001, -1.593477e-001, 5.076305e-001, -7.283933e-001, -1.265076e+000, 3.904153e+000, -8.196757e-002, 6.585734e-001, 4.998464e+000, 9.330667e-001, -1.378374e+000, -5.064534e-001, 7.231197e-001, 1.385088e+000, -9.500118e+000, -4.806746e-001, 1.067642e-001, -3.297209e+000, 4.441955e-001, -9.436176e-001, -6.189764e-002, 1.144482e-001, 9.137694e+000, 2.948867e-001, 1.224655e+000, 3.675148e-001, 2.124090e+000, 8.014519e-001, -1.078915e+000, -2.051854e-001, 4.754209e-001, 5.826389e-003, -2.498632e+000, -8.265078e-001, 7.644670e-001, 6.066256e-001, 6.811963e-001, // albedo 0, turbidity 9 -1.621711e+000, -6.425839e-001, -7.307813e-001, 1.109519e+000, -4.107299e-001, 7.789953e-001, 7.764812e-002, 2.335627e+000, 6.230915e-001, -4.003597e+000, -1.736865e+000, -6.062450e-001, -7.370264e-001, 7.002778e-001, -4.140325e-001, 3.926087e-001, 8.316399e-001, 1.516341e-001, -7.696712e-001, -3.872306e-001, -1.159436e+000, 1.660752e+000, 2.031840e+000, -7.697685e-001, 5.481684e-001, 2.788249e+000, 1.112977e+000, -8.506589e-001, -5.430791e-002, 1.088719e+000, -2.513532e+000, -4.144477e+000, 2.760914e+000, -3.011272e-001, -2.383556e+000, 4.496070e-001, -1.150061e+000, -3.009215e-001, -9.176868e-002, 8.996074e+000, -1.753862e+000, -2.428423e+000, 5.764492e-001, 1.218492e+000, 7.552230e-001, -1.020853e+000, -1.499849e-001, 3.437744e-001, -2.339597e-003, -2.646520e+000, 1.378457e+000, 6.708410e-001, 9.149680e-001, 6.961806e-001, // albedo 0, turbidity 10 -1.982394e+000, -9.369621e-001, -3.767595e-001, 2.514582e+000, -1.501415e+000, 6.258952e-001, -5.260430e-006, 2.100142e+000, 7.824077e-001, -3.432415e+000, -1.264283e+000, -9.042363e-001, -2.930432e+000, 8.249096e-001, 7.244840e-001, 3.055253e-002, 2.527405e+000, -2.107031e-003, -4.333533e+000, -2.156157e+000, -8.341654e-001, 5.048387e+000, 1.803580e+000, -9.318434e-001, 1.085401e+000, 8.728330e-001, 1.050061e+000, 4.889224e-001, 5.956721e-002, 8.445388e-001, -7.479177e+000, -4.049292e+000, 1.199966e+000, -7.060560e-001, -9.742353e-001, 4.893674e-001, -1.347508e+000, -1.874523e-001, -5.063342e-002, 1.299813e+001, -1.707387e+000, -4.076088e-001, 6.119042e-001, 3.717790e-001, 7.662157e-001, -1.047037e+000, -3.743109e-001, 3.452375e-001, -3.615559e-003, -2.169432e+000, -7.166880e-002, 3.747046e-001, 2.746126e-001, 6.773818e-001, // albedo 1, turbidity 1 -1.105396e+000, -1.663441e-001, -2.359634e-001, 2.476496e+000, -1.329052e-001, 1.715759e+000, 2.103991e-003, 1.421966e+000, 6.270733e-001, -1.132480e+000, -2.330883e-001, 2.273938e+000, 2.422717e-001, -4.159883e-001, 9.350714e-001, 1.432347e-002, -4.176684e-001, 4.664640e-001, -1.036155e+000, -9.432450e-002, 3.117262e+000, -6.369808e-001, 1.060389e+000, 3.386481e+000, -4.605081e-002, 1.248000e+000, 9.701974e-001, -1.162485e+000, -1.382303e-001, 1.544122e-001, 3.716511e-001, -9.520209e+000, -2.739605e-001, 8.489054e-002, 4.371570e+000, 7.694391e-002, -1.031787e+000, -2.165067e-001, 4.446666e+000, -1.470711e-001, 2.143436e+000, 1.922123e+000, -9.589030e-002, -3.594664e+000, 8.629249e-001, -1.081125e+000, -1.623953e-001, 2.048137e+000, 8.639386e-002, 1.225845e+000, 1.239255e-001, 8.366038e-002, 8.322625e-001, 5.604708e-001, // albedo 1, turbidity 2 -1.112606e+000, -1.514491e-001, -1.608942e+000, 3.592344e+000, -1.616115e-001, 1.593861e+000, 5.488306e-002, 2.854783e+000, 7.519999e-001, -1.098630e+000, -1.410161e-001, 2.155487e+000, -4.381610e-001, -3.635146e-001, 1.313843e+000, 1.201277e-001, 2.469958e+000, 6.481071e-001, -1.077575e+000, -1.275645e-001, 1.418205e+000, 2.057232e+000, -7.778503e-002, 2.433840e+000, -7.094034e-002, 3.347259e+000, 9.344752e-001, -1.099714e+000, -4.474282e-002, -1.247041e-001, -1.578342e-001, -7.968895e+000, 1.730912e-001, 5.303765e-001, 5.523179e+000, 3.840340e-001, -1.061945e+000, -2.200148e-001, 4.333103e+000, 1.818948e-002, 1.907751e+000, 1.560633e+000, -3.182192e-001, -3.010282e+000, 8.844351e-001, -1.087782e+000, -1.709041e-001, 1.834683e+000, 7.351214e-002, 1.282669e+000, 2.075884e-001, 2.698971e-001, 3.373859e-001, 5.808336e-001, // albedo 1, turbidity 3 -1.121417e+000, -1.551220e-001, -1.527123e+000, 2.788105e+000, -1.477847e-001, 1.152139e+000, 1.742181e-001, 3.473417e+000, 6.737050e-001, -1.118910e+000, -1.496848e-001, 2.736873e+000, -1.829596e+000, -3.411991e-001, 1.177538e-001, 2.960683e-001, 3.273898e+000, 5.743833e-001, -1.121145e+000, -1.980292e-001, -5.407002e-001, 2.886807e+000, 4.877852e-001, 3.692424e+000, -1.104033e-001, -2.358878e-001, 9.976295e-001, -1.078889e+000, -1.541161e-003, 1.370650e+000, 1.644450e+000, -1.425572e+001, -3.075430e+000, 9.346385e-001, 5.871863e+000, 2.618026e-001, -1.053346e+000, -2.262166e-001, 2.532003e+000, -8.720058e-001, 7.667901e+000, 4.357082e+000, -5.367969e-001, -2.073329e+000, 1.023965e+000, -1.100093e+000, -1.810893e-001, 2.566430e+000, 4.757700e-001, -2.069684e+000, -1.585209e+000, 4.693140e-001, -6.719615e-001, 5.569453e-001, // albedo 1, turbidity 4 -1.181528e+000, -2.151896e-001, -1.076470e+000, 2.037517e+000, -1.683559e-001, 8.780110e-001, 1.782773e-001, 2.768650e+000, 6.743293e-001, -1.142132e+000, -1.825403e-001, 1.320992e+000, -1.895472e+000, -2.160241e-001, -2.079637e-001, 3.424953e-001, 4.333355e+000, 5.663420e-001, -1.225408e+000, -2.906477e-001, 8.323962e-001, 2.176300e+000, 1.943859e+000, 3.003671e+000, 1.130255e-001, -4.449977e+000, 8.867390e-001, -9.815988e-001, 5.577004e-002, -4.240348e-001, 1.488466e+000, -1.279361e+001, -3.110899e+000, 7.360104e-001, 7.937751e+000, 4.474817e-001, -1.103439e+000, -2.481553e-001, 3.045691e+000, -6.993993e-001, 6.081464e+000, 3.986228e+000, -1.616828e-001, -3.373973e+000, 8.572294e-001, -1.081695e+000, -1.943361e-001, 2.303236e+000, 3.906537e-001, -1.498982e+000, -1.372140e+000, 3.379214e-001, -4.953601e-001, 6.521383e-001, // albedo 1, turbidity 5 -1.235776e+000, -2.745978e-001, 2.205316e-002, 4.505193e-001, -1.569202e-001, 5.065039e-001, 2.016320e-001, 2.449382e+000, 6.535188e-001, -1.268478e+000, -3.078367e-001, -2.041769e-001, 1.189583e+000, -1.311782e+000, 4.724677e-001, 1.025764e-001, 3.300615e+000, 6.689797e-001, -1.190389e+000, -2.597641e-001, 1.377486e+000, -2.289003e+000, 4.214767e+000, 1.900318e+000, 3.126604e-001, -2.537399e+000, 7.980811e-001, -9.632300e-001, 7.067379e-002, -6.690546e-001, 9.507059e+000, -1.721426e+001, -2.850631e+000, 6.931159e-001, 5.722238e+000, 4.856193e-001, -1.119689e+000, -3.019499e-001, 2.657474e+000, -5.208105e+000, 1.015200e+001, 3.863887e+000, -1.603721e-001, -3.132328e+000, 8.543154e-001, -1.078742e+000, -1.840880e-001, 2.341448e+000, 2.576821e+000, -5.011296e+000, -1.671996e+000, 3.955131e-001, -4.700684e-001, 6.516593e-001, // albedo 1, turbidity 6 -1.263449e+000, -3.016185e-001, -1.680842e-001, 4.791728e-001, -8.989862e-002, 5.069014e-001, 1.892810e-001, 2.535339e+000, 6.506411e-001, -1.544305e+000, -5.656222e-001, -2.084263e-001, 1.312304e+000, -8.580598e-001, 4.039133e-001, 1.008588e-001, 1.268784e+000, 6.333075e-001, -9.436041e-001, -1.620107e-002, 1.253874e+000, -3.499120e+000, 4.452594e+000, 1.870490e+000, 1.524710e-001, 8.031346e-001, 8.930942e-001, -1.106718e+000, -1.102586e-001, -8.803979e-001, 1.326904e+001, -1.878253e+001, -2.994671e+000, 9.501205e-001, 2.284893e+000, 3.662824e-001, -1.048783e+000, -2.156089e-001, 2.786728e+000, -4.862603e+000, 8.438175e+000, 3.683031e+000, -3.092444e-001, -1.293934e+000, 9.110045e-001, -1.108140e+000, -2.156079e-001, 2.181504e+000, 2.124553e+000, -5.007442e+000, -1.711417e+000, 4.904871e-001, -8.710312e-001, 6.376965e-001, // albedo 1, turbidity 7 -1.345282e+000, -3.856197e-001, -1.975094e-001, 3.016919e-001, 2.765844e-001, 2.092275e-001, 2.251325e-001, 2.058589e+000, 6.014266e-001, -1.907309e+000, -8.881952e-001, -4.827860e-001, 1.495665e+000, -9.243173e-001, 3.864061e-001, 7.491538e-002, 2.719526e-001, 6.046039e-001, -7.540737e-001, 1.800167e-001, 1.174575e+000, -3.052295e+000, 4.669060e+000, 1.793876e+000, 1.664066e-001, 2.376187e+000, 9.261122e-001, -1.165479e+000, -2.500464e-001, -9.603937e-001, 8.919733e+000, -1.561899e+001, -2.850650e+000, 8.368531e-001, 3.404393e-001, 3.694265e-001, -1.032259e+000, -1.593662e-001, 2.621639e+000, -5.369281e-001, 6.011517e+000, 3.234312e+000, -1.842335e-001, -3.749684e-001, 8.913063e-001, -1.119906e+000, -2.533313e-001, 2.017975e+000, 4.776492e-001, -5.005474e+000, -1.503414e+000, 4.694448e-001, -1.039200e+000, 6.438630e-001, // albedo 1, turbidity 8 -1.457842e+000, -4.806585e-001, -6.807833e-001, 2.682520e-001, 5.586195e-001, -2.806536e-001, 3.694491e-001, 2.169304e+000, 4.997873e-001, -2.906600e+000, -1.558470e+000, 4.048869e-001, 1.012321e+000, -8.709928e-001, 9.025637e-001, -9.171486e-002, -1.279805e+000, 5.327924e-001, -2.500868e-001, 5.175467e-001, -4.366020e-001, -1.156645e+000, 3.657335e+000, 4.092973e-001, 4.611188e-001, 4.971048e+000, 9.789196e-001, -1.282240e+000, -4.792753e-001, 3.824491e-001, 2.061672e+000, -9.474747e+000, -1.080446e+000, 3.852100e-001, -3.234591e+000, 3.696703e-001, -1.046065e+000, -1.097023e-001, 1.672284e+000, 4.799701e+000, 1.286403e+000, 1.712569e+000, 1.099301e-001, 1.214451e+000, 8.572886e-001, -1.104124e+000, -2.576744e-001, 1.919030e+000, -1.296687e-003, -3.500874e+000, -1.048831e+000, 3.929400e-001, -9.229794e-001, 6.687909e-001, // albedo 1, turbidity 9 -1.658918e+000, -6.637256e-001, -1.162850e+000, 1.829549e+000, -2.525065e-001, 8.624803e-001, 5.214746e-002, 1.977784e+000, 6.455044e-001, -3.553256e+000, -1.639022e+000, -8.821743e-001, -2.660037e-001, 5.168738e-001, -8.582770e-001, 4.110780e-001, 1.034123e-001, 1.039852e-001, -1.299367e+000, -4.890457e-001, -5.595307e-001, 1.129115e+000, 5.445041e-001, 5.361314e-001, 4.579589e-001, 3.385708e+000, 1.184267e+000, -4.366852e-001, -2.303554e-002, 5.417530e-001, -9.106900e-001, -4.398484e-001, 3.178252e-001, -2.132156e-001, -3.682761e+000, 3.754470e-001, -1.334075e+000, -2.466639e-001, 1.293237e+000, 4.685982e+000, -4.032879e+000, 4.666293e-001, 5.337822e-001, 1.603290e+000, 8.067400e-001, -1.052460e+000, -2.501759e-001, 1.601487e+000, 1.713504e+000, -2.810006e+000, -8.042597e-001, 3.216101e-001, -5.944876e-001, 6.740783e-001, // albedo 1, turbidity 10 -1.974746e+000, -9.111910e-001, -2.159155e-001, 2.437415e+000, -1.592257e+000, 6.133797e-001, -6.243023e-006, 1.960399e+000, 7.806415e-001, -2.677119e+000, -1.100702e+000, -6.847246e-001, -2.820855e+000, 1.577837e+000, 6.243833e-001, 2.218481e-002, 1.568717e+000, 2.327673e-002, -5.323827e+000, -2.461050e+000, -3.941307e-001, 4.908417e+000, -1.657232e-001, -9.501763e-001, 1.063520e+000, 1.455622e+000, 9.781890e-001, 1.325000e+000, 3.538115e-001, 1.783573e-001, -6.903650e+000, -8.079921e-001, 1.215973e+000, -6.852540e-001, -1.735835e+000, 5.744662e-001, -1.741196e+000, -3.448017e-001, 1.242377e+000, 1.098613e+001, -3.386782e+000, -3.128683e-001, 5.792848e-001, 1.364330e-002, 7.112763e-001, -9.762671e-001, -3.368355e-001, 1.374728e+000, -3.312353e-003, -2.576919e+000, -1.778015e-001, 2.024288e-001, -6.128666e-001, 6.917938e-001, }; static float datasetRad720[] = { // albedo 0, turbidity 1 1.130152e-002, 8.671843e-003, 2.004792e-002, 2.515879e-002, 2.020140e-002, 2.117353e-002, // albedo 0, turbidity 2 1.224368e-002, 8.839480e-003, 2.189489e-002, 4.083873e-002, 1.919064e-002, 2.455945e-002, // albedo 0, turbidity 3 1.252249e-002, 8.009335e-003, 2.371432e-002, 6.397292e-002, 2.042384e-002, 2.862112e-002, // albedo 0, turbidity 4 1.180325e-002, 8.958479e-003, 1.183940e-002, 1.148189e-001, 1.354571e-002, 3.848691e-002, // albedo 0, turbidity 5 1.085725e-002, 1.134459e-002, -7.554548e-003, 1.671603e-001, 8.431212e-003, 4.772824e-002, // albedo 0, turbidity 6 1.014547e-002, 1.403737e-002, -2.479898e-002, 2.032831e-001, 5.127749e-003, 5.409735e-002, // albedo 0, turbidity 7 9.143208e-003, 1.825961e-002, -4.902126e-002, 2.473204e-001, 7.992708e-003, 6.238918e-002, // albedo 0, turbidity 8 7.784746e-003, 2.352715e-002, -7.647231e-002, 2.868914e-001, 2.581232e-002, 7.345921e-002, // albedo 0, turbidity 9 6.425568e-003, 2.680506e-002, -9.216963e-002, 2.866525e-001, 7.712816e-002, 8.877708e-002, // albedo 0, turbidity 10 5.348459e-003, 2.347534e-002, -7.499904e-002, 2.035369e-001, 1.874982e-001, 1.045961e-001, // albedo 1, turbidity 1 1.168435e-002, 9.445039e-003, 1.950520e-002, 2.563333e-002, 4.729214e-002, 5.096829e-002, // albedo 1, turbidity 2 1.252521e-002, 1.012940e-002, 2.002302e-002, 4.276714e-002, 4.778275e-002, 5.748908e-002, // albedo 1, turbidity 3 1.285682e-002, 9.705956e-003, 2.018767e-002, 6.797612e-002, 5.181662e-002, 6.548541e-002, // albedo 1, turbidity 4 1.218970e-002, 1.070161e-002, 8.436124e-003, 1.177409e-001, 5.124773e-002, 8.069723e-002, // albedo 1, turbidity 5 1.129406e-002, 1.339498e-002, -1.193989e-002, 1.709051e-001, 5.001995e-002, 9.558448e-002, // albedo 1, turbidity 6 1.056724e-002, 1.570995e-002, -2.759057e-002, 2.030760e-001, 5.311962e-002, 1.037882e-001, // albedo 1, turbidity 7 9.594077e-003, 1.966415e-002, -5.024827e-002, 2.432607e-001, 6.172355e-002, 1.169276e-001, // albedo 1, turbidity 8 8.348105e-003, 2.415281e-002, -7.475064e-002, 2.748209e-001, 8.753187e-002, 1.356651e-001, // albedo 1, turbidity 9 7.106169e-003, 2.513833e-002, -7.928946e-002, 2.463668e-001, 1.685984e-001, 1.485820e-001, // albedo 1, turbidity 10 6.031610e-003, 2.016534e-002, -5.448075e-002, 1.436689e-001, 2.971830e-001, 1.639884e-001, }; static float *datasets[] = {dataset320, dataset360, dataset400, dataset440, dataset480, dataset520, dataset560, dataset600, dataset640, dataset680, dataset720}; static float *datasetsRad[] = {datasetRad320, datasetRad360, datasetRad400, datasetRad440, datasetRad480, datasetRad520, datasetRad560, datasetRad600, datasetRad640, datasetRad680, datasetRad720}; // Uses Feb 9 dataset static float solarDataset320[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.162049e+02, 4.610588e+00, 0, 0, -3.824759e+00, 1.338698e+01, 5.595274e-02, 3.125000e-04, -2.161500e+03, 1.113209e+02, 3.458172e-01, 2.500000e-03, 8.294600e+01, 1.711252e+02, 2.111274e+00, 1.984375e-02, -4.229939e+03, 6.275308e+02, 6.980643e+00, 8.375000e-02, -1.740178e+04, 1.708634e+03, 2.367820e+01, 3.350000e-01, -1.976851e+04, 2.817040e+03, 6.781352e+01, 1.193125e+00, -3.810737e+04, 4.836590e+03, 1.556846e+02, 3.466250e+00, -4.549929e+04, 6.516914e+03, 3.119331e+02, 8.744219e+00, -5.263436e+04, 8.036785e+03, 5.455303e+02, 1.930562e+01, -6.309578e+04, 9.205958e+03, 8.581439e+02, 3.815516e+01, -4.954890e+04, 8.736703e+03, 1.229615e+03, 6.870672e+01, -6.343828e+04, 9.001550e+03, 1.628815e+03, 1.138184e+02, -3.475406e+04, 6.615408e+03, 2.019023e+03, 1.763652e+02, -4.201833e+04, 6.105544e+03, 2.362030e+03, 2.567578e+02, -2.667604e+04, 4.055614e+03, 2.646799e+03, 3.559691e+02, -2.036310e+04, 2.748587e+03, 2.846313e+03, 4.723367e+02, -2.032124e+04, 1.878732e+03, 2.969980e+03, 6.041547e+02, -1.073640e+04, 4.777580e+02, 3.009645e+03, 7.491283e+02, -1.005389e+04, -3.672131e+01, 2.973858e+03, 9.033814e+02, -1.030868e+04, -4.464229e+02, 2.879841e+03, 1.064085e+03, -2.157918e+03, -1.342683e+03, 2.723843e+03, 1.227711e+03, -3.651657e+03, -1.197013e+03, 2.534012e+03, 1.389789e+03, -7.289195e+03, -9.708760e+02, 2.331442e+03, 1.548851e+03, -7.704469e+02, -1.628402e+03, 2.093848e+03, 1.702493e+03, -4.214558e+03, -1.153021e+03, 1.844767e+03, 1.845862e+03, -2.390689e+03, -1.287373e+03, 1.593697e+03, 1.978602e+03, -6.413034e+03, -8.008887e+02, 1.339243e+03, 2.097559e+03, -2.988481e+03, -1.136665e+03, 1.064931e+03, 2.201486e+03, -6.139876e+03, -5.991924e+02, 7.913266e+02, 2.285209e+03, -1.196221e+04, 1.344918e+02, 5.186582e+02, 2.348895e+03, -5.971683e+03, -6.555303e+01, 2.013157e+02, 2.389728e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.229445e+02, 7.374485e+00, 0, 0, -1.231740e+01, 1.262553e+01, 7.960490e-02, 4.687500e-04, -2.643352e+02, 5.605647e+01, 3.498905e-01, 2.812500e-03, -2.454452e+03, 2.369608e+02, 1.620789e+00, 1.531250e-02, -4.320948e+03, 5.952227e+02, 6.834726e+00, 7.828125e-02, -1.272903e+04, 1.474486e+03, 2.244014e+01, 3.187500e-01, -1.829132e+04, 2.679893e+03, 6.267850e+01, 1.107500e+00, -3.969700e+04, 4.797859e+03, 1.468690e+02, 3.237813e+00, -4.233637e+04, 6.288595e+03, 2.991805e+02, 8.289531e+00, -5.378742e+04, 8.016312e+03, 5.272841e+02, 1.845875e+01, -6.132387e+04, 9.078358e+03, 8.364539e+02, 3.679578e+01, -5.902508e+04, 9.037411e+03, 1.204972e+03, 6.666500e+01, -4.718111e+04, 8.049720e+03, 1.595444e+03, 1.110180e+02, -4.077260e+04, 7.049147e+03, 1.976792e+03, 1.719842e+02, -4.205766e+04, 6.112440e+03, 2.327488e+03, 2.511269e+02, -2.791505e+04, 4.115557e+03, 2.612616e+03, 3.489953e+02, -1.609988e+04, 2.510900e+03, 2.810607e+03, 4.639409e+02, -2.314164e+04, 2.163386e+03, 2.938786e+03, 5.940591e+02, -1.330257e+04, 6.221024e+02, 2.986256e+03, 7.378767e+02, -5.675969e+03, -3.846177e+02, 2.945011e+03, 8.909630e+02, -6.495665e+03, -5.518256e+02, 2.852178e+03, 1.049766e+03, -1.215437e+04, -4.405937e+02, 2.722478e+03, 1.212177e+03, 2.719602e+03, -1.879784e+03, 2.530070e+03, 1.375258e+03, -8.647169e+03, -7.569952e+02, 2.319694e+03, 1.532926e+03, -1.867684e+03, -1.528257e+03, 2.092233e+03, 1.686330e+03, -4.025935e+03, -1.211125e+03, 1.840308e+03, 1.829689e+03, -1.081717e+03, -1.411956e+03, 1.583655e+03, 1.961830e+03, -7.350389e+03, -6.622648e+02, 1.334664e+03, 2.079855e+03, -2.343916e+03, -1.205267e+03, 1.063635e+03, 2.183818e+03, -7.430550e+03, -4.556049e+02, 7.931502e+02, 2.267336e+03, -1.068232e+04, -2.114828e+01, 5.135211e+02, 2.331394e+03, -6.217560e+03, -3.350260e+01, 2.024873e+02, 2.371433e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.203441e+02, 4.171995e+00, 0, 0, 1.426480e+02, -4.022426e-01, 2.425240e-02, 1.562500e-04, -4.009478e+01, 1.125399e+01, 5.471435e-02, 4.687500e-04, -6.200072e+02, 5.758122e+01, 2.853042e-01, 2.343750e-03, -6.987267e+02, 1.643846e+02, 1.429285e+00, 1.359375e-02, -5.632468e+03, 5.971678e+02, 5.643686e+00, 6.437500e-02, -1.136274e+04, 1.361972e+03, 2.032334e+01, 2.812500e-01, -1.952933e+04, 2.607796e+03, 5.786257e+01, 1.004844e+00, -3.532941e+04, 4.461645e+03, 1.377803e+02, 3.003125e+00, -4.143687e+04, 6.064540e+03, 2.816662e+02, 7.743281e+00, -5.085245e+04, 7.694233e+03, 5.005985e+02, 1.737797e+01, -6.042859e+04, 8.861458e+03, 7.989383e+02, 3.484813e+01, -5.375945e+04, 8.686126e+03, 1.157257e+03, 6.348969e+01, -4.609594e+04, 8.037224e+03, 1.541142e+03, 1.061803e+02, -5.818693e+04, 7.796026e+03, 1.925333e+03, 1.653475e+02, -1.234873e+04, 4.326471e+03, 2.261366e+03, 2.427720e+02, -4.100578e+04, 5.301137e+03, 2.543132e+03, 3.370997e+02, -2.570418e+04, 3.036407e+03, 2.771427e+03, 4.502481e+02, -9.930667e+03, 1.185082e+03, 2.888544e+03, 5.787917e+02, -1.540011e+04, 1.011847e+03, 2.933616e+03, 7.193989e+02, -8.074592e+03, -9.360958e+01, 2.915801e+03, 8.705267e+02, -1.229699e+04, -1.891092e+02, 2.833288e+03, 1.028212e+03, 1.425166e+02, -1.460737e+03, 2.687065e+03, 1.189614e+03, -7.667229e+03, -7.968169e+02, 2.508850e+03, 1.349517e+03, -2.347845e+03, -1.408348e+03, 2.307273e+03, 1.507527e+03, -4.419120e+03, -1.175822e+03, 2.079767e+03, 1.659044e+03, -4.704423e+03, -1.172710e+03, 1.838621e+03, 1.802379e+03, -3.231727e+01, -1.540847e+03, 1.575896e+03, 1.934311e+03, -7.381753e+03, -6.308022e+02, 1.326603e+03, 2.051421e+03, -2.673977e+03, -1.159966e+03, 1.060234e+03, 2.154908e+03, -6.512200e+03, -5.471063e+02, 7.899642e+02, 2.238250e+03, -9.505497e+03, -1.111579e+02, 5.172803e+02, 2.301960e+03, -6.085971e+03, -7.278179e+01, 2.224392e+02, 2.342608e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.398243e+02, 5.776206e+00, 0, 0, 2.463155e+02, -2.094592e-01, 4.496203e-02, 3.125000e-04, -1.010040e+03, 5.790287e+01, 1.278306e-01, 1.093750e-03, -3.545764e+02, 1.294156e+02, 1.099066e+00, 9.687500e-03, -6.451710e+03, 5.563384e+02, 4.533285e+00, 4.984375e-02, -5.934123e+03, 1.056602e+03, 1.730255e+01, 2.356250e-01, -2.331347e+04, 2.539950e+03, 4.913378e+01, 8.401563e-01, -2.454544e+04, 3.778662e+03, 1.219910e+02, 2.611719e+00, -4.570703e+04, 5.952157e+03, 2.514711e+02, 6.796719e+00, -4.332230e+04, 7.038252e+03, 4.577067e+02, 1.558687e+01, -6.059598e+04, 8.589735e+03, 7.371821e+02, 3.161938e+01, -4.538550e+04, 8.101580e+03, 1.079569e+03, 5.827141e+01, -5.158798e+04, 8.232570e+03, 1.451372e+03, 9.823734e+01, -4.012520e+04, 6.957081e+03, 1.830066e+03, 1.543975e+02, -3.793394e+04, 5.939944e+03, 2.176636e+03, 2.281206e+02, -3.211292e+04, 4.482161e+03, 2.467196e+03, 3.200717e+02, -1.588792e+04, 2.521470e+03, 2.673764e+03, 4.292442e+02, -1.756764e+04, 1.927386e+03, 2.804183e+03, 5.532441e+02, -1.277374e+04, 8.843716e+02, 2.867650e+03, 6.906603e+02, -8.721587e+03, 7.343786e+01, 2.857501e+03, 8.384222e+02, -1.210720e+04, -1.134775e+02, 2.787446e+03, 9.933153e+02, -7.324531e+02, -1.323481e+03, 2.651921e+03, 1.152349e+03, -7.693693e+03, -7.693487e+02, 2.480657e+03, 1.310405e+03, -2.653371e+03, -1.366675e+03, 2.282324e+03, 1.466687e+03, -3.648018e+03, -1.230454e+03, 2.056210e+03, 1.616582e+03, -2.664373e+03, -1.284624e+03, 1.819352e+03, 1.758212e+03, -5.222558e+03, -9.816239e+02, 1.575433e+03, 1.888928e+03, -2.865965e+03, -1.196481e+03, 1.315007e+03, 2.006915e+03, -3.599541e+03, -9.578621e+02, 1.050151e+03, 2.108105e+03, -6.734962e+03, -5.085043e+02, 7.938554e+02, 2.191497e+03, -1.211854e+04, 1.393363e+02, 5.225520e+02, 2.255726e+03, -5.940851e+03, -7.200209e+01, 2.016666e+02, 2.296840e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.810245e+01, 2.305294e+00, 0, 0, -4.677095e+01, 7.181418e+00, 2.797637e-02, 1.562500e-04, -2.390763e+02, 3.399401e+01, 1.676014e-01, 1.250000e-03, -1.572353e+03, 1.448172e+02, 9.018003e-01, 8.125000e-03, -1.932258e+03, 3.555380e+02, 4.045229e+00, 4.515625e-02, -8.021604e+03, 1.011597e+03, 1.385505e+01, 1.907813e-01, -1.760146e+04, 2.142284e+03, 4.213012e+01, 7.085938e-01, -2.771190e+04, 3.598579e+03, 1.059734e+02, 2.232031e+00, -2.685562e+04, 4.912314e+03, 2.231363e+02, 5.951250e+00, -5.816933e+04, 7.488614e+03, 4.119772e+02, 1.372719e+01, -5.375236e+04, 7.934157e+03, 6.844993e+02, 2.860453e+01, -4.429083e+04, 7.764848e+03, 1.006186e+03, 5.337641e+01, -4.260900e+04, 7.623473e+03, 1.360246e+03, 9.077234e+01, -4.165134e+04, 7.075685e+03, 1.728438e+03, 1.435205e+02, -4.199611e+04, 6.142734e+03, 2.077584e+03, 2.136358e+02, -1.823240e+04, 3.778736e+03, 2.365364e+03, 3.017798e+02, -2.860530e+04, 3.604470e+03, 2.586318e+03, 4.064622e+02, -1.609512e+04, 1.794040e+03, 2.736939e+03, 5.275606e+02, -1.254070e+04, 8.805854e+02, 2.797800e+03, 6.615970e+02, -6.090084e+03, -5.143658e+01, 2.789103e+03, 8.057959e+02, -1.308790e+04, 9.060229e+01, 2.728964e+03, 9.570091e+02, -1.747122e+03, -1.183227e+03, 2.607217e+03, 1.113144e+03, -4.502060e+03, -9.631705e+02, 2.441686e+03, 1.268743e+03, -4.925191e+03, -1.030626e+03, 2.258761e+03, 1.422545e+03, -4.605435e+03, -1.142309e+03, 2.046600e+03, 1.571669e+03, -2.008970e+03, -1.371278e+03, 1.807372e+03, 1.712698e+03, -4.054953e+03, -1.064272e+03, 1.561721e+03, 1.842282e+03, -4.186489e+03, -1.014859e+03, 1.310764e+03, 1.959238e+03, -4.536370e+03, -8.990475e+02, 1.048215e+03, 2.060568e+03, -4.732931e+03, -7.451517e+02, 7.801005e+02, 2.143593e+03, -1.235209e+04, 2.174097e+02, 5.169935e+02, 2.206104e+03, -6.154950e+03, -5.382014e+01, 2.046788e+02, 2.247203e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.126883e+02, 5.520338e+00, 0, 0, 1.263603e+02, 2.194173e+00, 4.737462e-02, 3.125000e-04, -1.508116e+01, 2.129591e+01, 1.399562e-01, 1.250000e-03, -9.018236e+02, 1.098378e+02, 6.623187e-01, 6.250000e-03, -3.504771e+03, 3.721805e+02, 3.219475e+00, 3.484375e-02, -6.289506e+03, 8.722241e+02, 1.237269e+01, 1.653125e-01, -1.480606e+04, 1.913931e+03, 3.734160e+01, 6.228125e-01, -2.450066e+04, 3.351021e+03, 9.544644e+01, 1.985000e+00, -3.693950e+04, 5.083189e+03, 2.063989e+02, 5.391406e+00, -4.358414e+04, 6.496516e+03, 3.861177e+02, 1.272703e+01, -4.530622e+04, 7.428171e+03, 6.366847e+02, 2.650891e+01, -4.733767e+04, 7.964659e+03, 9.501384e+02, 4.969906e+01, -5.370278e+04, 8.090009e+03, 1.307795e+03, 8.545641e+01, -3.321384e+04, 6.411379e+03, 1.669725e+03, 1.365462e+02, -3.641652e+04, 5.884973e+03, 2.004006e+03, 2.040570e+02, -2.540098e+04, 4.300449e+03, 2.297230e+03, 2.892628e+02, -2.760640e+04, 3.474278e+03, 2.524065e+03, 3.914722e+02, -8.048468e+03, 1.366510e+03, 2.669037e+03, 5.095961e+02, -2.029543e+04, 1.620800e+03, 2.744637e+03, 6.402722e+02, -3.964493e+03, -2.191741e+02, 2.750646e+03, 7.826442e+02, -1.106059e+04, 3.180232e+01, 2.691209e+03, 9.316025e+02, -4.643371e+03, -8.533850e+02, 2.583124e+03, 1.085744e+03, -4.533634e+03, -9.829180e+02, 2.425278e+03, 1.240435e+03, -6.144697e+03, -9.649133e+02, 2.239377e+03, 1.393075e+03, 1.615287e+03, -1.671132e+03, 2.018903e+03, 1.540777e+03, -9.492625e+03, -5.137586e+02, 1.801463e+03, 1.679387e+03, -4.863360e+02, -1.552130e+03, 1.555354e+03, 1.810186e+03, -4.150248e+03, -9.569455e+02, 1.295372e+03, 1.925326e+03, -3.336249e+03, -9.666328e+02, 1.043430e+03, 2.025790e+03, -8.928017e+03, -2.828557e+02, 7.918380e+02, 2.108700e+03, -8.901351e+03, -2.240739e+02, 5.052828e+02, 2.172922e+03, -6.226979e+03, -2.346247e+01, 2.056987e+02, 2.211881e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.915526e+02, 7.366238e+00, 0, 0, 6.163369e+01, 1.204175e+01, 9.225802e-02, 6.250000e-04, -6.773000e+02, 7.896783e+01, 4.201401e-01, 3.750000e-03, -1.616556e+03, 2.639201e+02, 2.241390e+00, 2.343750e-02, -1.059666e+04, 9.232364e+02, 9.386152e+00, 1.187500e-01, -8.791318e+03, 1.500107e+03, 3.211158e+01, 5.154688e-01, -2.227497e+04, 2.999099e+03, 8.091825e+01, 1.660469e+00, -3.111629e+04, 4.548813e+03, 1.797262e+02, 4.607656e+00, -4.734025e+04, 6.313047e+03, 3.438787e+02, 1.107969e+01, -3.301271e+04, 6.534868e+03, 5.771119e+02, 2.356234e+01, -5.497932e+04, 8.077472e+03, 8.696235e+02, 4.460859e+01, -3.691249e+04, 7.075388e+03, 1.212190e+03, 7.774641e+01, -4.535714e+04, 7.102579e+03, 1.562845e+03, 1.251120e+02, -3.169379e+04, 5.490801e+03, 1.899280e+03, 1.890709e+02, -1.728180e+04, 3.949454e+03, 2.183344e+03, 2.698602e+02, -3.714132e+04, 4.285851e+03, 2.423673e+03, 3.672678e+02, -5.215022e+03, 1.183427e+03, 2.583754e+03, 4.816480e+02, -1.863398e+04, 1.625851e+03, 2.661413e+03, 6.081128e+02, -6.406195e+03, 7.803378e+01, 2.681066e+03, 7.464519e+02, -1.136441e+04, 7.752814e+01, 2.632242e+03, 8.920981e+02, -2.047264e+03, -1.002831e+03, 2.526395e+03, 1.042912e+03, -6.248742e+03, -7.263883e+02, 2.379661e+03, 1.194150e+03, -5.489763e+03, -9.816353e+02, 2.205342e+03, 1.344432e+03, -1.167746e+02, -1.486682e+03, 1.991891e+03, 1.489923e+03, -6.259862e+03, -8.113410e+02, 1.773796e+03, 1.626878e+03, -1.374682e+03, -1.342055e+03, 1.539054e+03, 1.755264e+03, -5.056021e+03, -8.353907e+02, 1.295621e+03, 1.869990e+03, -4.537758e+03, -8.790940e+02, 1.044749e+03, 1.970797e+03, -6.706975e+03, -5.509051e+02, 7.801558e+02, 2.053670e+03, -1.020946e+04, -4.372454e+01, 5.016635e+02, 2.116272e+03, -6.221044e+03, -1.982749e+01, 1.997960e+02, 2.155378e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.471287e+01, 3.454011e+00, 0, 0, -5.151738e+01, 1.088983e+01, 4.862104e-02, 3.125000e-04, -5.554154e+02, 5.853337e+01, 2.954357e-01, 2.500000e-03, -1.401631e+03, 1.899381e+02, 1.613639e+00, 1.671875e-02, -3.677010e+03, 5.381794e+02, 6.576231e+00, 8.437500e-02, -1.130930e+04, 1.351274e+03, 2.217409e+01, 3.490625e-01, -1.610460e+04, 2.382976e+03, 6.220396e+01, 1.221875e+00, -3.182774e+04, 4.050808e+03, 1.429730e+02, 3.534531e+00, -2.661339e+04, 4.911419e+03, 2.820920e+02, 8.833438e+00, -4.684400e+04, 6.742349e+03, 4.845560e+02, 1.910938e+01, -3.607371e+04, 6.710619e+03, 7.550675e+02, 3.735891e+01, -4.154781e+04, 7.152810e+03, 1.067429e+03, 6.618859e+01, -4.204317e+04, 6.774326e+03, 1.407564e+03, 1.085970e+02, -2.942193e+04, 5.355563e+03, 1.733269e+03, 1.666419e+02, -2.313904e+04, 4.280577e+03, 2.017180e+03, 2.408670e+02, -2.385720e+04, 3.520820e+03, 2.254320e+03, 3.314445e+02, -1.513209e+04, 2.112956e+03, 2.426267e+03, 4.378639e+02, -9.126023e+03, 1.113924e+03, 2.524502e+03, 5.577991e+02, -1.571455e+04, 1.029708e+03, 2.566730e+03, 6.890491e+02, -7.238440e+03, -2.206829e+02, 2.538549e+03, 8.297720e+02, -3.160979e+03, -7.760560e+02, 2.439782e+03, 9.749502e+02, -5.602452e+03, -6.902848e+02, 2.308307e+03, 1.121456e+03, -3.553157e+03, -1.014479e+03, 2.146930e+03, 1.267419e+03, -4.461083e+03, -9.863057e+02, 1.956534e+03, 1.409364e+03, -2.326809e+03, -1.209321e+03, 1.742287e+03, 1.544723e+03, -4.135229e+03, -9.712685e+02, 1.515864e+03, 1.670126e+03, -3.963535e+03, -9.751278e+02, 1.278348e+03, 1.783945e+03, -3.590545e+03, -9.317344e+02, 1.027352e+03, 1.882948e+03, -7.816601e+03, -3.861471e+02, 7.759248e+02, 1.964524e+03, -8.824559e+03, -1.916167e+02, 4.991662e+02, 2.027263e+03, -6.003275e+03, -4.576937e+01, 2.081407e+02, 2.066007e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.625582e+01, 1.932575e+00, 0, 0, 6.414978e+01, 1.472767e+00, 2.207452e-02, 1.562500e-04, -2.922836e+02, 2.777474e+01, 8.841004e-02, 7.812500e-04, -8.188740e+02, 1.059625e+02, 6.968160e-01, 6.718750e-03, -2.889488e+03, 3.500503e+02, 3.437535e+00, 4.109375e-02, -6.748480e+03, 8.561885e+02, 1.311485e+01, 1.956250e-01, -9.511546e+03, 1.611095e+03, 3.896265e+01, 7.334375e-01, -2.290021e+04, 3.066546e+03, 9.552066e+01, 2.243906e+00, -2.821286e+04, 4.251733e+03, 2.028843e+02, 5.967656e+00, -2.913541e+04, 5.203704e+03, 3.675117e+02, 1.368859e+01, -4.048369e+04, 6.372044e+03, 5.934689e+02, 2.775234e+01, -3.547831e+04, 6.262590e+03, 8.720572e+02, 5.110688e+01, -3.218587e+04, 5.921591e+03, 1.172909e+03, 8.616875e+01, -2.477427e+04, 5.121564e+03, 1.475680e+03, 1.350383e+02, -2.868072e+04, 4.746820e+03, 1.762617e+03, 1.991086e+02, -1.754454e+04, 3.266592e+03, 2.009591e+03, 2.794042e+02, -1.913506e+04, 2.655854e+03, 2.197015e+03, 3.748694e+02, -9.992284e+03, 1.320722e+03, 2.319693e+03, 4.845859e+02, -1.419455e+04, 1.062222e+03, 2.376302e+03, 6.057533e+02, -2.694677e+03, -3.023730e+02, 2.365281e+03, 7.364186e+02, -9.185589e+03, -8.118530e+00, 2.302949e+03, 8.721534e+02, -2.847409e+03, -8.444596e+02, 2.197532e+03, 1.011741e+03, -3.035145e+03, -8.775668e+02, 2.051168e+03, 1.150592e+03, -5.533588e+03, -7.385513e+02, 1.887015e+03, 1.286758e+03, -3.565998e+03, -1.040906e+03, 1.691788e+03, 1.417959e+03, -2.327347e+03, -1.126813e+03, 1.469339e+03, 1.539923e+03, -3.906176e+03, -8.827879e+02, 1.242034e+03, 1.649925e+03, -6.221863e+03, -6.310295e+02, 1.007942e+03, 1.746547e+03, -3.114073e+03, -8.975397e+02, 7.474580e+02, 1.826920e+03, -1.186080e+04, 2.407749e+02, 4.982586e+02, 1.886371e+03, -6.394004e+03, -1.686521e+01, 2.046311e+02, 1.926321e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.355371e+02, 8.998932e+00, 0, 0, -3.468260e+02, 4.003623e+01, 1.728223e-01, 1.406250e-03, -1.659534e+03, 1.606414e+02, 1.180182e+00, 1.281250e-02, -5.133751e+02, 3.182364e+02, 5.307610e+00, 7.484375e-02, -1.044783e+04, 1.132211e+03, 1.723019e+01, 2.984375e-01, -1.232620e+04, 1.809523e+03, 5.164214e+01, 1.100625e+00, -1.492798e+04, 2.716347e+03, 1.170312e+02, 3.201250e+00, -2.509641e+04, 4.034536e+03, 2.285777e+02, 7.860000e+00, -3.139992e+04, 4.936112e+03, 3.976305e+02, 1.709562e+01, -1.992734e+04, 4.752382e+03, 6.133259e+02, 3.325813e+01, -3.583565e+04, 5.733661e+03, 8.653644e+02, 5.850203e+01, -1.864658e+04, 4.463079e+03, 1.140041e+03, 9.577875e+01, -2.806870e+04, 4.628337e+03, 1.403590e+03, 1.460806e+02, -1.224450e+04, 3.007469e+03, 1.643849e+03, 2.111303e+02, -1.837221e+04, 2.895966e+03, 1.840158e+03, 2.900925e+02, -1.305949e+04, 1.813863e+03, 1.991237e+03, 3.832811e+02, -7.995788e+03, 9.019857e+02, 2.074227e+03, 4.884772e+02, -5.202137e+03, 3.292653e+02, 2.101192e+03, 6.031734e+02, -9.894927e+03, 3.490710e+02, 2.086841e+03, 7.252181e+02, -2.081824e+03, -6.584184e+02, 2.017335e+03, 8.526909e+02, -5.753047e+03, -4.455308e+02, 1.904978e+03, 9.807998e+02, -2.548608e+03, -9.027576e+02, 1.761653e+03, 1.108055e+03, -4.593746e+03, -7.480921e+02, 1.589904e+03, 1.230419e+03, -2.237374e+03, -1.028298e+03, 1.394230e+03, 1.345830e+03, -4.404710e+03, -7.547906e+02, 1.184581e+03, 1.450460e+03, -3.128602e+03, -8.687342e+02, 9.614427e+02, 1.542825e+03, -7.364928e+03, -3.355787e+02, 7.322318e+02, 1.619357e+03, -9.377841e+03, -7.234116e+01, 4.767442e+02, 1.678824e+03, -6.106783e+03, -2.487557e+00, 1.931677e+02, 1.715997e+03, }; static float solarDataset360[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.078413e+03, 7.118205e+01, 0, 0, 4.658139e+03, -1.838006e+01, 1.514489e-01, 5.208333e-04, -1.266691e+04, 2.223605e+02, 2.846817e-01, 1.302083e-03, 5.376673e+03, 1.263979e+02, 1.585011e+00, 7.812500e-03, -6.287382e+03, 6.310960e+02, 4.070404e+00, 2.630208e-02, -1.089068e+04, 1.566596e+03, 1.304182e+01, 9.713542e-02, -5.578495e+04, 4.275269e+03, 3.968016e+01, 3.502604e-01, -7.874206e+04, 8.041790e+03, 1.128851e+02, 1.215885e+00, -1.523996e+05, 1.484058e+04, 2.762902e+02, 3.709896e+00, -2.545257e+05, 2.361556e+04, 6.036183e+02, 1.011875e+01, -2.941122e+05, 3.066092e+04, 1.160209e+03, 2.459557e+01, -3.612497e+05, 3.709042e+04, 1.969276e+03, 5.311250e+01, -2.820800e+05, 3.689189e+04, 3.009049e+03, 1.034445e+02, -3.813699e+05, 4.027793e+04, 4.213037e+03, 1.833859e+02, -3.197931e+05, 3.414742e+04, 5.485024e+03, 3.019268e+02, -1.923698e+05, 2.458254e+04, 6.615509e+03, 4.632190e+02, -2.078027e+05, 2.080724e+04, 7.548980e+03, 6.677510e+02, -1.360611e+05, 1.255134e+04, 8.240067e+03, 9.159479e+02, -6.729497e+04, 5.762938e+03, 8.622622e+03, 1.202090e+03, -9.900171e+04, 4.710833e+03, 8.774927e+03, 1.519642e+03, -3.788016e+04, -1.223413e+03, 8.689075e+03, 1.864136e+03, -3.007086e+04, -2.674663e+03, 8.385744e+03, 2.224184e+03, -1.454468e+04, -4.149445e+03, 7.962237e+03, 2.593449e+03, -3.313233e+04, -3.256536e+03, 7.461974e+03, 2.965295e+03, -2.461750e+03, -5.667421e+03, 6.865987e+03, 3.335167e+03, -5.859709e+03, -4.818237e+03, 6.224765e+03, 3.692920e+03, -1.114171e+04, -4.055929e+03, 5.606249e+03, 4.036827e+03, -2.940298e+01, -4.599486e+03, 4.980260e+03, 4.363959e+03, -8.192323e+03, -3.332635e+03, 4.380331e+03, 4.669007e+03, -1.314651e+02, -3.690650e+03, 3.804426e+03, 4.952310e+03, -9.321444e+03, -2.355513e+03, 3.265525e+03, 5.209421e+03, -4.323778e+03, -2.664833e+03, 2.740069e+03, 5.441705e+03, -4.030446e+03, -2.268601e+03, 2.225562e+03, 5.643180e+03, -7.709530e+03, -1.532269e+03, 1.753678e+03, 5.813184e+03, -9.915496e+03, -1.081222e+03, 1.297245e+03, 5.951777e+03, -1.918399e+04, 1.650147e+02, 8.356870e+02, 6.055439e+03, -9.182623e+03, -1.363456e+02, 3.168424e+02, 6.120820e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.007459e+06, 1.920534e+03, 0, 0, 4.479837e+05, -7.065871e+02, 0, 2.604167e-04, 0, 0, 0, 0, -4.964101e+04, 1.630114e+02, 0, 0, 2.106646e+04, -9.205597e+01, 0, 2.604167e-04, 0, 0, 0, 0, -1.305437e+04, 1.325834e+02, 0, 0, 7.455004e+03, -2.985865e+01, 3.840792e-01, 1.562500e-03, -2.055425e+04, 4.505399e+02, 7.714470e-01, 4.166667e-03, 1.086675e+04, 2.797690e+02, 4.050099e+00, 2.395833e-02, -1.873506e+04, 1.575040e+03, 1.070445e+01, 8.072917e-02, -4.327245e+04, 3.801002e+03, 3.540976e+01, 3.059896e-01, -1.102894e+05, 8.242103e+03, 1.027385e+02, 1.085156e+00, -7.645743e+04, 1.218373e+04, 2.565037e+02, 3.423437e+00, -3.095499e+05, 2.422173e+04, 5.541844e+02, 9.238802e+00, -1.908061e+05, 2.675484e+04, 1.088555e+03, 2.286589e+01, -3.934663e+05, 3.821301e+04, 1.856451e+03, 4.946328e+01, -3.390953e+05, 3.834252e+04, 2.902994e+03, 9.776536e+01, -3.420266e+05, 3.790490e+04, 4.089229e+03, 1.755013e+02, -2.686944e+05, 3.228911e+04, 5.315213e+03, 2.902633e+02, -2.564538e+05, 2.755072e+04, 6.453482e+03, 4.467523e+02, -1.509348e+05, 1.825991e+04, 7.399666e+03, 6.475846e+02, -1.630120e+05, 1.453409e+04, 8.097017e+03, 8.903924e+02, -9.950958e+04, 7.104934e+03, 8.521488e+03, 1.172941e+03, -2.923012e+04, 1.025880e+03, 8.643788e+03, 1.487047e+03, -8.585662e+04, 2.418502e+03, 8.589889e+03, 1.824949e+03, -1.614087e+04, -3.639570e+03, 8.338546e+03, 2.183701e+03, -2.320497e+04, -3.485113e+03, 7.912837e+03, 2.550157e+03, -2.187702e+04, -3.972423e+03, 7.416360e+03, 2.920199e+03, -1.034810e+04, -4.884562e+03, 6.835820e+03, 3.287367e+03, -2.759089e+03, -5.058797e+03, 6.209527e+03, 3.644522e+03, -9.328274e+03, -4.074038e+03, 5.594421e+03, 3.987341e+03, -4.936422e+03, -4.126474e+03, 4.986817e+03, 4.314099e+03, -3.321617e+03, -3.792265e+03, 4.386012e+03, 4.620225e+03, -1.003521e+04, -2.819991e+03, 3.816137e+03, 4.903331e+03, 2.907803e+03, -3.685267e+03, 3.246729e+03, 5.162089e+03, -7.981799e+03, -2.001596e+03, 2.732990e+03, 5.390627e+03, -8.279987e+03, -1.868805e+03, 2.254065e+03, 5.593927e+03, -5.136369e+03, -1.945934e+03, 1.758273e+03, 5.766632e+03, -9.493658e+03, -1.095077e+03, 1.289392e+03, 5.904171e+03, -1.816478e+04, 8.782733e+01, 8.362875e+02, 6.007321e+03, -1.016501e+04, -5.757161e+01, 3.316172e+02, 6.072978e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.106646e+04, 9.205597e+01, 0, 0, 9.951134e+03, -5.583492e+01, 0, 2.604167e-04, -6.862369e+03, 7.979095e+01, 0, 0, 3.093701e+03, 1.042453e+01, 2.962179e-01, 1.041667e-03, -3.848975e+03, 1.884300e+02, 7.173252e-01, 3.645833e-03, -1.922464e+03, 4.118046e+02, 2.755566e+00, 1.614583e-02, -1.029728e+04, 1.238807e+03, 9.037110e+00, 6.432292e-02, -5.326510e+04, 3.551966e+03, 2.965222e+01, 2.510417e-01, -5.119148e+04, 6.178442e+03, 8.801668e+01, 9.252604e-01, -1.102076e+05, 1.208818e+04, 2.178717e+02, 2.875260e+00, -2.455519e+05, 2.133109e+04, 4.927790e+02, 8.033333e+00, -2.314605e+05, 2.675653e+04, 9.837470e+02, 2.021667e+01, -3.383926e+05, 3.503899e+04, 1.713479e+03, 4.473359e+01, -3.279210e+05, 3.710837e+04, 2.699082e+03, 8.941484e+01, -3.295655e+05, 3.695410e+04, 3.847503e+03, 1.622500e+02, -2.654830e+05, 3.200589e+04, 5.049391e+03, 2.708594e+02, -2.374300e+05, 2.701443e+04, 6.179434e+03, 4.202516e+02, -1.686326e+05, 1.951749e+04, 7.141543e+03, 6.132620e+02, -1.530711e+05, 1.439417e+04, 7.865806e+03, 8.487388e+02, -8.333989e+04, 7.055607e+03, 8.314596e+03, 1.123732e+03, -8.130111e+04, 4.141743e+03, 8.497304e+03, 1.431033e+03, -3.575768e+04, -5.696968e+02, 8.448170e+03, 1.764856e+03, -3.255295e+04, -1.826416e+03, 8.210999e+03, 2.116095e+03, -3.660834e+04, -2.550753e+03, 7.848763e+03, 2.478988e+03, -7.337777e+03, -5.008166e+03, 7.349120e+03, 2.846617e+03, -5.379678e+03, -4.784496e+03, 6.777142e+03, 3.209571e+03, -2.374637e+04, -3.331316e+03, 6.206260e+03, 3.564630e+03, 1.080518e+04, -5.854954e+03, 5.579585e+03, 3.908975e+03, -1.909992e+04, -2.668851e+03, 4.981595e+03, 4.232768e+03, 1.911058e+03, -4.437068e+03, 4.390299e+03, 4.540824e+03, -3.848120e+03, -3.213454e+03, 3.806091e+03, 4.822876e+03, -9.851976e+03, -2.361374e+03, 3.277626e+03, 5.081202e+03, -1.578794e+03, -2.943684e+03, 2.741918e+03, 5.314140e+03, -5.601199e+03, -2.034313e+03, 2.236027e+03, 5.515390e+03, -8.507381e+03, -1.484607e+03, 1.769983e+03, 5.687009e+03, -8.981222e+03, -1.217297e+03, 1.303053e+03, 5.826869e+03, -1.807778e+04, 6.647867e+01, 8.405294e+02, 5.930647e+03, -1.028919e+04, -5.100950e+01, 3.341801e+02, 5.996596e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.528365e+03, 1.907311e+01, 0, 0, 1.516070e+03, 1.652342e+00, 7.814024e-02, 2.604167e-04, -1.566422e+04, 2.938113e+02, 2.450638e-01, 1.041667e-03, 9.323103e+03, 7.951170e+01, 2.065634e+00, 1.145833e-02, -7.689699e+03, 8.647270e+02, 5.179331e+00, 3.828125e-02, -4.120250e+04, 2.746625e+03, 1.943548e+01, 1.575521e-01, -5.390461e+04, 5.341204e+03, 6.456184e+01, 6.408854e-01, -1.009697e+05, 1.038629e+04, 1.723484e+02, 2.164844e+00, -1.920166e+05, 1.804640e+04, 4.048162e+02, 6.370052e+00, -2.372478e+05, 2.492915e+04, 8.320197e+02, 1.654844e+01, -2.793231e+05, 3.114679e+04, 1.491609e+03, 3.777448e+01, -3.104765e+05, 3.519482e+04, 2.392658e+03, 7.703568e+01, -3.177075e+05, 3.568983e+04, 3.482617e+03, 1.424852e+02, -2.494221e+05, 3.108444e+04, 4.644386e+03, 2.418099e+02, -2.364069e+05, 2.715189e+04, 5.759209e+03, 3.802539e+02, -1.404746e+05, 1.898809e+04, 6.731675e+03, 5.613974e+02, -2.017016e+05, 1.743282e+04, 7.504484e+03, 7.844820e+02, -4.320413e+04, 5.367012e+03, 7.992650e+03, 1.048910e+03, -9.571801e+04, 5.908238e+03, 8.211533e+03, 1.344214e+03, -3.686322e+04, 6.522573e+01, 8.234419e+03, 1.668699e+03, -4.436791e+04, -8.088656e+02, 8.044739e+03, 2.011998e+03, -2.002588e+04, -3.383672e+03, 7.702298e+03, 2.368391e+03, -1.741256e+04, -3.854559e+03, 7.237658e+03, 2.728893e+03, -7.888695e+03, -4.546112e+03, 6.704484e+03, 3.087804e+03, -6.588850e+03, -4.351038e+03, 6.137185e+03, 3.439195e+03, -1.547834e+04, -3.487809e+03, 5.565533e+03, 3.779451e+03, 3.267247e+03, -4.786579e+03, 4.960190e+03, 4.105218e+03, -6.089460e+03, -3.295662e+03, 4.377885e+03, 4.409076e+03, -1.218322e+04, -2.582626e+03, 3.837023e+03, 4.693073e+03, 3.616890e+03, -3.794143e+03, 3.268057e+03, 4.953780e+03, -9.102661e+03, -1.913822e+03, 2.750126e+03, 5.183632e+03, -6.696343e+03, -2.063778e+03, 2.263473e+03, 5.388297e+03, -3.048448e+03, -2.093974e+03, 1.768789e+03, 5.561364e+03, -1.551802e+04, -4.318095e+02, 1.323227e+03, 5.700141e+03, -1.234976e+04, -6.368560e+02, 8.363357e+02, 5.807329e+03, -9.311490e+03, -1.488186e+02, 3.568924e+02, 5.871500e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.492148e+03, 2.451223e+01, 0, 0, 1.641003e+03, 8.115125e+00, 1.339882e-01, 5.208333e-04, -1.214574e+04, 3.860017e+02, 4.756144e-01, 2.343750e-03, -1.064944e+04, 7.243819e+02, 4.335378e+00, 2.500000e-02, -6.266723e+03, 1.498871e+03, 1.515545e+01, 1.213542e-01, -4.724146e+04, 4.315847e+03, 4.553783e+01, 4.554687e-01, -8.443089e+04, 8.583278e+03, 1.309248e+02, 1.597396e+00, -1.541231e+05, 1.527165e+04, 3.224487e+02, 4.907813e+00, -2.382286e+05, 2.297833e+04, 6.902681e+02, 1.323568e+01, -2.235609e+05, 2.735690e+04, 1.279864e+03, 3.133542e+01, -2.906342e+05, 3.320621e+04, 2.096545e+03, 6.539010e+01, -3.123834e+05, 3.467834e+04, 3.128177e+03, 1.236672e+02, -2.393461e+05, 3.025589e+04, 4.250709e+03, 2.140122e+02, -2.028333e+05, 2.609503e+04, 5.342867e+03, 3.417609e+02, -2.151191e+05, 2.250055e+04, 6.337131e+03, 5.109326e+02, -9.763169e+04, 1.271519e+04, 7.112202e+03, 7.229203e+02, -1.312211e+05, 1.094586e+04, 7.636174e+03, 9.727784e+02, -3.907836e+04, 2.892178e+03, 7.911983e+03, 1.258277e+03, -5.691819e+04, 2.234234e+03, 7.958878e+03, 1.569822e+03, -4.605984e+04, -2.949351e+02, 7.845258e+03, 1.903886e+03, -9.288844e+03, -3.584873e+03, 7.538797e+03, 2.252188e+03, -3.275040e+04, -2.362390e+03, 7.129354e+03, 2.605553e+03, 7.240576e+03, -5.434321e+03, 6.628154e+03, 2.960763e+03, -2.435119e+04, -2.700395e+03, 6.099256e+03, 3.307801e+03, -3.407342e+03, -4.548247e+03, 5.539707e+03, 3.647942e+03, -4.437134e+03, -3.961614e+03, 4.941027e+03, 3.970917e+03, -3.090062e+03, -3.635715e+03, 4.368076e+03, 4.274897e+03, -6.315304e+03, -2.954206e+03, 3.823070e+03, 4.557586e+03, -5.534764e+03, -2.764660e+03, 3.293166e+03, 4.817570e+03, -7.186551e+03, -2.326088e+03, 2.771736e+03, 5.051273e+03, -2.914677e+03, -2.446875e+03, 2.255978e+03, 5.256005e+03, -7.073055e+03, -1.589272e+03, 1.777935e+03, 5.427988e+03, -1.092444e+04, -9.714652e+02, 1.326496e+03, 5.568739e+03, -1.803434e+04, 5.807577e+00, 8.590316e+02, 5.675268e+03, -1.059246e+04, -4.287520e+01, 3.420559e+02, 5.742487e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.109094e+03, 3.580031e+01, 0, 0, 2.803934e+03, -2.399769e+01, 0, 2.604167e-04, -3.970877e+03, 8.834116e+01, 0, 0, -5.636564e+02, 1.192399e+02, 6.512142e-01, 2.864583e-03, -6.086357e+02, 3.883172e+02, 2.468692e+00, 1.562500e-02, -2.893914e+04, 1.718661e+03, 9.629309e+00, 7.291667e-02, -2.076572e+04, 3.183627e+03, 3.674586e+01, 3.437500e-01, -1.011023e+05, 8.189104e+03, 1.062582e+02, 1.252344e+00, -1.095898e+05, 1.282006e+04, 2.767597e+02, 4.090625e+00, -2.297269e+05, 2.151665e+04, 6.004328e+02, 1.125651e+01, -2.107325e+05, 2.568211e+04, 1.146269e+03, 2.735495e+01, -2.800842e+05, 3.166650e+04, 1.911957e+03, 5.823177e+01, -2.923688e+05, 3.303608e+04, 2.891607e+03, 1.118773e+02, -2.033237e+05, 2.870850e+04, 3.969933e+03, 1.959010e+02, -2.617431e+05, 2.851329e+04, 5.055149e+03, 3.158836e+02, -1.440848e+05, 1.921772e+04, 6.043374e+03, 4.774372e+02, -1.420361e+05, 1.553418e+04, 6.820003e+03, 6.792667e+02, -9.006131e+04, 9.284458e+03, 7.382916e+03, 9.207971e+02, -7.093812e+04, 5.455005e+03, 7.700927e+03, 1.196878e+03, -3.964068e+04, 1.575567e+03, 7.802084e+03, 1.502182e+03, -7.280366e+04, 1.632438e+03, 7.724594e+03, 1.829778e+03, 1.690897e+04, -5.252913e+03, 7.429101e+03, 2.174115e+03, -4.574865e+04, -9.598807e+02, 7.041073e+03, 2.521259e+03, 2.816103e+03, -5.134375e+03, 6.581128e+03, 2.873876e+03, -1.565202e+04, -3.351712e+03, 6.045391e+03, 3.218518e+03, -2.906298e+03, -4.297581e+03, 5.498150e+03, 3.555040e+03, -9.963636e+03, -3.361737e+03, 4.936026e+03, 3.876524e+03, -2.334266e+02, -3.922430e+03, 4.370841e+03, 4.181196e+03, -1.330539e+04, -2.367708e+03, 3.827009e+03, 4.463648e+03, 2.006252e+03, -3.636281e+03, 3.271498e+03, 4.724332e+03, -6.128696e+03, -2.215009e+03, 2.749376e+03, 4.954650e+03, -5.894247e+03, -2.020601e+03, 2.272207e+03, 5.158856e+03, -8.330230e+03, -1.530492e+03, 1.802163e+03, 5.333464e+03, -8.185462e+03, -1.311486e+03, 1.331275e+03, 5.475951e+03, -2.089177e+04, 3.374858e+02, 8.719856e+02, 5.582192e+03, -9.930639e+03, -1.239258e+02, 3.378337e+02, 5.651177e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.109094e+03, 3.580031e+01, 0, 0, 2.803934e+03, -2.399769e+01, 0, 2.604167e-04, -5.944797e+02, 2.075013e+01, 0, 0, -4.117657e+03, 1.320064e+02, 2.004808e-01, 7.812500e-04, 2.833792e+03, 1.774131e+02, 1.527515e+00, 8.854167e-03, -2.276165e+04, 1.257648e+03, 5.629040e+00, 4.140625e-02, -1.581115e+04, 2.383463e+03, 2.490926e+01, 2.221354e-01, -8.271046e+04, 6.514143e+03, 7.682795e+01, 8.695312e-01, -7.892773e+04, 1.023660e+04, 2.110950e+02, 3.012500e+00, -1.833413e+05, 1.835639e+04, 4.760003e+02, 8.611719e+00, -2.594243e+05, 2.515475e+04, 9.535555e+02, 2.177422e+01, -1.626629e+05, 2.553274e+04, 1.641990e+03, 4.828620e+01, -3.138765e+05, 3.311180e+04, 2.521424e+03, 9.437135e+01, -2.023791e+05, 2.790945e+04, 3.566488e+03, 1.692937e+02, -2.361401e+05, 2.715103e+04, 4.611801e+03, 2.781815e+02, -1.387146e+05, 1.936281e+04, 5.584871e+03, 4.265570e+02, -1.260435e+05, 1.563798e+04, 6.386036e+03, 6.144526e+02, -1.326077e+05, 1.212714e+04, 7.010195e+03, 8.421141e+02, -3.897682e+04, 3.959405e+03, 7.366325e+03, 1.106369e+03, -5.889334e+04, 3.350540e+03, 7.497170e+03, 1.398210e+03, -3.933554e+04, 2.719489e+02, 7.466882e+03, 1.714702e+03, -2.390631e+04, -1.853368e+03, 7.252314e+03, 2.047736e+03, -2.178522e+04, -2.640984e+03, 6.907977e+03, 2.389698e+03, -6.125885e+03, -4.003762e+03, 6.464812e+03, 2.734296e+03, -1.126017e+04, -3.477681e+03, 5.972548e+03, 3.074501e+03, -1.131751e+04, -3.475106e+03, 5.455067e+03, 3.407229e+03, -5.340261e+02, -4.136362e+03, 4.898586e+03, 3.727215e+03, -8.792165e+03, -2.990082e+03, 4.352596e+03, 4.028768e+03, -4.742079e+03, -3.169825e+03, 3.815352e+03, 4.311590e+03, -4.254148e+03, -2.851538e+03, 3.279048e+03, 4.570477e+03, -4.354544e+03, -2.480152e+03, 2.766874e+03, 4.803165e+03, -7.432540e+03, -1.878460e+03, 2.281570e+03, 5.007989e+03, -6.205415e+03, -1.788706e+03, 1.802434e+03, 5.183474e+03, -1.145931e+04, -9.481364e+02, 1.336118e+03, 5.325439e+03, -1.587470e+04, -2.321854e+02, 8.590106e+02, 5.432634e+03, -1.049374e+04, -6.518902e+01, 3.575002e+02, 5.499596e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8.531048e+02, 1.695939e+01, 0, 0, 6.095111e+02, 9.076932e+00, 1.122616e-01, 5.208333e-04, -6.857359e+02, 1.069152e+02, 3.785397e-01, 2.343750e-03, -6.528912e+03, 5.478130e+02, 2.211863e+00, 1.484375e-02, -2.807616e+04, 1.924054e+03, 1.181174e+01, 9.531250e-02, -4.135252e+04, 3.975660e+03, 4.662733e+01, 4.854167e-01, -6.513897e+04, 7.571929e+03, 1.340027e+02, 1.815104e+00, -1.130550e+05, 1.330006e+04, 3.248641e+02, 5.579167e+00, -2.128461e+05, 2.104638e+04, 6.894764e+02, 1.487135e+01, -1.938231e+05, 2.394323e+04, 1.270357e+03, 3.495443e+01, -2.250683e+05, 2.733125e+04, 2.036520e+03, 7.189036e+01, -1.878061e+05, 2.633878e+04, 2.957468e+03, 1.331286e+02, -2.270545e+05, 2.650296e+04, 3.950502e+03, 2.252544e+02, -1.452222e+05, 1.974198e+04, 4.908788e+03, 3.544242e+02, -9.739988e+04, 1.480522e+04, 5.714679e+03, 5.215013e+02, -1.391311e+05, 1.365247e+04, 6.380017e+03, 7.267320e+02, -4.788766e+04, 5.382256e+03, 6.821131e+03, 9.697984e+02, -5.285286e+04, 3.809721e+03, 7.022384e+03, 1.241959e+03, -3.337682e+04, 9.042881e+02, 7.062654e+03, 1.539764e+03, -4.007437e+04, -2.699339e+01, 6.941219e+03, 1.856429e+03, -6.051283e+03, -3.209377e+03, 6.660347e+03, 2.185851e+03, -2.435908e+04, -2.124954e+03, 6.283149e+03, 2.518370e+03, 2.551445e+03, -4.363071e+03, 5.832923e+03, 2.851286e+03, -1.489483e+04, -2.673771e+03, 5.352245e+03, 3.175629e+03, -9.389643e+03, -3.278006e+03, 4.853753e+03, 3.491487e+03, 3.161923e+03, -4.031601e+03, 4.306797e+03, 3.791312e+03, -1.194090e+04, -2.196499e+03, 3.796276e+03, 4.069944e+03, -2.953957e+03, -3.004063e+03, 3.287319e+03, 4.329823e+03, -6.149918e+03, -2.304854e+03, 2.774682e+03, 4.562834e+03, -3.373794e+03, -2.296007e+03, 2.282599e+03, 4.768486e+03, -1.034299e+04, -1.265867e+03, 1.820241e+03, 4.943532e+03, -1.110375e+04, -1.092537e+03, 1.348590e+03, 5.088307e+03, -1.629907e+04, -2.127533e+02, 8.538122e+02, 5.195697e+03, -1.089887e+04, -2.417175e+00, 3.439132e+02, 5.261939e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.508513e+01, 4.753078e+00, 0, 0, -7.542336e+02, 4.194538e+01, 5.820865e-02, 2.604167e-04, -1.284200e+03, 1.590937e+02, 6.480504e-01, 3.906250e-03, -7.617453e+03, 6.908946e+02, 3.653193e+00, 2.812500e-02, -2.285529e+04, 2.070239e+03, 1.729678e+01, 1.656250e-01, -4.265825e+04, 4.564970e+03, 6.200908e+01, 7.559896e-01, -8.135927e+04, 8.796250e+03, 1.745256e+02, 2.714323e+00, -1.186992e+05, 1.383851e+04, 4.094748e+02, 8.109375e+00, -1.729788e+05, 1.934059e+04, 8.160818e+02, 2.061328e+01, -1.630315e+05, 2.150283e+04, 1.411697e+03, 4.571406e+01, -1.624940e+05, 2.289915e+04, 2.160330e+03, 8.952969e+01, -1.678006e+05, 2.296466e+04, 3.025299e+03, 1.588792e+02, -1.625820e+05, 2.081553e+04, 3.926482e+03, 2.601164e+02, -1.026208e+05, 1.529805e+04, 4.748836e+03, 3.972128e+02, -9.110283e+04, 1.222390e+04, 5.429607e+03, 5.703201e+02, -7.839298e+04, 8.798951e+03, 5.957019e+03, 7.792841e+02, -4.969894e+04, 4.718760e+03, 6.285543e+03, 1.021049e+03, -3.394798e+04, 2.050471e+03, 6.418885e+03, 1.289738e+03, -2.926526e+04, 4.598630e+02, 6.397153e+03, 1.579698e+03, -1.911569e+04, -1.195949e+03, 6.238186e+03, 1.885275e+03, -2.090631e+04, -1.729267e+03, 5.964421e+03, 2.199667e+03, -1.444247e+03, -3.487510e+03, 5.588336e+03, 2.516915e+03, -1.151447e+04, -2.536741e+03, 5.168912e+03, 2.829230e+03, -1.111331e+04, -2.723565e+03, 4.725716e+03, 3.135111e+03, 1.710810e+03, -3.676459e+03, 4.229067e+03, 3.428469e+03, -1.164580e+04, -2.096150e+03, 3.746819e+03, 3.702957e+03, -1.692949e+03, -2.995892e+03, 3.257140e+03, 3.959883e+03, -8.118107e+03, -2.006853e+03, 2.767986e+03, 4.191197e+03, -4.383850e+03, -2.223397e+03, 2.285550e+03, 4.397215e+03, -9.697211e+03, -1.380502e+03, 1.813706e+03, 4.572417e+03, -7.068293e+03, -1.463914e+03, 1.337003e+03, 4.716157e+03, -2.122598e+04, 3.866204e+02, 8.784811e+02, 4.822514e+03, -1.022737e+04, -1.101296e+02, 3.443440e+02, 4.892292e+03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.856739e+02, 1.195308e+01, 0, 0, 0, 0, 0, 2.604167e-04, -1.720472e+02, 1.507814e+01, 0, 2.604167e-04, -5.197869e+03, 2.521753e+02, 2.669468e-01, 1.822917e-03, -1.789035e+03, 4.897775e+02, 4.126558e+00, 3.411458e-02, -2.356297e+04, 1.990572e+03, 1.685742e+01, 1.843750e-01, -3.079983e+04, 3.806333e+03, 6.218522e+01, 8.572917e-01, -5.867444e+04, 7.219324e+03, 1.679956e+02, 2.980208e+00, -9.193536e+04, 1.140888e+04, 3.838865e+02, 8.630729e+00, -1.093232e+05, 1.496515e+04, 7.495575e+02, 2.142161e+01, -1.454474e+05, 1.835651e+04, 1.277678e+03, 4.640313e+01, -1.060384e+05, 1.738770e+04, 1.939819e+03, 8.983255e+01, -1.317236e+05, 1.829440e+04, 2.673577e+03, 1.569544e+02, -9.918836e+04, 1.511239e+04, 3.428617e+03, 2.536474e+02, -6.597280e+04, 1.172004e+04, 4.108547e+03, 3.822750e+02, -8.933787e+04, 1.089011e+04, 4.698809e+03, 5.437974e+02, -3.303439e+04, 5.345711e+03, 5.140684e+03, 7.388943e+02, -4.639993e+04, 4.646300e+03, 5.414926e+03, 9.618318e+02, -2.854970e+04, 1.826186e+03, 5.551188e+03, 1.210728e+03, -2.483031e+04, 4.061465e+02, 5.528659e+03, 1.478848e+03, -1.065058e+04, -1.391460e+03, 5.374176e+03, 1.760276e+03, -7.673933e+03, -1.880549e+03, 5.126809e+03, 2.047961e+03, -1.467883e+04, -1.593262e+03, 4.830964e+03, 2.337684e+03, -7.526978e+03, -2.499826e+03, 4.467952e+03, 2.625599e+03, -4.169590e+03, -2.726037e+03, 4.046171e+03, 2.904100e+03, -4.507799e+03, -2.496923e+03, 3.611144e+03, 3.168575e+03, -6.215844e+03, -2.180448e+03, 3.176433e+03, 3.416260e+03, -9.828176e+03, -1.778987e+03, 2.732565e+03, 3.644142e+03, -2.786098e+03, -2.382096e+03, 2.253500e+03, 3.847887e+03, -6.796697e+03, -1.565581e+03, 1.789222e+03, 4.020204e+03, -1.447871e+04, -6.111844e+02, 1.348581e+03, 4.162343e+03, -1.363735e+04, -5.238507e+02, 8.553840e+02, 4.271182e+03, -9.848364e+03, -1.203178e+02, 3.610664e+02, 4.337093e+03, }; static float solarDataset400[] = { 1.117129e+12, -1.629427e+07, -4.340837e+02, 2.288813e-02, -3.507469e+09, 6.348417e+05, 0, 1.628578e-02, 2.505700e+07, -1.230995e+04, 0, 1.936688e-02, -1.719863e+07, 2.178956e+04, 0, 1.892672e-02, 1.438988e+06, -1.616402e+03, 6.806146e+00, 2.332828e-02, 1.696702e+05, 1.495455e+03, 8.179956e+00, 3.037078e-02, -1.912560e+06, 7.286691e+03, 1.412411e+01, 4.753688e-02, 1.068454e+06, -3.820033e+03, 1.852974e+01, 9.331313e-02, -4.480441e+05, 7.070752e+03, 2.347567e+01, 1.412902e-01, -2.844742e+05, 7.763926e+03, 5.756619e+01, 3.045881e-01, 3.820870e+05, 5.835991e+03, 1.114800e+02, 7.139334e-01, -5.903447e+05, 2.442660e+04, 2.153938e+02, 1.610972e+00, -2.022151e+05, 3.048178e+04, 4.667749e+02, 4.039754e+00, -7.774876e+05, 5.556041e+04, 9.199868e+02, 9.698843e+00, -7.414445e+05, 7.551752e+04, 1.760381e+03, 2.266144e+01, -1.531201e+06, 1.128349e+05, 3.140037e+03, 4.978959e+01, -1.554180e+06, 1.298094e+05, 5.235208e+03, 1.033051e+02, -1.695156e+06, 1.421715e+05, 7.966732e+03, 1.984392e+02, -1.678161e+06, 1.399827e+05, 1.119495e+04, 3.535841e+02, -1.463039e+06, 1.225635e+05, 1.457341e+04, 5.863313e+02, -1.215237e+06, 9.771091e+04, 1.769675e+04, 9.092475e+02, -8.636409e+05, 6.734484e+04, 2.022204e+04, 1.327606e+03, -6.651680e+05, 4.343026e+04, 2.196126e+04, 1.837785e+03, -3.857503e+05, 1.929567e+04, 2.286749e+04, 2.430659e+03, -3.671416e+05, 8.823173e+03, 2.302563e+04, 3.090578e+03, -1.503106e+05, -7.693949e+03, 2.251190e+04, 3.802935e+03, -1.434123e+05, -1.080121e+04, 2.148437e+04, 4.545612e+03, -7.621756e+04, -1.576213e+04, 2.013222e+04, 5.304807e+03, -7.041412e+04, -1.599827e+04, 1.854944e+04, 6.063558e+03, 1.247797e+04, -1.940579e+04, 1.683252e+04, 6.809340e+03, -4.230704e+04, -1.372257e+04, 1.516152e+04, 7.528765e+03, -1.341378e+04, -1.442508e+04, 1.354734e+04, 8.221723e+03, 1.305159e+04, -1.404328e+04, 1.196086e+04, 8.877132e+03, -3.228613e+04, -8.830029e+03, 1.054343e+04, 9.490735e+03, 6.334330e+03, -1.081216e+04, 9.192167e+03, 1.006662e+04, -1.320077e+04, -7.485103e+03, 7.933060e+03, 1.059296e+04, 9.474767e+03, -8.180859e+03, 6.789131e+03, 1.107455e+04, -1.394154e+04, -4.679057e+03, 5.796750e+03, 1.150659e+04, -3.468549e+03, -5.125712e+03, 4.894953e+03, 1.189805e+04, -1.168377e+04, -3.552944e+03, 4.047968e+03, 1.224160e+04, -3.595156e+03, -3.828358e+03, 3.246376e+03, 1.253896e+04, -9.636883e+03, -2.443091e+03, 2.519269e+03, 1.278460e+04, -1.695233e+04, -1.289283e+03, 1.854717e+03, 1.298280e+04, -1.903977e+04, -6.528410e+02, 1.170083e+03, 1.313098e+04, -1.350669e+04, -1.652916e+02, 4.953127e+02, 1.322139e+04, 1.427101e+11, -1.957428e+06, -5.973210e+01, 1.232438e-02, -2.505335e+09, 4.534583e+05, 0, 1.144406e-02, 2.505700e+07, -1.230995e+04, 0, 1.364484e-02, -1.530567e+07, 1.841817e+04, 0, 1.320469e-02, 1.680202e+06, -2.365652e+03, 4.815713e+00, 1.672594e-02, -1.426389e+06, 3.973627e+03, 5.413944e+00, 2.112750e-02, 6.318979e+05, -1.710393e+03, 7.350863e+00, 3.389203e-02, -1.473582e+05, 2.336923e+03, 8.947389e+00, 4.841719e-02, 6.750351e+04, 2.142457e+03, 1.881145e+01, 9.067219e-02, -6.137863e+04, 5.312427e+03, 3.767319e+01, 1.945491e-01, -2.368579e+05, 1.056334e+04, 8.328836e+01, 4.802105e-01, -3.502458e+04, 1.450254e+04, 1.806983e+02, 1.255326e+00, -3.536828e+05, 2.941026e+04, 3.742713e+02, 3.159882e+00, -5.525650e+05, 4.829087e+04, 7.804581e+02, 7.921052e+00, -1.131425e+06, 7.774385e+04, 1.543754e+03, 1.911026e+01, -9.674282e+05, 9.542627e+04, 2.833425e+03, 4.364369e+01, -1.726176e+06, 1.303805e+05, 4.757123e+03, 9.174177e+01, -1.560050e+06, 1.354377e+05, 7.402393e+03, 1.797757e+02, -1.659007e+06, 1.378766e+05, 1.051897e+04, 3.248278e+02, -1.371101e+06, 1.198850e+05, 1.384088e+04, 5.450543e+02, -1.299875e+06, 1.013112e+05, 1.696555e+04, 8.532262e+02, -7.373351e+05, 6.441420e+04, 1.952739e+04, 1.256523e+03, -6.447884e+05, 4.627416e+04, 2.134307e+04, 1.750144e+03, -5.825478e+05, 2.880250e+04, 2.244015e+04, 2.329148e+03, -1.914632e+05, 1.757698e+03, 2.265971e+04, 2.980030e+03, -2.801179e+05, 8.443567e+01, 2.221525e+04, 3.679473e+03, -9.016021e+04, -1.353444e+04, 2.127045e+04, 4.416034e+03, -5.848055e+04, -1.550950e+04, 1.993050e+04, 5.166405e+03, -8.007881e+04, -1.426653e+04, 1.844888e+04, 5.918714e+03, 4.462178e+03, -1.832929e+04, 1.682629e+04, 6.662612e+03, -8.309437e+04, -1.148821e+04, 1.520348e+04, 7.383206e+03, 4.995264e+04, -1.893244e+04, 1.352107e+04, 8.078812e+03, -3.495005e+04, -9.918410e+03, 1.197260e+04, 8.729566e+03, -2.254439e+03, -1.140785e+04, 1.057610e+04, 9.348295e+03, -1.194317e+04, -9.037030e+03, 9.229099e+03, 9.923259e+03, 4.037681e+03, -8.955305e+03, 7.980764e+03, 1.045434e+04, -1.351607e+04, -6.061553e+03, 6.864874e+03, 1.093757e+04, 7.338831e+03, -6.963548e+03, 5.837108e+03, 1.137736e+04, -2.292706e+04, -3.086934e+03, 4.940689e+03, 1.176787e+04, 4.648356e+03, -5.474011e+03, 4.063248e+03, 1.211814e+04, -1.227871e+04, -2.657876e+03, 3.270644e+03, 1.241280e+04, -8.698683e+03, -2.708755e+03, 2.554663e+03, 1.266362e+04, -1.098022e+04, -1.900095e+03, 1.865115e+03, 1.286352e+04, -2.959044e+04, 5.140675e+02, 1.222700e+03, 1.301222e+04, -1.386763e+04, -1.800631e+02, 4.732027e+02, 1.310906e+04, -2.250626e+10, 2.821518e+05, 2.735822e+01, 3.081094e-03, 1.015964e+08, -6.264336e+04, 1.702289e+01, 3.521250e-03, -1.603967e+07, -1.803368e+03, 6.342924e+00, 4.841719e-03, 2.035804e+07, -1.947652e+04, 0, 6.162188e-03, -6.628634e+06, 1.134906e+04, 0, 3.521250e-03, 5.620458e+05, -1.364648e+03, 1.880042e+00, 8.362969e-03, -3.417573e+05, 2.062172e+03, 1.747725e+00, 1.012359e-02, -7.534766e+03, 8.619116e+02, 5.863022e+00, 2.024719e-02, 8.599540e+04, 9.720702e+02, 1.069301e+01, 4.445578e-02, -1.156890e+05, 3.868880e+03, 2.157506e+01, 1.025564e-01, 7.657473e+04, 4.835159e+03, 5.014776e+01, 2.759780e-01, -2.781167e+05, 1.440504e+04, 1.128026e+02, 7.337405e-01, -2.634244e+05, 2.323850e+04, 2.708874e+02, 2.091182e+00, -5.456420e+05, 4.153386e+04, 5.949804e+02, 5.660850e+00, -7.962351e+05, 6.431258e+04, 1.232698e+03, 1.450623e+01, -1.197053e+06, 9.234505e+04, 2.349153e+03, 3.449857e+01, -1.230918e+06, 1.114998e+05, 4.089853e+03, 7.566110e+01, -1.644144e+06, 1.336157e+05, 6.498004e+03, 1.519362e+02, -1.555109e+06, 1.322636e+05, 9.493547e+03, 2.818699e+02, -1.357583e+06, 1.188301e+05, 1.271440e+04, 4.827603e+02, -1.116449e+06, 9.761383e+04, 1.581326e+04, 7.684710e+02, -9.139236e+05, 7.403173e+04, 1.847437e+04, 1.146857e+03, -6.990817e+05, 4.906624e+04, 2.044711e+04, 1.618387e+03, -3.467195e+05, 2.202997e+04, 2.157873e+04, 2.174869e+03, -4.305811e+05, 1.548297e+04, 2.198860e+04, 2.801117e+03, -1.289765e+05, -5.992939e+03, 2.170495e+04, 3.485799e+03, -1.198868e+05, -8.943475e+03, 2.086422e+04, 4.204074e+03, -1.470410e+05, -1.001341e+04, 1.974012e+04, 4.944323e+03, 1.334018e+03, -1.882254e+04, 1.828199e+04, 5.692294e+03, -3.345755e+04, -1.481065e+04, 1.670764e+04, 6.427177e+03, -4.222028e+04, -1.336937e+04, 1.517112e+04, 7.146100e+03, -1.048132e+04, -1.430800e+04, 1.359152e+04, 7.840347e+03, -2.882922e+03, -1.287178e+04, 1.204023e+04, 8.498728e+03, -1.162564e+04, -1.046185e+04, 1.060814e+04, 9.117565e+03, 8.458319e+02, -9.934087e+03, 9.276245e+03, 9.695744e+03, -1.175585e+04, -7.451056e+03, 8.062850e+03, 1.022931e+04, 3.308565e+02, -7.420070e+03, 6.941772e+03, 1.071991e+04, -1.318812e+04, -5.104680e+03, 5.924005e+03, 1.116308e+04, 2.440679e+03, -5.803752e+03, 4.972255e+03, 1.156184e+04, -1.312707e+04, -3.300552e+03, 4.125489e+03, 1.190999e+04, -6.642305e+03, -3.582143e+03, 3.336437e+03, 1.221449e+04, -7.838423e+03, -2.777393e+03, 2.585322e+03, 1.246768e+04, -1.594267e+04, -1.412070e+03, 1.904021e+03, 1.267038e+04, -2.650924e+04, 5.450457e+01, 1.222878e+03, 1.282292e+04, -1.407506e+04, -1.421113e+02, 4.719557e+02, 1.291827e+04, 0, 0, 0, 0, -1.002134e+09, 1.813833e+05, 0, 0, 2.505700e+07, -1.230995e+04, 0, 8.803125e-04, -3.540684e+06, 4.422303e+03, 0, 4.401563e-04, -1.077551e+06, 1.071832e+03, 1.320161e+00, 1.320469e-03, 4.561374e+05, -1.073274e+03, 0, 2.640938e-03, -1.241178e+05, 7.309221e+02, 0, 1.760625e-03, -6.807449e+03, 4.155531e+02, 1.415729e+00, 3.961406e-03, -5.892697e+04, 1.065543e+03, 3.663583e+00, 1.144406e-02, 7.462404e+04, 7.963727e+02, 9.161593e+00, 3.697313e-02, -1.449805e+05, 4.808397e+03, 2.148746e+01, 1.047572e-01, -7.483031e+04, 7.438418e+03, 6.219855e+01, 3.569667e-01, -1.551526e+05, 1.519258e+04, 1.534935e+02, 1.106993e+00, -3.869766e+05, 3.031932e+04, 3.687213e+02, 3.258917e+00, -7.418804e+05, 5.270793e+04, 8.372727e+02, 9.106833e+00, -8.892984e+05, 7.452028e+04, 1.720571e+03, 2.349510e+01, -1.173248e+06, 9.980147e+04, 3.160816e+03, 5.468281e+01, -1.451666e+06, 1.199829e+05, 5.273780e+03, 1.157149e+02, -1.406590e+06, 1.229404e+05, 7.982304e+03, 2.235989e+02, -1.256174e+06, 1.143387e+05, 1.101269e+04, 3.956375e+02, -1.047141e+06, 9.726801e+04, 1.405257e+04, 6.469126e+02, -9.893584e+05, 7.986424e+04, 1.679688e+04, 9.875755e+02, -6.207149e+05, 4.968663e+04, 1.891915e+04, 1.421301e+03, -4.129199e+05, 2.877273e+04, 2.024445e+04, 1.939607e+03, -3.571950e+05, 1.606478e+04, 2.087749e+04, 2.531703e+03, -1.930391e+05, 8.010621e+02, 2.084215e+04, 3.184647e+03, -1.137334e+05, -6.987208e+03, 2.024103e+04, 3.879152e+03, -9.850133e+04, -9.863565e+03, 1.928338e+04, 4.599642e+03, -9.788409e+04, -1.144184e+04, 1.805974e+04, 5.332882e+03, 1.245732e+04, -1.762258e+04, 1.658022e+04, 6.064098e+03, -5.720841e+04, -1.160080e+04, 1.506961e+04, 6.775777e+03, 1.067936e+04, -1.514209e+04, 1.355611e+04, 7.467565e+03, -2.175393e+04, -1.083518e+04, 1.208639e+04, 8.124791e+03, -1.089978e+04, -1.053521e+04, 1.070786e+04, 8.749151e+03, 1.343549e+03, -9.970273e+03, 9.374791e+03, 9.333012e+03, -1.328865e+04, -7.346112e+03, 8.162598e+03, 9.872624e+03, -1.034417e+03, -7.407299e+03, 7.035667e+03, 1.036975e+04, -5.754438e+03, -5.779644e+03, 6.000216e+03, 1.081900e+04, -9.018099e+03, -4.670102e+03, 5.068244e+03, 1.122259e+04, -9.313739e+02, -4.706751e+03, 4.193278e+03, 1.157960e+04, -1.674258e+04, -2.394722e+03, 3.415508e+03, 1.188682e+04, -4.162404e+03, -3.416222e+03, 2.647810e+03, 1.214910e+04, -1.641018e+04, -1.375684e+03, 1.940197e+03, 1.235489e+04, -2.597781e+04, -4.072350e+01, 1.253613e+03, 1.251075e+04, -1.550160e+04, -5.658062e+01, 4.993210e+02, 1.260869e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.571821e+05, 1.194273e+03, 0, 0, 2.280687e+05, -5.366371e+02, 0, 4.401563e-04, -3.880904e+04, 2.686421e+02, 0, 0, -1.184002e+05, 6.513468e+02, 6.182344e-01, 8.803125e-04, 6.120952e+04, -2.568675e+02, 1.398755e+00, 5.281875e-03, -2.456577e+04, 8.465396e+02, 2.046431e+00, 1.012359e-02, -5.560163e+04, 2.207308e+03, 8.347310e+00, 3.565266e-02, -6.365941e+04, 4.514850e+03, 2.810550e+01, 1.448114e-01, -1.150207e+05, 9.826355e+03, 8.095553e+01, 5.281875e-01, -2.675326e+05, 2.088122e+04, 2.172854e+02, 1.764146e+00, -4.855776e+05, 3.851471e+04, 5.397100e+02, 5.445173e+00, -8.721331e+05, 6.367194e+04, 1.205217e+03, 1.524745e+01, -9.184539e+05, 8.282197e+04, 2.383759e+03, 3.838735e+01, -1.307361e+06, 1.073647e+05, 4.170076e+03, 8.581991e+01, -1.216270e+06, 1.119986e+05, 6.587459e+03, 1.736267e+02, -1.276352e+06, 1.124177e+05, 9.409381e+03, 3.185987e+02, -9.788697e+05, 9.416016e+04, 1.235028e+04, 5.374427e+02, -7.995613e+05, 7.618671e+04, 1.505625e+04, 8.403357e+02, -7.460602e+05, 5.950676e+04, 1.732816e+04, 1.232937e+03, -4.349269e+05, 3.288320e+04, 1.890991e+04, 1.714067e+03, -2.903175e+05, 1.679987e+04, 1.972389e+04, 2.270884e+03, -2.341700e+05, 6.717412e+03, 1.992757e+04, 2.890724e+03, -1.591140e+05, -2.541145e+03, 1.958483e+04, 3.559598e+03, -9.377026e+04, -9.049582e+03, 1.877055e+04, 4.259945e+03, -3.112181e+04, -1.324477e+04, 1.763230e+04, 4.974656e+03, -6.713941e+04, -1.097160e+04, 1.635475e+04, 5.689683e+03, -1.171086e+04, -1.418498e+04, 1.495911e+04, 6.397430e+03, -1.203079e+04, -1.259366e+04, 1.351290e+04, 7.082987e+03, -2.735949e+04, -1.036650e+04, 1.212531e+04, 7.741638e+03, 8.398267e+03, -1.176714e+04, 1.074781e+04, 8.368608e+03, -2.360952e+04, -7.700526e+03, 9.466757e+03, 8.954412e+03, 3.871276e+03, -9.056076e+03, 8.250344e+03, 9.502464e+03, -6.443405e+03, -6.671943e+03, 7.119198e+03, 1.000279e+04, -7.871410e+03, -5.649041e+03, 6.108047e+03, 1.045952e+04, -8.718557e+03, -4.829450e+03, 5.161480e+03, 1.087083e+04, -1.292495e+03, -4.766287e+03, 4.267365e+03, 1.123419e+04, -9.861345e+03, -3.065607e+03, 3.472933e+03, 1.154681e+04, -1.727524e+04, -2.001187e+03, 2.739962e+03, 1.181333e+04, -9.339880e+03, -2.491882e+03, 1.972342e+03, 1.202929e+04, -2.480383e+04, -8.960043e+01, 1.262307e+03, 1.218417e+04, -1.550976e+04, -1.052398e+02, 5.321763e+02, 1.228360e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.280687e+05, 5.366371e+02, 0, 0, 0, 0, 0, 4.401563e-04, 0, 0, 0, 4.401563e-04, -1.733338e+04, 2.221243e+02, 0, 4.401563e-04, -1.275858e+04, 4.042146e+02, 9.341664e-01, 2.640938e-03, 1.648620e+03, 8.526882e+02, 3.875433e+00, 1.452516e-02, -1.019729e+05, 3.723777e+03, 1.376684e+01, 6.470297e-02, -5.222279e+04, 6.376447e+03, 5.040666e+01, 3.006267e-01, -1.972467e+05, 1.575596e+04, 1.432681e+02, 1.097310e+00, -4.522255e+05, 3.224516e+04, 3.877865e+02, 3.683668e+00, -6.472011e+05, 5.229836e+04, 9.287428e+02, 1.113463e+01, -9.846451e+05, 7.751316e+04, 1.928807e+03, 2.951336e+01, -1.120147e+06, 9.516690e+04, 3.526207e+03, 6.930084e+01, -1.060774e+06, 1.024968e+05, 5.698072e+03, 1.445909e+02, -1.080278e+06, 1.054362e+05, 8.329768e+03, 2.717027e+02, -1.167184e+06, 1.012812e+05, 1.122358e+04, 4.681035e+02, -8.134116e+05, 7.589663e+04, 1.397221e+04, 7.479364e+02, -5.142486e+05, 5.263146e+04, 1.620649e+04, 1.114264e+03, -5.840860e+05, 4.293903e+04, 1.790499e+04, 1.565472e+03, -2.806635e+05, 1.804160e+04, 1.892835e+04, 2.098314e+03, -1.902676e+05, 6.983141e+03, 1.923705e+04, 2.694941e+03, -2.082007e+05, 2.150441e+03, 1.906114e+04, 3.342563e+03, -5.374742e+04, -9.636906e+03, 1.839341e+04, 4.027727e+03, -9.427047e+04, -8.455175e+03, 1.739289e+04, 4.729183e+03, -1.263315e+04, -1.383242e+04, 1.618343e+04, 5.437924e+03, -5.405956e+04, -1.051530e+04, 1.486152e+04, 6.137134e+03, 4.123323e+03, -1.373276e+04, 1.347434e+04, 6.821774e+03, -1.966848e+04, -1.038438e+04, 1.209746e+04, 7.477629e+03, -1.751199e+04, -9.652355e+03, 1.078686e+04, 8.104279e+03, 3.295847e+03, -1.002127e+04, 9.489445e+03, 8.694407e+03, -1.938731e+03, -7.963785e+03, 8.293167e+03, 9.241338e+03, -2.615570e+04, -5.085764e+03, 7.230361e+03, 9.747489e+03, 1.004382e+04, -7.737635e+03, 6.157052e+03, 1.021296e+04, -1.151870e+04, -4.264058e+03, 5.190961e+03, 1.062368e+04, -5.395239e+03, -4.360268e+03, 4.334166e+03, 1.099135e+04, -1.187237e+04, -3.068215e+03, 3.525120e+03, 1.130985e+04, -8.828785e+03, -2.951184e+03, 2.748294e+03, 1.157956e+04, -1.425606e+04, -1.790576e+03, 2.012464e+03, 1.179469e+04, -3.104649e+04, 4.096561e+02, 1.304758e+03, 1.195543e+04, -1.414188e+04, -2.345618e+02, 4.929940e+02, 1.205795e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.284378e+03, 4.000235e+01, 0, 0, -1.596943e+04, 2.327633e+02, 2.033762e-01, 4.401563e-04, 1.547436e+04, 9.728437e+01, 1.332585e+00, 4.841719e-03, -4.391863e+04, 1.611874e+03, 3.954053e+00, 1.848656e-02, -1.774277e+04, 3.338879e+03, 1.984506e+01, 1.069580e-01, -2.636354e+05, 1.231744e+04, 7.035266e+01, 4.762491e-01, -1.523250e+05, 1.881496e+04, 2.323194e+02, 2.013715e+00, -5.937322e+05, 4.171430e+04, 5.875574e+02, 6.570653e+00, -7.266381e+05, 6.055013e+04, 1.349311e+03, 1.917673e+01, -8.860678e+05, 8.010778e+04, 2.622440e+03, 4.815926e+01, -1.086569e+06, 9.639717e+04, 4.493415e+03, 1.062836e+02, -9.745768e+05, 9.666372e+04, 6.884892e+03, 2.100144e+02, -1.047773e+06, 9.496512e+04, 9.556296e+03, 3.754075e+02, -6.732150e+05, 7.257512e+04, 1.219959e+04, 6.172408e+02, -6.412646e+05, 6.073496e+04, 1.451547e+04, 9.412046e+02, -4.770761e+05, 4.172546e+04, 1.637709e+04, 1.351410e+03, -3.658491e+05, 2.573258e+04, 1.759304e+04, 1.842114e+03, -1.459050e+05, 7.797252e+03, 1.813296e+04, 2.402150e+03, -2.270501e+05, 6.345087e+03, 1.816235e+04, 3.015249e+03, -5.163556e+04, -7.248933e+03, 1.772472e+04, 3.672398e+03, -9.784000e+04, -6.113061e+03, 1.692069e+04, 4.351479e+03, -4.721276e+04, -1.058933e+04, 1.588911e+04, 5.044252e+03, -2.325812e+04, -1.187676e+04, 1.464898e+04, 5.733633e+03, -7.615191e+03, -1.186838e+04, 1.334468e+04, 6.408326e+03, -2.309797e+04, -9.681961e+03, 1.206642e+04, 7.060851e+03, -1.619285e+04, -9.482512e+03, 1.080185e+04, 7.687342e+03, 2.078178e+03, -9.714292e+03, 9.537486e+03, 8.279170e+03, -1.618945e+04, -6.927762e+03, 8.365159e+03, 8.829938e+03, 7.335199e+02, -7.533587e+03, 7.255793e+03, 9.341236e+03, -1.450326e+03, -6.043556e+03, 6.228118e+03, 9.805634e+03, -1.816953e+04, -3.758371e+03, 5.326053e+03, 1.022606e+04, -1.744599e+03, -5.007206e+03, 4.429541e+03, 1.060407e+04, -1.013527e+04, -3.265815e+03, 3.587398e+03, 1.092797e+04, -1.259356e+04, -2.582008e+03, 2.814548e+03, 1.120259e+04, -1.274805e+04, -2.097313e+03, 2.054883e+03, 1.142390e+04, -2.791789e+04, 7.523855e+01, 1.329347e+03, 1.158716e+04, -1.719612e+04, -4.713965e+00, 5.420132e+02, 1.169180e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.176421e+02, 3.113526e+01, 0, 0, -1.800870e+04, 5.044997e+02, 2.852090e-01, 8.803125e-04, -6.298356e+03, 1.097487e+03, 4.660042e+00, 2.068734e-02, -8.791947e+04, 4.920687e+03, 2.117041e+01, 1.267650e-01, -1.511792e+05, 1.141104e+04, 9.051543e+01, 6.901650e-01, -3.106193e+05, 2.415462e+04, 2.850943e+02, 2.830205e+00, -5.405713e+05, 4.217464e+04, 7.415631e+02, 9.508255e+00, -5.706933e+05, 5.709472e+04, 1.607830e+03, 2.680684e+01, -8.596668e+05, 7.785137e+04, 2.987113e+03, 6.433676e+01, -8.771786e+05, 8.485822e+04, 4.935285e+03, 1.368477e+02, -8.102174e+05, 8.281917e+04, 7.255334e+03, 2.600694e+02, -6.674694e+05, 7.297462e+04, 9.707332e+03, 4.485879e+02, -6.717545e+05, 6.389033e+04, 1.205217e+04, 7.132714e+02, -3.554819e+05, 4.055708e+04, 1.401631e+04, 1.060593e+03, -4.167811e+05, 3.366675e+04, 1.546312e+04, 1.485747e+03, -1.323838e+05, 1.206436e+04, 1.634842e+04, 1.985782e+03, -2.565296e+05, 1.235833e+04, 1.671070e+04, 2.544205e+03, -7.754431e+04, -2.778930e+03, 1.659321e+04, 3.155150e+03, -6.065238e+04, -5.532359e+03, 1.601994e+04, 3.795263e+03, -6.016013e+04, -6.874641e+03, 1.523403e+04, 4.453979e+03, -3.842724e+04, -9.051155e+03, 1.424960e+04, 5.120220e+03, -1.505812e+04, -1.038403e+04, 1.311185e+04, 5.780549e+03, -1.932609e+04, -9.311433e+03, 1.192713e+04, 6.424029e+03, -2.567878e+03, -9.668649e+03, 1.073681e+04, 7.044632e+03, -2.137310e+04, -7.226824e+03, 9.588529e+03, 7.634721e+03, -4.048428e+03, -8.024655e+03, 8.455858e+03, 8.192586e+03, -9.345105e+03, -6.504380e+03, 7.358232e+03, 8.708498e+03, 1.110868e+03, -6.498387e+03, 6.328846e+03, 9.181543e+03, -1.038927e+04, -4.423289e+03, 5.401265e+03, 9.607874e+03, -8.382929e+03, -4.148725e+03, 4.539967e+03, 9.991244e+03, -1.284061e+04, -3.196734e+03, 3.706702e+03, 1.032616e+04, -7.952644e+03, -3.238144e+03, 2.887171e+03, 1.060975e+04, -2.012766e+04, -1.354531e+03, 2.121075e+03, 1.083559e+04, -2.131326e+04, -8.004748e+02, 1.341130e+03, 1.100550e+04, -1.524196e+04, -2.164961e+02, 5.721496e+02, 1.110911e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.811733e+03, 6.623464e+01, 0, 0, 2.568464e+03, 8.432503e+01, 5.115023e-01, 2.200781e-03, -2.004794e+04, 1.119994e+03, 2.378582e+00, 1.320469e-02, -5.899960e+04, 3.846531e+03, 1.815237e+01, 1.184020e-01, -1.105061e+05, 9.320633e+03, 8.088947e+01, 6.950067e-01, -2.221620e+05, 1.985802e+04, 2.613633e+02, 2.927919e+00, -4.065581e+05, 3.551385e+04, 6.885058e+02, 9.926844e+00, -5.094984e+05, 4.979654e+04, 1.507612e+03, 2.812995e+01, -6.336678e+05, 6.263542e+04, 2.791695e+03, 6.759920e+01, -5.771321e+05, 6.548998e+04, 4.520174e+03, 1.419161e+02, -5.870919e+05, 6.615160e+04, 6.549199e+03, 2.651867e+02, -5.916423e+05, 6.099313e+04, 8.705613e+03, 4.515611e+02, -3.105146e+05, 4.215730e+04, 1.068282e+04, 7.107075e+02, -3.690182e+05, 3.754835e+04, 1.233110e+04, 1.043000e+03, -2.480750e+05, 2.322678e+04, 1.359551e+04, 1.450970e+03, -1.497117e+05, 1.185092e+04, 1.431604e+04, 1.925035e+03, -8.514757e+04, 4.263741e+03, 1.458441e+04, 2.453455e+03, -1.505205e+05, 4.067158e+03, 1.452717e+04, 3.025317e+03, -3.556097e+03, -7.629858e+03, 1.407200e+04, 3.631602e+03, -5.542532e+04, -4.547126e+03, 1.336358e+04, 4.249173e+03, -2.492334e+04, -7.511616e+03, 1.254118e+04, 4.875408e+03, -3.228374e+04, -7.095606e+03, 1.157333e+04, 5.495835e+03, 8.005456e+03, -9.642728e+03, 1.050910e+04, 6.101611e+03, -2.540419e+04, -5.998865e+03, 9.470682e+03, 6.680639e+03, -1.534258e+03, -7.644748e+03, 8.443364e+03, 7.234962e+03, -1.521422e+04, -5.588894e+03, 7.427301e+03, 7.752369e+03, 2.151713e+03, -6.514804e+03, 6.440484e+03, 8.232600e+03, -1.841369e+04, -3.729884e+03, 5.527030e+03, 8.667363e+03, 1.579701e+03, -5.323167e+03, 4.630580e+03, 9.060834e+03, -1.605496e+04, -2.666378e+03, 3.802381e+03, 9.400648e+03, -1.363337e+04, -2.777913e+03, 3.003439e+03, 9.694207e+03, -9.563748e+03, -2.638621e+03, 2.184130e+03, 9.930046e+03, -3.556888e+04, 7.624686e+02, 1.440821e+03, 1.010325e+04, -1.690964e+04, -1.764955e+02, 5.681839e+02, 1.021822e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.643694e+03, 1.140404e+02, 0, 0, -6.562979e+03, 4.816660e+02, 1.445460e+00, 7.922813e-03, -1.299063e+04, 1.609270e+03, 9.594276e+00, 7.218563e-02, -7.131240e+04, 5.726209e+03, 4.357593e+01, 4.150673e-01, -1.117634e+05, 1.180640e+04, 1.624316e+02, 1.965298e+00, -2.304253e+05, 2.279086e+04, 4.523525e+02, 7.057025e+00, -3.315911e+05, 3.411993e+04, 1.042647e+03, 2.092943e+01, -3.603710e+05, 4.191874e+04, 1.999991e+03, 5.211274e+01, -3.916216e+05, 4.727670e+04, 3.311539e+03, 1.116914e+02, -3.844057e+05, 4.753490e+04, 4.900611e+03, 2.125391e+02, -3.148316e+05, 4.217486e+04, 6.599279e+03, 3.665476e+02, -2.947627e+05, 3.672338e+04, 8.238001e+03, 5.821150e+02, -1.877393e+05, 2.615824e+04, 9.665892e+03, 8.644409e+02, -1.939038e+05, 2.109766e+04, 1.078832e+04, 1.211959e+03, -1.268775e+05, 1.194889e+04, 1.155350e+04, 1.622333e+03, -5.212276e+04, 4.145660e+03, 1.190591e+04, 2.084908e+03, -1.041510e+05, 4.464942e+03, 1.197827e+04, 2.588510e+03, -1.984863e+04, -3.569719e+03, 1.174725e+04, 3.127176e+03, -3.741808e+04, -3.091579e+03, 1.126593e+04, 3.681872e+03, -2.888744e+04, -4.650632e+03, 1.065302e+04, 4.246808e+03, -6.248874e+03, -6.533785e+03, 9.886316e+03, 4.810160e+03, -1.492326e+04, -5.462305e+03, 9.064728e+03, 5.360728e+03, -1.612605e+04, -5.277340e+03, 8.222609e+03, 5.894540e+03, -1.302281e+04, -5.381978e+03, 7.329188e+03, 6.403576e+03, 1.844868e+03, -6.123135e+03, 6.402092e+03, 6.878745e+03, -1.598640e+04, -3.668586e+03, 5.540739e+03, 7.312670e+03, -3.218371e+03, -4.662379e+03, 4.696477e+03, 7.708645e+03, -1.404880e+04, -2.925585e+03, 3.881197e+03, 8.055558e+03, -1.463165e+04, -2.666220e+03, 3.081586e+03, 8.355163e+03, -1.277586e+04, -2.405669e+03, 2.258415e+03, 8.598143e+03, -3.742817e+04, 7.803610e+02, 1.474543e+03, 8.777701e+03, -1.548654e+04, -3.160486e+02, 5.519917e+02, 8.894396e+03, }; static float solarDataset440[] = { -6.439155e+11, 7.682264e+06, 1.061520e+03, 2.039373e+00, -1.551568e+09, -1.644546e+06, 7.523669e+02, 2.056656e+00, 1.570174e+09, -8.522139e+05, 2.877172e+02, 2.120770e+00, -3.012090e+08, 4.421119e+05, 2.347757e+02, 2.178751e+00, -2.081867e+07, 7.272809e+04, 4.311484e+02, 2.430188e+00, 7.899508e+06, 1.295109e+04, 5.150411e+02, 2.939752e+00, 4.151745e+06, 2.883739e+04, 6.139858e+02, 3.810026e+00, 3.293018e+06, 4.361918e+04, 7.999407e+02, 5.335932e+00, -3.828120e+06, 9.429242e+04, 1.137923e+03, 8.117909e+00, 2.986346e+06, 6.726090e+04, 1.682654e+03, 1.349342e+01, -1.518315e+06, 1.401839e+05, 2.506574e+03, 2.312609e+01, -2.560500e+06, 1.889565e+05, 3.957987e+03, 4.170958e+01, -3.827648e+06, 2.429145e+05, 6.184460e+03, 7.682438e+01, -3.299120e+06, 2.716569e+05, 9.361640e+03, 1.406772e+02, -4.786591e+06, 3.230548e+05, 1.360464e+04, 2.503356e+02, -5.235884e+06, 3.347402e+05, 1.893351e+04, 4.303752e+02, -4.344959e+06, 2.992049e+05, 2.482781e+04, 7.073441e+02, -4.495848e+06, 2.671507e+05, 3.067007e+04, 1.104209e+03, -2.904965e+06, 1.819224e+05, 3.574947e+04, 1.639240e+03, -2.295257e+06, 1.245881e+05, 3.945941e+04, 2.313019e+03, -2.021822e+06, 7.712727e+04, 4.169658e+04, 3.119853e+03, -5.892701e+05, 4.095196e+03, 4.218370e+04, 4.041884e+03, -1.166644e+06, 8.504980e+03, 4.136899e+04, 5.044736e+03, -1.972687e+05, -4.070728e+04, 3.941477e+04, 6.112839e+03, -2.093258e+05, -3.893157e+04, 3.660650e+04, 7.200837e+03, -2.639589e+05, -3.598837e+04, 3.358396e+04, 8.293512e+03, 8.246154e+03, -4.584505e+04, 3.026767e+04, 9.372228e+03, -6.438522e+04, -3.581717e+04, 2.697011e+04, 1.041147e+04, -7.353188e+04, -3.121684e+04, 2.387281e+04, 1.140770e+04, 5.933961e+04, -3.366294e+04, 2.086077e+04, 1.235002e+04, -3.538054e+04, -2.202528e+04, 1.819119e+04, 1.322614e+04, -2.443121e+04, -1.981273e+04, 1.582620e+04, 1.404641e+04, 3.781173e+04, -2.036056e+04, 1.359973e+04, 1.480309e+04, -1.650133e+04, -1.256169e+04, 1.171377e+04, 1.549140e+04, -1.983390e+04, -1.069497e+04, 1.008886e+04, 1.612572e+04, 1.056101e+04, -1.130558e+04, 8.546710e+03, 1.670160e+04, -2.713816e+03, -7.912829e+03, 7.207588e+03, 1.721354e+04, -4.452889e+03, -6.395793e+03, 6.078559e+03, 1.767169e+04, -6.835308e+03, -5.126471e+03, 5.077617e+03, 1.807822e+04, -9.922932e+03, -4.054774e+03, 4.171164e+03, 1.843425e+04, -4.659839e+03, -3.888745e+03, 3.322981e+03, 1.873921e+04, -9.547958e+03, -2.601152e+03, 2.562645e+03, 1.899026e+04, -1.701043e+04, -1.361229e+03, 1.872053e+03, 1.919113e+04, -1.872608e+04, -7.127307e+02, 1.172457e+03, 1.934026e+04, -1.350361e+04, -1.647467e+02, 4.949774e+02, 1.943062e+04, 2.157451e+11, 1.943248e+06, -2.593158e+02, 9.505553e-01, -7.114316e+10, 1.371541e+07, 0, 9.477677e-01, 1.280844e+09, -7.152589e+05, 2.024044e+02, 1.022474e+00, -3.379517e+08, 4.237257e+05, 1.460656e+02, 1.057040e+00, 3.483677e+07, -4.170331e+04, 2.741455e+02, 1.234886e+00, -6.107958e+06, 4.113951e+04, 3.019965e+02, 1.517543e+00, 6.609522e+06, 7.210950e+03, 3.859744e+02, 2.068921e+00, 6.293178e+05, 4.235131e+04, 5.125775e+02, 3.017804e+00, -8.119125e+05, 6.395016e+04, 7.753549e+02, 4.886021e+00, -1.001544e+06, 8.369718e+04, 1.219698e+03, 8.638624e+00, 2.469002e+05, 1.020158e+05, 1.936104e+03, 1.606076e+01, -3.071414e+06, 1.744496e+05, 3.124365e+03, 3.047463e+01, -2.398553e+06, 2.065189e+05, 5.080502e+03, 5.904147e+01, -4.148108e+06, 2.720416e+05, 7.949415e+03, 1.123456e+02, -4.421216e+06, 3.044491e+05, 1.197323e+04, 2.080105e+02, -4.886328e+06, 3.225125e+05, 1.702702e+04, 3.685740e+02, -4.260302e+06, 2.983774e+05, 2.277937e+04, 6.206306e+02, -4.488843e+06, 2.719539e+05, 2.864869e+04, 9.887191e+02, -3.035307e+06, 1.911892e+05, 3.388554e+04, 1.492962e+03, -2.303207e+06, 1.301134e+05, 3.780104e+04, 2.135924e+03, -1.695747e+06, 7.533493e+04, 4.024633e+04, 2.912218e+03, -1.131339e+06, 2.856670e+04, 4.111774e+04, 3.805227e+03, -7.045700e+05, -4.867972e+03, 4.054360e+04, 4.789173e+03, -3.620224e+05, -2.694148e+04, 3.883948e+04, 5.834790e+03, -4.066279e+05, -2.925181e+04, 3.641435e+04, 6.913749e+03, -1.132796e+05, -4.305023e+04, 3.342235e+04, 8.003883e+03, 3.570589e+03, -4.331910e+04, 3.014234e+04, 9.074909e+03, -1.133431e+05, -3.225022e+04, 2.700976e+04, 1.011271e+04, 1.186040e+03, -3.456607e+04, 2.396680e+04, 1.111301e+04, -4.979073e+04, -2.665824e+04, 2.106894e+04, 1.205891e+04, 1.592532e+04, -2.657005e+04, 1.836669e+04, 1.294864e+04, 8.401869e+03, -2.123268e+04, 1.592066e+04, 1.377255e+04, -2.611279e+04, -1.551961e+04, 1.380784e+04, 1.453477e+04, 1.246222e+04, -1.579531e+04, 1.187851e+04, 1.523848e+04, -6.658919e+03, -1.142901e+04, 1.017094e+04, 1.587713e+04, 1.928404e+03, -1.015849e+04, 8.688190e+03, 1.645836e+04, -1.608648e+04, -7.006837e+03, 7.388582e+03, 1.698200e+04, 6.840295e+03, -7.868280e+03, 6.193951e+03, 1.745255e+04, -1.757879e+04, -4.203383e+03, 5.158025e+03, 1.786403e+04, 6.926599e+03, -5.876158e+03, 4.203700e+03, 1.822680e+04, -1.598552e+04, -2.390669e+03, 3.390699e+03, 1.853138e+04, -6.027778e+03, -3.175285e+03, 2.640031e+03, 1.879204e+04, -1.851678e+04, -1.220782e+03, 1.930943e+03, 1.899774e+04, -2.290692e+04, -3.911046e+02, 1.218154e+03, 1.915237e+04, -1.519600e+04, -2.633004e+01, 4.835101e+02, 1.924636e+04, -3.704596e+12, 5.454497e+07, 1.421905e+03, 2.926930e-01, 3.173305e+09, -5.743591e+05, 0, 3.144359e-01, -3.364539e+06, 6.299289e+03, 0, 3.116483e-01, -3.980029e+08, 4.573928e+05, 3.043542e+00, 3.122058e-01, 4.559887e+07, -6.916950e+04, 1.007848e+02, 3.969474e-01, -2.443350e+07, 8.526024e+04, 1.065719e+02, 4.794590e-01, 5.589237e+06, -4.160307e+03, 1.936915e+02, 7.621167e-01, 9.451238e+04, 2.614347e+04, 2.558371e+02, 1.224850e+00, 3.067526e+04, 3.723230e+04, 4.105653e+02, 2.194361e+00, -7.036798e+05, 5.911092e+04, 6.903957e+02, 4.252689e+00, -5.513797e+05, 8.299526e+04, 1.196595e+03, 8.696047e+00, -2.191497e+06, 1.345808e+05, 2.089839e+03, 1.812299e+01, -2.070793e+06, 1.743475e+05, 3.623925e+03, 3.802500e+01, -4.038717e+06, 2.455242e+05, 6.036923e+03, 7.762385e+01, -3.761674e+06, 2.746045e+05, 9.589842e+03, 1.529898e+02, -5.050391e+06, 3.152332e+05, 1.422849e+04, 2.849469e+02, -4.033593e+06, 2.876971e+05, 1.972387e+04, 5.007826e+02, -3.837058e+06, 2.611389e+05, 2.542725e+04, 8.243544e+02, -3.415481e+06, 2.122601e+05, 3.081216e+04, 1.277441e+03, -2.263710e+06, 1.384666e+05, 3.511626e+04, 1.870490e+03, -1.502418e+06, 8.143096e+04, 3.793597e+04, 2.597510e+03, -1.629920e+06, 5.437166e+04, 3.934644e+04, 3.445165e+03, -3.463979e+05, -1.248103e+04, 3.915122e+04, 4.394698e+03, -4.796136e+05, -1.400399e+04, 3.778512e+04, 5.405067e+03, -4.525999e+05, -2.265499e+04, 3.581125e+04, 6.461725e+03, -3.180239e+04, -4.281554e+04, 3.309592e+04, 7.538118e+03, -1.696614e+05, -3.260128e+04, 3.010816e+04, 8.601531e+03, 2.216761e+03, -3.819533e+04, 2.706857e+04, 9.643927e+03, -5.840964e+04, -2.977311e+04, 2.409090e+04, 1.064435e+04, -5.917126e+04, -2.642897e+04, 2.128022e+04, 1.159950e+04, 7.415464e+04, -2.984562e+04, 1.854160e+04, 1.249835e+04, -4.015798e+04, -1.708081e+04, 1.618474e+04, 1.332958e+04, -2.724330e+04, -1.610742e+04, 1.411441e+04, 1.410972e+04, 3.392267e+04, -1.758161e+04, 1.211073e+04, 1.482824e+04, -1.941985e+04, -1.017686e+04, 1.041268e+04, 1.547855e+04, -1.295582e+04, -9.453817e+03, 8.939028e+03, 1.607642e+04, 1.103183e+04, -9.749963e+03, 7.541593e+03, 1.661529e+04, -1.309367e+04, -5.774869e+03, 6.355166e+03, 1.709222e+04, -6.434020e+03, -5.622814e+03, 5.307434e+03, 1.751883e+04, -4.996029e+03, -4.764721e+03, 4.331959e+03, 1.788974e+04, -4.447507e+03, -3.893715e+03, 3.465440e+03, 1.820564e+04, -1.239499e+04, -2.374546e+03, 2.708845e+03, 1.846887e+04, -1.791766e+04, -1.467369e+03, 1.990862e+03, 1.868255e+04, -2.061413e+04, -6.862093e+02, 1.247688e+03, 1.884111e+04, -1.468218e+04, -1.400460e+02, 5.211565e+02, 1.893732e+04, 1.308076e+12, -1.882941e+07, -5.168990e+02, 4.404332e-02, -8.250594e+09, 1.493334e+06, 0, 3.623818e-02, 6.347536e+07, -3.118404e+04, 0, 4.348581e-02, -6.744998e+07, 8.687614e+04, 0, 4.237079e-02, -1.059940e+06, 1.737933e+03, 2.850557e+01, 6.021112e-02, 3.873147e+06, -6.437214e+03, 2.864464e+01, 9.087420e-02, -2.038775e+06, 1.383359e+04, 3.704050e+01, 1.349175e-01, 1.734783e+06, 9.982716e+02, 6.829641e+01, 2.609149e-01, -1.300032e+06, 2.675349e+04, 1.182804e+02, 5.112371e-01, -4.406929e+05, 3.149201e+04, 2.638582e+02, 1.259974e+00, -8.366025e+05, 5.266660e+04, 5.292339e+02, 3.134881e+00, -7.924932e+05, 7.942542e+04, 1.048528e+03, 7.713714e+00, -2.114312e+06, 1.343945e+05, 2.024267e+03, 1.835492e+01, -3.185798e+06, 1.914041e+05, 3.782729e+03, 4.238696e+01, -3.032631e+06, 2.279831e+05, 6.542534e+03, 9.240122e+01, -4.568244e+06, 2.833195e+05, 1.042573e+04, 1.866350e+02, -3.365946e+06, 2.645481e+05, 1.535126e+04, 3.512042e+02, -4.471630e+06, 2.758277e+05, 2.079988e+04, 6.104689e+02, -2.224000e+06, 1.886401e+05, 2.617243e+04, 9.914146e+02, -2.922616e+06, 1.750678e+05, 3.076047e+04, 1.501533e+03, -1.487031e+06, 9.279157e+04, 3.425527e+04, 2.152028e+03, -1.120184e+06, 5.413495e+04, 3.618144e+04, 2.925201e+03, -9.574249e+05, 2.560661e+04, 3.684905e+04, 3.805894e+03, -4.688823e+05, -8.953231e+03, 3.622075e+04, 4.771127e+03, -2.008025e+05, -2.566219e+04, 3.456168e+04, 5.787472e+03, -2.845628e+05, -2.408577e+04, 3.238769e+04, 6.829708e+03, -9.819349e+04, -3.380507e+04, 2.980207e+04, 7.880871e+03, -2.605063e+04, -3.403133e+04, 2.695787e+04, 8.913987e+03, -6.318205e+04, -2.810438e+04, 2.417620e+04, 9.914760e+03, -4.302365e+04, -2.624841e+04, 2.148046e+04, 1.087609e+04, 6.156530e+04, -2.811597e+04, 1.885622e+04, 1.178578e+04, -7.492135e+04, -1.496397e+04, 1.657837e+04, 1.263475e+04, 1.109430e+04, -1.929611e+04, 1.445066e+04, 1.343597e+04, 2.424357e+04, -1.637395e+04, 1.244181e+04, 1.416959e+04, -4.234273e+04, -8.757096e+03, 1.078613e+04, 1.484129e+04, 2.003718e+04, -1.262376e+04, 9.226693e+03, 1.546219e+04, -1.526070e+04, -7.207988e+03, 7.836505e+03, 1.601547e+04, -1.628001e+03, -7.394836e+03, 6.625916e+03, 1.651619e+04, -7.377006e+03, -5.561068e+03, 5.524485e+03, 1.695833e+04, -6.725890e+03, -4.724347e+03, 4.541853e+03, 1.734582e+04, -4.572217e+03, -4.074851e+03, 3.648060e+03, 1.767801e+04, -1.896547e+04, -1.949759e+03, 2.858043e+03, 1.795535e+04, -1.298453e+04, -2.311439e+03, 2.059357e+03, 1.818104e+04, -2.551484e+04, -2.163187e+02, 1.287627e+03, 1.834266e+04, -1.600338e+04, -4.270993e+01, 5.122679e+02, 1.844268e+04, -1.846467e+11, 2.613334e+06, 7.450276e+01, 3.902573e-03, 1.667286e+09, -3.160544e+05, 0, 5.017594e-03, -3.902174e+05, 5.452947e+03, -3.446309e+00, 3.345062e-03, -2.708707e+06, 4.468648e+03, 0, 2.787552e-03, -1.153853e+06, 2.969827e+03, 2.394593e+00, 3.902573e-03, 3.457846e+05, 1.456899e+01, 4.812851e+00, 8.362656e-03, 2.322128e+04, 1.682256e+03, 7.411109e+00, 1.728282e-02, -9.250953e+04, 3.491170e+03, 1.511058e+01, 4.181328e-02, -1.140402e+04, 5.499039e+03, 3.309618e+01, 1.131746e-01, 2.602436e+05, 9.641526e+03, 7.375697e+01, 3.133209e-01, -1.325523e+06, 3.732442e+04, 1.808742e+02, 8.948042e-01, -4.382676e+05, 4.642239e+04, 4.773414e+02, 2.895709e+00, -1.636631e+06, 9.209222e+04, 1.051141e+03, 8.195961e+00, -2.042284e+06, 1.355507e+05, 2.219278e+03, 2.184828e+01, -2.868143e+06, 1.895901e+05, 4.230793e+03, 5.311346e+01, -3.378460e+06, 2.314211e+05, 7.337166e+03, 1.178716e+02, -3.383704e+06, 2.485497e+05, 1.152400e+04, 2.383223e+02, -3.611693e+06, 2.504024e+05, 1.651144e+04, 4.404639e+02, -2.710830e+06, 2.062171e+05, 2.172585e+04, 7.505122e+02, -2.193920e+06, 1.640529e+05, 2.647851e+04, 1.184719e+03, -1.888746e+06, 1.220847e+05, 3.038570e+04, 1.752278e+03, -1.180573e+06, 6.785978e+04, 3.301593e+04, 2.451054e+03, -9.119347e+05, 3.479131e+04, 3.423626e+04, 3.263083e+03, -4.432393e+05, 6.671025e+02, 3.418252e+04, 4.167016e+03, -3.338143e+05, -1.199384e+04, 3.313578e+04, 5.133589e+03, -1.979577e+05, -2.245575e+04, 3.142588e+04, 6.140752e+03, -1.443444e+05, -2.612535e+04, 2.924376e+04, 7.164707e+03, -1.039579e+05, -2.759601e+04, 2.677478e+04, 8.185464e+03, 6.889591e+03, -3.078271e+04, 2.413897e+04, 9.184259e+03, -7.514438e+04, -2.239874e+04, 2.158917e+04, 1.014449e+04, 4.257686e+04, -2.654203e+04, 1.911626e+04, 1.106395e+04, -6.392534e+04, -1.575459e+04, 1.685800e+04, 1.192695e+04, 3.833671e+04, -2.059340e+04, 1.473601e+04, 1.274193e+04, -4.175233e+04, -1.138346e+04, 1.282932e+04, 1.349170e+04, 1.568732e+04, -1.428547e+04, 1.108599e+04, 1.418980e+04, -1.592132e+04, -9.200685e+03, 9.505594e+03, 1.482175e+04, 9.423744e+03, -9.833787e+03, 8.103365e+03, 1.539779e+04, -2.081387e+04, -5.508437e+03, 6.882485e+03, 1.591251e+04, 2.938513e+03, -6.992832e+03, 5.751007e+03, 1.637591e+04, -1.006852e+04, -4.396123e+03, 4.730716e+03, 1.677699e+04, -9.845785e+03, -3.800704e+03, 3.824602e+03, 1.712480e+04, -1.466034e+04, -2.720469e+03, 2.967253e+03, 1.741587e+04, -1.131802e+04, -2.508277e+03, 2.133736e+03, 1.764822e+04, -2.788700e+04, -1.062039e+01, 1.368856e+03, 1.781643e+04, -1.738426e+04, -4.486282e+01, 5.656062e+02, 1.792414e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.297648e+06, 4.111555e+03, 0, 0, 0, 0, 0, 5.575104e-04, -5.581082e+05, 1.781758e+03, 0, 5.575104e-04, 1.843572e+05, -3.770991e+02, 1.469976e+00, 2.787552e-03, -3.952308e+05, 2.931368e+03, 2.469540e+00, 6.132615e-03, 2.621871e+05, -9.011830e+01, 9.486217e+00, 2.843303e-02, -1.562634e+05, 6.783349e+03, 1.981770e+01, 7.637893e-02, -5.987073e+05, 1.920998e+04, 7.296369e+01, 3.010556e-01, -4.734045e+05, 3.233755e+04, 2.337040e+02, 1.231541e+00, -1.292884e+06, 6.785280e+04, 6.097906e+02, 4.193593e+00, -1.682559e+06, 1.071776e+05, 1.453400e+03, 1.287515e+01, -2.404541e+06, 1.584818e+05, 3.025797e+03, 3.469778e+01, -3.146009e+06, 2.066665e+05, 5.619983e+03, 8.326530e+01, -2.709797e+06, 2.201851e+05, 9.299217e+03, 1.789965e+02, -3.778700e+06, 2.492082e+05, 1.388870e+04, 3.460623e+02, -2.343804e+06, 1.957822e+05, 1.893955e+04, 6.135988e+02, -2.283303e+06, 1.718623e+05, 2.366783e+04, 9.972451e+02, -1.924180e+06, 1.288603e+05, 2.777848e+04, 1.511863e+03, -9.241237e+05, 6.747835e+04, 3.065304e+04, 2.156804e+03, -1.086438e+06, 5.116178e+04, 3.229492e+04, 2.915626e+03, -4.632157e+05, 7.870416e+03, 3.273955e+04, 3.776818e+03, -3.230504e+05, -6.985506e+03, 3.205541e+04, 4.707586e+03, -2.475074e+05, -1.596795e+04, 3.068760e+04, 5.686358e+03, -1.378401e+05, -2.375715e+04, 2.877374e+04, 6.690937e+03, -8.940252e+04, -2.589151e+04, 2.650252e+04, 7.698058e+03, -2.683560e+04, -2.716741e+04, 2.406685e+04, 8.689683e+03, -5.526493e+04, -2.270183e+04, 2.164225e+04, 9.650765e+03, -8.489383e+03, -2.300292e+04, 1.926287e+04, 1.057381e+04, -1.388131e+04, -1.936649e+04, 1.699055e+04, 1.144637e+04, 7.094209e+03, -1.780787e+04, 1.489322e+04, 1.226540e+04, -2.836236e+04, -1.264700e+04, 1.301116e+04, 1.302698e+04, 2.092988e+04, -1.443269e+04, 1.125648e+04, 1.373400e+04, -2.156834e+04, -8.504181e+03, 9.717555e+03, 1.437710e+04, -6.708749e+03, -8.789276e+03, 8.334151e+03, 1.496836e+04, -1.692188e+03, -7.736227e+03, 7.027454e+03, 1.549866e+04, -4.473494e+03, -6.083076e+03, 5.875349e+03, 1.596817e+04, -1.208879e+04, -4.407527e+03, 4.863871e+03, 1.638080e+04, -8.618245e+03, -4.133615e+03, 3.916455e+03, 1.673821e+04, -8.899190e+03, -3.323467e+03, 3.029126e+03, 1.703543e+04, -1.897729e+04, -1.633485e+03, 2.225304e+03, 1.727258e+04, -3.279575e+04, 2.298052e+02, 1.423357e+03, 1.745072e+04, -1.484592e+04, -2.882339e+02, 5.261383e+02, 1.756148e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.090528e+04, 4.110663e+02, 0, 0, 2.437332e+04, 1.728558e+02, 1.098978e+00, 2.230042e-03, -5.251004e+04, 1.839037e+03, 3.415254e+00, 1.003519e-02, -1.034817e+05, 5.494798e+03, 1.715950e+01, 6.076864e-02, -3.817933e+05, 1.664499e+04, 6.975643e+01, 3.183384e-01, -5.260784e+05, 3.421596e+04, 2.439328e+02, 1.452872e+00, -1.288699e+06, 7.236937e+04, 6.940201e+02, 5.383321e+00, -1.884821e+06, 1.157847e+05, 1.715049e+03, 1.728115e+01, -2.068708e+06, 1.540029e+05, 3.564861e+03, 4.720887e+01, -2.701302e+06, 1.965799e+05, 6.434261e+03, 1.113315e+02, -2.916540e+06, 2.134724e+05, 1.036392e+04, 2.333911e+02, -2.526077e+06, 1.969947e+05, 1.493163e+04, 4.395490e+02, -1.965767e+06, 1.637507e+05, 1.953147e+04, 7.516110e+02, -1.697977e+06, 1.315705e+05, 2.369155e+04, 1.184152e+03, -1.124648e+06, 8.674265e+04, 2.700457e+04, 1.743860e+03, -9.015866e+05, 5.643048e+04, 2.922375e+04, 2.423722e+03, -7.506628e+05, 3.028053e+04, 3.032450e+04, 3.211428e+03, -1.502096e+05, -6.976241e+03, 3.021703e+04, 4.084801e+03, -4.313262e+05, -4.280012e+02, 2.934955e+04, 5.011680e+03, -8.356901e+04, -2.305404e+04, 2.785722e+04, 5.981843e+03, -6.447470e+04, -2.307799e+04, 2.585185e+04, 6.959204e+03, -6.518919e+04, -2.177705e+04, 2.375067e+04, 7.931175e+03, -6.379765e+04, -2.063416e+04, 2.157590e+04, 8.885643e+03, 3.719946e+02, -2.246051e+04, 1.933079e+04, 9.809115e+03, -2.302765e+04, -1.787789e+04, 1.717219e+04, 1.068719e+04, -8.297077e+03, -1.659973e+04, 1.515538e+04, 1.151822e+04, 7.842093e+02, -1.472122e+04, 1.326753e+04, 1.229522e+04, -1.859957e+04, -1.110603e+04, 1.156662e+04, 1.301583e+04, 4.434424e+03, -1.134157e+04, 9.987902e+03, 1.368140e+04, -2.070461e+04, -7.474109e+03, 8.566013e+03, 1.428543e+04, 1.277143e+04, -9.241875e+03, 7.241224e+03, 1.483337e+04, -1.508531e+04, -4.897739e+03, 6.099617e+03, 1.531603e+04, -1.471159e+04, -4.527480e+03, 5.082794e+03, 1.574803e+04, -3.968351e+03, -4.893573e+03, 4.064790e+03, 1.612095e+04, -1.081038e+04, -3.174699e+03, 3.148908e+03, 1.642812e+04, -2.027976e+04, -1.650839e+03, 2.326102e+03, 1.667577e+04, -2.971391e+04, -2.147712e+02, 1.486818e+03, 1.686212e+04, -1.842872e+04, -5.515463e+01, 5.911260e+02, 1.697771e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.548164e+03, 5.832732e+01, 0, 0, -4.254350e+04, 1.106875e+03, 4.435921e-01, 1.115021e-03, -6.186367e+04, 3.476985e+03, 8.919585e+00, 3.177809e-02, -2.400450e+05, 1.236929e+04, 4.781682e+01, 2.358269e-01, -5.044807e+05, 3.042742e+04, 2.007490e+02, 1.304017e+00, -1.089476e+06, 6.341001e+04, 6.399979e+02, 5.479212e+00, -1.227911e+06, 9.442542e+04, 1.632738e+03, 1.854057e+01, -1.843917e+06, 1.380790e+05, 3.410850e+03, 5.106126e+01, -2.151846e+06, 1.665970e+05, 6.202903e+03, 1.213332e+02, -2.042129e+06, 1.709803e+05, 9.861164e+03, 2.528505e+02, -2.013808e+06, 1.629299e+05, 1.399494e+04, 4.696808e+02, -1.226414e+06, 1.227890e+05, 1.806697e+04, 7.926443e+02, -1.415486e+06, 1.097980e+05, 2.166666e+04, 1.230785e+03, -7.867272e+05, 6.384606e+04, 2.448953e+04, 1.792229e+03, -6.455655e+05, 4.083803e+04, 2.621488e+04, 2.463119e+03, -4.555601e+05, 1.792048e+04, 2.696774e+04, 3.230170e+03, -9.267617e+04, -6.476458e+03, 2.676322e+04, 4.071033e+03, -2.927601e+05, -1.052446e+03, 2.601313e+04, 4.960256e+03, -1.217774e+05, -1.516011e+04, 2.477810e+04, 5.889640e+03, -3.133872e+04, -2.038053e+04, 2.303332e+04, 6.828298e+03, -8.323439e+04, -1.637279e+04, 2.115509e+04, 7.757606e+03, 2.477021e+04, -2.169634e+04, 1.917545e+04, 8.668998e+03, -6.502164e+04, -1.334719e+04, 1.725980e+04, 9.544082e+03, 5.350009e+03, -1.721099e+04, 1.537623e+04, 1.038587e+04, -1.384803e+04, -1.325894e+04, 1.354377e+04, 1.117533e+04, 4.594548e+03, -1.274668e+04, 1.186473e+04, 1.191404e+04, -3.094085e+04, -8.212376e+03, 1.034769e+04, 1.259716e+04, 2.132700e+04, -1.145801e+04, 8.882879e+03, 1.322813e+04, -3.035282e+04, -4.902982e+03, 7.607703e+03, 1.379274e+04, 5.411916e+03, -7.830371e+03, 6.412932e+03, 1.430841e+04, -1.810219e+04, -4.158606e+03, 5.307838e+03, 1.475643e+04, -3.007288e+02, -5.370719e+03, 4.283134e+03, 1.514813e+04, -2.178750e+04, -2.173925e+03, 3.365475e+03, 1.547263e+04, -1.511740e+04, -2.655632e+03, 2.459696e+03, 1.573975e+04, -3.355339e+04, 7.946364e+01, 1.567829e+03, 1.593402e+04, -1.896481e+04, -1.109393e+02, 6.194191e+02, 1.605676e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.491786e+03, 2.774529e+02, 0, 0, -4.543511e+04, 1.887313e+03, 2.744877e+00, 1.059270e-02, -6.058786e+04, 5.419371e+03, 2.435209e+01, 1.321300e-01, -2.888232e+05, 1.859427e+04, 1.103914e+02, 7.927798e-01, -6.056967e+05, 4.106824e+04, 4.123811e+02, 3.821734e+00, -8.632473e+05, 6.819488e+04, 1.152532e+03, 1.412787e+01, -1.223397e+06, 9.931776e+04, 2.559702e+03, 4.147376e+01, -1.340520e+06, 1.187963e+05, 4.785345e+03, 1.020841e+02, -1.331923e+06, 1.258200e+05, 7.731127e+03, 2.165939e+02, -1.384212e+06, 1.233902e+05, 1.113473e+04, 4.071911e+02, -6.897551e+05, 8.991942e+04, 1.453688e+04, 6.933099e+02, -1.214735e+06, 9.534407e+04, 1.765376e+04, 1.082844e+03, -4.097940e+05, 4.438210e+04, 2.014827e+04, 1.588657e+03, -3.878253e+05, 3.305638e+04, 2.168065e+04, 2.190812e+03, -4.045554e+05, 2.233340e+04, 2.261177e+04, 2.884151e+03, -1.793317e+05, 1.946184e+03, 2.274125e+04, 3.654479e+03, -6.062687e+04, -7.801344e+03, 2.217293e+04, 4.474418e+03, -1.596910e+05, -4.718906e+03, 2.128443e+04, 5.326097e+03, -4.954925e+04, -1.385354e+04, 2.004253e+04, 6.200059e+03, -1.408864e+04, -1.539126e+04, 1.849437e+04, 7.069552e+03, -3.886102e+04, -1.263844e+04, 1.691557e+04, 7.922135e+03, -2.899779e+04, -1.274985e+04, 1.531142e+04, 8.751657e+03, 3.490567e+03, -1.374791e+04, 1.365887e+04, 9.545296e+03, -1.297414e+04, -1.056211e+04, 1.209829e+04, 1.029242e+04, -9.319178e+03, -9.642875e+03, 1.065048e+04, 1.099410e+04, -9.836923e+03, -8.388618e+03, 9.274745e+03, 1.164472e+04, -1.192357e+04, -7.167599e+03, 7.978709e+03, 1.224070e+04, 1.301938e+03, -7.300621e+03, 6.746966e+03, 1.277847e+04, -2.409152e+04, -3.801826e+03, 5.650636e+03, 1.325335e+04, 2.135069e+03, -6.018935e+03, 4.566522e+03, 1.367190e+04, -2.471835e+04, -2.111991e+03, 3.591472e+03, 1.401725e+04, -1.336144e+04, -3.118779e+03, 2.626973e+03, 1.430292e+04, -3.618346e+04, 1.887078e+02, 1.694546e+03, 1.451020e+04, -2.192421e+04, -1.048766e+01, 6.919574e+02, 1.464393e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.298658e+02, 1.891811e+01, 0, 0, -1.240277e+04, 5.345032e+02, 2.608164e-01, 1.115021e-03, -1.596284e+04, 1.741852e+03, 7.032467e+00, 4.069826e-02, -1.027246e+05, 7.361202e+03, 3.925922e+01, 3.027282e-01, -2.060335e+05, 1.759016e+04, 1.746335e+02, 1.730512e+00, -4.143519e+05, 3.512883e+04, 5.474948e+02, 7.103240e+00, -5.194204e+05, 5.235380e+04, 1.348534e+03, 2.294490e+01, -7.226607e+05, 7.188365e+04, 2.713832e+03, 6.034437e+01, -8.224504e+05, 8.236982e+04, 4.702827e+03, 1.360303e+02, -5.759747e+05, 7.532407e+04, 7.117950e+03, 2.687273e+02, -7.814308e+05, 7.950876e+04, 9.732035e+03, 4.740952e+02, -4.677243e+05, 5.706459e+04, 1.228851e+04, 7.694051e+02, -3.405356e+05, 4.326742e+04, 1.440361e+04, 1.156059e+03, -3.661262e+05, 3.527188e+04, 1.610547e+04, 1.634736e+03, -2.050564e+05, 1.800520e+04, 1.723562e+04, 2.202346e+03, -1.739701e+05, 9.803099e+03, 1.773202e+04, 2.842272e+03, -4.267503e+04, -1.775289e+03, 1.770045e+04, 3.540405e+03, -1.174590e+05, 2.979865e+02, 1.732537e+04, 4.277679e+03, -6.005372e+04, -6.416114e+03, 1.663838e+04, 5.047353e+03, -1.009872e+04, -1.033768e+04, 1.560400e+04, 5.826299e+03, -4.043125e+04, -7.878538e+03, 1.446322e+04, 6.598461e+03, -2.113247e+04, -9.484497e+03, 1.324051e+04, 7.358438e+03, 2.589035e+03, -1.043233e+04, 1.192600e+04, 8.090833e+03, -2.651877e+04, -6.981116e+03, 1.067108e+04, 8.786026e+03, -6.138087e+03, -8.355998e+03, 9.423123e+03, 9.444529e+03, -1.199978e+04, -6.803323e+03, 8.184259e+03, 1.005210e+04, -5.136721e+03, -6.606467e+03, 7.004292e+03, 1.060672e+04, -8.765806e+03, -5.278347e+03, 5.900880e+03, 1.110251e+04, -2.318204e+04, -3.325419e+03, 4.877837e+03, 1.153968e+04, -6.973830e+03, -4.679254e+03, 3.813233e+03, 1.191537e+04, -2.198839e+04, -2.109273e+03, 2.813720e+03, 1.221296e+04, -4.232767e+04, 4.552064e+02, 1.844062e+03, 1.243947e+04, -2.133196e+04, -2.242884e+02, 7.171137e+02, 1.258462e+04, }; static float solarDataset480[] = { -2.547404e+13, 3.635631e+08, 1.293910e+04, 3.796038e+01, 1.491564e+11, -3.082064e+07, 2.764923e+03, 3.816097e+01, -4.508309e+10, 2.784696e+07, 1.842137e+03, 3.830790e+01, 1.877320e+09, -2.075191e+06, 5.574952e+03, 4.031446e+01, 1.363759e+08, 1.060735e+05, 5.218855e+03, 4.351307e+01, -4.042173e+07, 4.168932e+05, 5.894289e+03, 4.927657e+01, -1.979427e+07, 3.130223e+05, 6.903811e+03, 5.939239e+01, 6.227794e+07, 3.355382e+04, 7.989751e+03, 7.579875e+01, -2.611063e+07, 5.428849e+05, 9.770848e+03, 1.008989e+02, 6.751575e+06, 3.486580e+05, 1.273626e+04, 1.436773e+02, -7.094370e+06, 5.158292e+05, 1.643574e+04, 2.114709e+02, -9.375221e+06, 5.686982e+05, 2.162922e+04, 3.207238e+02, -9.044998e+06, 5.787047e+05, 2.809570e+04, 4.923702e+02, -1.059918e+07, 5.884594e+05, 3.567928e+04, 7.525556e+02, -1.032559e+07, 5.383256e+05, 4.394951e+04, 1.132412e+03, -9.508141e+06, 4.496710e+05, 5.199543e+04, 1.660855e+03, -6.314974e+06, 3.051184e+05, 5.876680e+04, 2.358284e+03, -6.086400e+06, 2.212357e+05, 6.360343e+04, 3.228792e+03, -3.788528e+06, 9.381155e+04, 6.603062e+04, 4.267693e+03, -2.077730e+06, 4.085149e+03, 6.579013e+04, 5.445031e+03, -1.998244e+06, -2.581562e+04, 6.353956e+04, 6.724786e+03, -5.455764e+05, -8.455452e+04, 5.958479e+04, 8.073218e+03, -5.401502e+05, -8.066396e+04, 5.460598e+04, 9.442031e+03, -4.626920e+05, -7.878633e+04, 4.927072e+04, 1.080685e+04, 4.307696e+04, -8.866941e+04, 4.363750e+04, 1.213911e+04, -9.896498e+04, -6.809587e+04, 3.825652e+04, 1.340968e+04, -4.046726e+04, -6.013412e+04, 3.334045e+04, 1.461550e+04, 2.465424e+04, -5.267288e+04, 2.881215e+04, 1.574516e+04, -6.606890e+04, -3.886479e+04, 2.480495e+04, 1.679298e+04, 8.625368e+04, -3.988716e+04, 2.118987e+04, 1.776151e+04, -5.094497e+04, -2.400663e+04, 1.812357e+04, 1.864229e+04, 3.521782e+04, -2.523723e+04, 1.545985e+04, 1.945299e+04, -2.910575e+04, -1.612809e+04, 1.314789e+04, 2.018464e+04, 2.987436e+04, -1.729633e+04, 1.112528e+04, 2.084999e+04, -2.392041e+04, -9.871844e+03, 9.419435e+03, 2.144328e+04, 1.318656e+04, -1.113363e+04, 7.932171e+03, 2.198012e+04, -8.189886e+03, -7.083342e+03, 6.648923e+03, 2.245346e+04, 8.760018e+02, -6.634529e+03, 5.556208e+03, 2.287527e+04, -7.219063e+03, -4.650361e+03, 4.605098e+03, 2.324459e+04, -7.443951e+03, -3.898973e+03, 3.764874e+03, 2.356703e+04, -5.229746e+03, -3.417661e+03, 2.990255e+03, 2.384152e+04, -9.160621e+03, -2.339852e+03, 2.297538e+03, 2.406739e+04, -1.337575e+04, -1.443204e+03, 1.662712e+03, 2.424699e+04, -1.609842e+04, -6.573803e+02, 1.042947e+03, 2.437881e+04, -1.154888e+04, -2.049765e+02, 4.517902e+02, 2.445949e+04, 4.227183e+11, 1.389648e+06, 1.036346e+03, 1.739462e+01, -4.523986e+10, 1.309428e+07, 1.461077e+03, 1.741507e+01, -1.974469e+09, 2.075506e+06, 2.645040e+03, 1.770254e+01, -1.554063e+09, 1.591460e+06, 3.369179e+03, 1.872211e+01, 5.672809e+08, -8.382778e+05, 3.502720e+03, 2.111515e+01, -1.132935e+08, 5.257210e+05, 3.621481e+03, 2.453096e+01, 5.367205e+07, 3.863978e+04, 4.434495e+03, 3.106808e+01, -7.651470e+05, 2.973158e+05, 5.375363e+03, 4.152440e+01, -5.641271e+06, 3.520079e+05, 7.088158e+03, 5.968817e+01, -3.575740e+05, 3.595429e+05, 9.484804e+03, 9.083227e+01, -5.432283e+06, 4.570748e+05, 1.282057e+04, 1.429497e+02, -8.493195e+06, 5.345880e+05, 1.750590e+04, 2.299714e+02, -9.361727e+06, 5.742448e+05, 2.362945e+04, 3.720855e+02, -1.230376e+07, 6.089220e+05, 3.107881e+04, 5.957043e+02, -8.209413e+06, 5.098829e+05, 3.928027e+04, 9.325726e+02, -9.315159e+06, 4.745999e+05, 4.745855e+04, 1.409587e+03, -8.627264e+06, 3.733993e+05, 5.493900e+04, 2.054851e+03, -4.714765e+06, 2.032292e+05, 6.032301e+04, 2.878534e+03, -3.679437e+06, 1.165562e+05, 6.321237e+04, 3.866403e+03, -2.929350e+06, 4.492419e+04, 6.387975e+04, 5.001581e+03, -1.392612e+06, -3.265661e+04, 6.224732e+04, 6.253081e+03, -1.117804e+06, -5.501965e+04, 5.885362e+04, 7.576411e+03, -4.075604e+05, -8.239287e+04, 5.430578e+04, 8.936806e+03, -2.459750e+05, -8.099482e+04, 4.915270e+04, 1.029496e+04, -3.665911e+05, -6.851276e+04, 4.392374e+04, 1.162710e+04, 2.205685e+05, -8.274490e+04, 3.860977e+04, 1.291372e+04, -3.040342e+05, -4.570146e+04, 3.379260e+04, 1.412701e+04, 1.469667e+05, -6.087770e+04, 2.926964e+04, 1.527950e+04, -6.797871e+04, -3.790137e+04, 2.518196e+04, 1.633998e+04, 3.949307e+04, -3.733814e+04, 2.163770e+04, 1.732591e+04, -7.975621e+03, -2.732830e+04, 1.851668e+04, 1.822774e+04, -4.377782e+03, -2.272640e+04, 1.583173e+04, 1.905445e+04, 1.693589e+04, -1.978767e+04, 1.346464e+04, 1.980645e+04, -1.488896e+04, -1.382418e+04, 1.145439e+04, 2.048569e+04, -5.303294e+03, -1.226164e+04, 9.699219e+03, 2.110102e+04, 2.706972e+04, -1.214607e+04, 8.129372e+03, 2.165037e+04, -3.562524e+04, -4.676288e+03, 6.891074e+03, 2.213611e+04, 2.093737e+04, -9.026232e+03, 5.739331e+03, 2.257705e+04, -2.006414e+04, -3.337389e+03, 4.758662e+03, 2.295476e+04, -1.964465e+03, -4.781112e+03, 3.893292e+03, 2.329090e+04, -7.979526e+03, -3.208613e+03, 3.083342e+03, 2.357289e+04, -3.882281e+03, -2.975486e+03, 2.366732e+03, 2.380648e+04, -1.970221e+04, -7.385175e+02, 1.744297e+03, 2.399093e+04, -2.049545e+04, -4.245408e+02, 1.090574e+03, 2.413137e+04, -1.271643e+04, -9.063678e+01, 4.186658e+02, 2.421482e+04, -3.562425e+12, 4.547613e+07, 3.869422e+03, 4.918330e+00, 4.689183e+10, -1.281786e+07, 2.261597e+03, 4.980296e+00, 2.022864e+09, -1.220456e+06, 1.216501e+03, 5.148946e+00, 2.776720e+08, -1.053418e+05, 1.068025e+03, 5.487525e+00, -1.590271e+08, 4.112991e+05, 1.272512e+03, 6.197900e+00, 6.495931e+07, -3.603970e+04, 1.609987e+03, 7.805828e+00, -2.064038e+07, 2.320516e+05, 1.976444e+03, 1.049337e+01, 1.765744e+07, 1.028749e+05, 2.695696e+03, 1.571579e+01, -1.181768e+07, 3.056096e+05, 3.744644e+03, 2.487848e+01, 3.197837e+06, 2.544026e+05, 5.534911e+03, 4.254333e+01, -9.201137e+06, 4.284098e+05, 8.121123e+03, 7.427706e+01, -8.890947e+06, 4.785445e+05, 1.211126e+04, 1.328518e+02, -7.071586e+06, 5.059339e+05, 1.741186e+04, 2.352960e+02, -1.166674e+07, 5.930738e+05, 2.420576e+04, 4.053939e+02, -1.014664e+07, 5.469944e+05, 3.227826e+04, 6.765805e+02, -8.709155e+06, 4.717684e+05, 4.057628e+04, 1.079331e+03, -6.589641e+06, 3.640900e+05, 4.826717e+04, 1.639785e+03, -5.956205e+06, 2.764700e+05, 5.460139e+04, 2.373352e+03, -4.410054e+06, 1.636818e+05, 5.887661e+04, 3.284026e+03, -2.573675e+06, 5.767791e+04, 6.052561e+04, 4.353163e+03, -1.725557e+06, -2.089540e+03, 5.980763e+04, 5.546333e+03, -7.726710e+05, -4.982537e+04, 5.727085e+04, 6.827655e+03, -9.367723e+05, -5.118449e+04, 5.356326e+04, 8.157893e+03, -2.139498e+05, -7.920098e+04, 4.895601e+04, 9.508497e+03, -1.552485e+05, -7.235301e+04, 4.390792e+04, 1.083723e+04, -1.628579e+04, -6.809604e+04, 3.896658e+04, 1.212598e+04, -1.983318e+05, -5.059195e+04, 3.433105e+04, 1.335883e+04, 8.171771e+04, -5.652750e+04, 2.987115e+04, 1.452950e+04, -1.382147e+04, -4.085430e+04, 2.582431e+04, 1.561625e+04, -1.903892e+04, -3.373542e+04, 2.231868e+04, 1.662797e+04, 1.630797e+04, -2.980642e+04, 1.916625e+04, 1.756241e+04, -1.470429e+04, -2.241600e+04, 1.641147e+04, 1.841734e+04, 1.183830e+04, -2.013913e+04, 1.399466e+04, 1.919851e+04, -7.425767e+03, -1.497561e+04, 1.190037e+04, 1.990483e+04, 2.348122e+04, -1.430663e+04, 1.008697e+04, 2.054362e+04, -3.407580e+04, -7.210622e+03, 8.592568e+03, 2.111580e+04, 8.410728e+03, -9.841158e+03, 7.218391e+03, 2.163577e+04, 5.333101e+03, -7.356348e+03, 5.982069e+03, 2.208915e+04, -1.934314e+04, -3.841909e+03, 4.996690e+03, 2.248734e+04, 3.189408e+03, -5.483261e+03, 4.066681e+03, 2.283908e+04, -1.021377e+04, -2.980445e+03, 3.244087e+03, 2.313320e+04, -9.790041e+03, -2.583961e+03, 2.517956e+03, 2.338071e+04, -1.444370e+04, -1.591158e+03, 1.824665e+03, 2.357756e+04, -2.379887e+04, -1.133726e+02, 1.149303e+03, 2.372235e+04, -1.332327e+04, -1.181356e+02, 4.433913e+02, 2.381143e+04, -4.062495e+12, 5.889514e+07, 1.822539e+03, 5.934704e-01, 1.116655e+10, -2.476749e+06, 2.315678e+02, 6.215788e-01, -2.883849e+08, 3.186874e+05, 1.216092e+02, 6.330776e-01, -3.334973e+08, 3.506258e+05, 2.375575e+02, 6.969603e-01, 9.502123e+07, -1.388013e+05, 2.778272e+02, 9.045791e-01, -3.169474e+07, 1.355526e+05, 3.011117e+02, 1.153722e+00, 1.354177e+07, 8.549983e+03, 4.924110e+02, 1.837267e+00, -9.788296e+06, 1.268912e+05, 7.245476e+02, 3.098311e+00, 8.321999e+06, 5.975755e+04, 1.214653e+03, 6.043943e+00, -9.981085e+06, 2.455768e+05, 2.011040e+03, 1.185919e+01, -2.885803e+06, 2.397529e+05, 3.652004e+03, 2.559525e+01, -6.329634e+06, 3.478969e+05, 6.106085e+03, 5.370172e+01, -7.960277e+06, 4.345711e+05, 9.978396e+03, 1.097524e+02, -7.895936e+06, 4.855802e+05, 1.544416e+04, 2.146203e+02, -1.056970e+07, 5.455151e+05, 2.249529e+04, 3.967972e+02, -8.772676e+06, 4.836844e+05, 3.061098e+04, 6.924183e+02, -6.125317e+06, 3.824122e+05, 3.856863e+04, 1.130737e+03, -6.234374e+06, 3.223025e+05, 4.569520e+04, 1.732649e+03, -4.135207e+06, 1.989626e+05, 5.121311e+04, 2.512630e+03, -2.831010e+06, 1.064359e+05, 5.436969e+04, 3.458681e+03, -1.771421e+06, 3.391272e+04, 5.527105e+04, 4.547677e+03, -1.352058e+06, -6.747689e+03, 5.423442e+04, 5.746928e+03, -4.737948e+05, -5.056302e+04, 5.159311e+04, 7.021275e+03, -5.178401e+05, -5.085618e+04, 4.797068e+04, 8.329029e+03, -3.165613e+05, -5.894560e+04, 4.379803e+04, 9.645661e+03, -3.525713e+04, -6.498724e+04, 3.922274e+04, 1.093910e+04, -1.698033e+03, -5.646027e+04, 3.473194e+04, 1.218335e+04, -8.252137e+04, -4.418587e+04, 3.062394e+04, 1.337026e+04, -4.452976e+04, -4.012949e+04, 2.678876e+04, 1.449551e+04, 1.756583e+04, -3.688401e+04, 2.318145e+04, 1.554675e+04, 2.497374e+04, -3.028839e+04, 1.996805e+04, 1.651698e+04, -4.542787e+04, -2.074654e+04, 1.722708e+04, 1.741034e+04, 4.577114e+04, -2.317554e+04, 1.473888e+04, 1.823360e+04, -2.941513e+04, -1.335336e+04, 1.261663e+04, 1.897704e+04, 9.540414e+03, -1.422160e+04, 1.076932e+04, 1.965858e+04, -1.333019e+04, -9.795617e+03, 9.126910e+03, 2.026983e+04, 6.872783e+03, -9.753800e+03, 7.680151e+03, 2.081939e+04, -6.794840e+03, -6.642494e+03, 6.433964e+03, 2.130449e+04, -6.512347e+03, -5.595285e+03, 5.359979e+03, 2.173466e+04, -7.453009e+03, -4.569078e+03, 4.387344e+03, 2.210973e+04, -8.453112e+03, -3.685525e+03, 3.504406e+03, 2.243008e+04, -1.058157e+04, -2.798516e+03, 2.696662e+03, 2.269567e+04, -1.175275e+04, -2.070349e+03, 1.946314e+03, 2.290618e+04, -2.725053e+04, 1.473825e+02, 1.251869e+03, 2.306034e+04, -1.529872e+04, -8.045642e+01, 4.978280e+02, 2.315872e+04, 0, 0, 0, 3.002487e-02, -1.090846e+10, 1.974400e+06, 0, 3.002487e-02, 3.636683e+07, -1.786622e+04, 0, 3.960728e-02, -7.026847e+07, 9.507055e+04, 0, 3.896845e-02, 1.333478e+06, 3.529875e+03, 3.551876e+01, 5.941092e-02, 2.003892e+06, 3.786981e+03, 4.736528e+01, 1.022123e-01, -1.002646e+05, 1.491867e+04, 7.403866e+01, 1.935646e-01, 8.840045e+05, 2.053897e+04, 1.379171e+02, 4.260977e-01, -1.799941e+06, 5.585624e+04, 2.800918e+02, 1.024040e+00, -1.272606e+06, 8.353843e+04, 6.224092e+02, 2.759094e+00, -3.142945e+06, 1.498386e+05, 1.319586e+03, 7.359927e+00, -5.325514e+06, 2.353986e+05, 2.722502e+03, 1.918334e+01, -4.367873e+06, 2.950794e+05, 5.196144e+03, 4.713202e+01, -8.293792e+06, 4.208244e+05, 9.110856e+03, 1.061188e+02, -8.395418e+06, 4.579295e+05, 1.483469e+04, 2.224875e+02, -6.520037e+06, 4.312038e+05, 2.181675e+04, 4.272194e+02, -7.601962e+06, 4.292473e+05, 2.951377e+04, 7.524578e+02, -5.359980e+06, 3.235804e+05, 3.708090e+04, 1.232011e+03, -4.257096e+06, 2.366275e+05, 4.329759e+04, 1.879326e+03, -2.362298e+06, 1.320983e+05, 4.767316e+04, 2.696374e+03, -2.586387e+06, 9.404854e+04, 5.012795e+04, 3.667154e+03, -1.346937e+06, 1.521702e+04, 5.055045e+04, 4.774654e+03, -6.311932e+05, -2.761653e+04, 4.896823e+04, 5.973547e+03, -2.859925e+05, -4.535140e+04, 4.622372e+04, 7.225477e+03, -5.833449e+05, -3.576030e+04, 4.293299e+04, 8.502104e+03, 5.723729e+03, -6.133686e+04, 3.902591e+04, 9.783052e+03, -8.123325e+04, -4.879934e+04, 3.491969e+04, 1.102637e+04, -5.068165e+04, -4.411026e+04, 3.105343e+04, 1.222640e+04, -3.207428e+04, -3.889547e+04, 2.737029e+04, 1.337046e+04, -1.066219e+04, -3.412928e+04, 2.393260e+04, 1.444923e+04, -1.141680e+04, -2.854544e+04, 2.079563e+04, 1.545628e+04, -4.908479e+03, -2.421760e+04, 1.796966e+04, 1.638943e+04, 2.053346e+04, -2.145813e+04, 1.544534e+04, 1.724714e+04, -3.179755e+04, -1.406796e+04, 1.328479e+04, 1.803018e+04, 3.081852e+04, -1.632250e+04, 1.133044e+04, 1.874762e+04, -2.520860e+04, -8.744463e+03, 9.671271e+03, 1.939042e+04, -5.258707e+02, -9.682975e+03, 8.210156e+03, 1.997663e+04, -3.603629e+03, -7.596047e+03, 6.868361e+03, 2.049617e+04, -1.284514e+04, -5.501197e+03, 5.706315e+03, 2.095412e+04, 5.408753e+03, -6.215871e+03, 4.636466e+03, 2.135343e+04, -1.729670e+04, -2.725560e+03, 3.738994e+03, 2.168992e+04, -8.133455e+03, -3.384342e+03, 2.903206e+03, 2.197692e+04, -1.400569e+04, -2.007834e+03, 2.106764e+03, 2.220291e+04, -3.787921e+04, 9.695897e+02, 1.365023e+03, 2.237077e+04, -1.169926e+04, -4.806728e+02, 4.665493e+02, 2.247814e+04, 6.525532e+11, -9.597776e+06, -2.508142e+02, 5.110617e-03, -7.272307e+08, 1.316266e+05, 0, 1.277654e-03, 7.273367e+07, -3.573244e+04, 0, 1.916481e-03, -9.307074e+05, 2.164022e+03, 0, 6.388271e-04, -3.846153e+06, 8.276968e+03, 1.624622e+00, 1.277654e-03, 7.045428e+05, -9.506031e+02, 6.273509e+00, 7.665925e-03, 5.471221e+05, 7.881141e+02, 8.492069e+00, 1.788716e-02, -1.157790e+06, 1.343443e+04, 1.980918e+01, 4.599555e-02, 5.648178e+05, 1.177962e+04, 6.860591e+01, 1.890928e-01, -2.168944e+06, 5.449721e+04, 1.804408e+02, 6.401047e-01, -1.936415e+06, 8.671467e+04, 5.476078e+02, 2.451180e+00, -2.778014e+06, 1.502939e+05, 1.348026e+03, 8.039000e+00, -5.988957e+06, 2.595586e+05, 3.014769e+03, 2.341237e+01, -4.953844e+06, 3.123771e+05, 6.037281e+03, 6.158549e+01, -8.072078e+06, 4.188727e+05, 1.060684e+04, 1.421314e+02, -6.102258e+06, 4.036899e+05, 1.685401e+04, 2.966719e+02, -7.081157e+06, 4.155400e+05, 2.406072e+04, 5.567832e+02, -5.275326e+06, 3.322858e+05, 3.155165e+04, 9.582758e+02, -3.846919e+06, 2.463955e+05, 3.810789e+04, 1.520520e+03, -3.514763e+06, 1.822427e+05, 4.321496e+04, 2.251031e+03, -1.456565e+06, 7.443224e+04, 4.630479e+04, 3.144755e+03, -1.859068e+06, 5.498326e+04, 4.747600e+04, 4.171486e+03, -4.928980e+05, -1.792985e+04, 4.691705e+04, 5.312605e+03, -8.773971e+05, -1.418775e+04, 4.496428e+04, 6.519951e+03, -2.751454e+04, -5.502387e+04, 4.200632e+04, 7.772248e+03, -1.594475e+05, -4.385961e+04, 3.851029e+04, 9.022491e+03, -2.928118e+05, -3.624179e+04, 3.501918e+04, 1.026196e+04, 9.244874e+04, -5.182584e+04, 3.122779e+04, 1.147202e+04, -7.298447e+04, -3.463156e+04, 2.759798e+04, 1.261967e+04, -2.297138e+04, -3.303978e+04, 2.430195e+04, 1.371250e+04, -7.257520e+03, -2.883089e+04, 2.118824e+04, 1.473725e+04, 1.617806e+04, -2.529034e+04, 1.836369e+04, 1.568909e+04, -1.048687e+04, -1.906491e+04, 1.589586e+04, 1.656705e+04, -2.280875e+03, -1.656326e+04, 1.371907e+04, 1.737679e+04, -1.173034e+04, -1.313659e+04, 1.177337e+04, 1.811680e+04, 1.764221e+03, -1.200134e+04, 1.002274e+04, 1.878901e+04, -5.443919e+03, -9.216609e+03, 8.480824e+03, 1.939176e+04, -2.042247e+03, -7.901444e+03, 7.133254e+03, 1.993055e+04, -8.037811e+03, -5.968600e+03, 5.951562e+03, 2.040675e+04, -1.379071e+04, -4.556409e+03, 4.894801e+03, 2.082428e+04, -5.451456e+02, -5.063627e+03, 3.890115e+03, 2.118233e+04, -2.023326e+04, -2.060668e+03, 3.019280e+03, 2.147555e+04, -2.864907e+03, -3.469182e+03, 2.170665e+03, 2.171383e+04, -4.564474e+04, 1.914149e+03, 1.447545e+03, 2.188399e+04, -1.285998e+04, -5.186207e+02, 5.108418e+02, 2.200120e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.075985e+04, 4.214961e+02, 0, 0, 5.562181e+04, 8.061994e+01, 8.281078e-01, 1.277654e-03, -3.121437e+05, 4.825055e+03, 2.713965e+00, 5.749444e-03, -1.563799e+05, 9.395735e+03, 2.570856e+01, 6.707684e-02, -7.453272e+05, 3.122976e+04, 1.032542e+02, 3.762692e-01, -1.989081e+06, 7.880134e+04, 3.868377e+02, 1.843655e+00, -3.098191e+06, 1.440545e+05, 1.185918e+03, 7.543909e+00, -4.215556e+06, 2.225784e+05, 2.907656e+03, 2.490978e+01, -4.786020e+06, 2.938944e+05, 5.980692e+03, 6.858128e+01, -6.298563e+06, 3.655079e+05, 1.067540e+04, 1.622455e+02, -5.412413e+06, 3.568233e+05, 1.684205e+04, 3.392913e+02, -4.918343e+06, 3.291889e+05, 2.367207e+04, 6.321366e+02, -3.916896e+06, 2.666399e+05, 3.039895e+04, 1.070198e+03, -3.234356e+06, 2.003322e+05, 3.615701e+04, 1.670192e+03, -2.040334e+06, 1.180905e+05, 4.028384e+04, 2.434229e+03, -1.401604e+06, 6.196017e+04, 4.252555e+04, 3.344716e+03, -8.510153e+05, 1.754662e+04, 4.308474e+04, 4.377716e+03, -5.868429e+05, -7.897552e+03, 4.225322e+04, 5.502610e+03, -4.777308e+05, -2.215277e+04, 4.036574e+04, 6.689373e+03, -2.027395e+05, -3.838610e+04, 3.760893e+04, 7.906894e+03, 4.688571e+04, -4.650040e+04, 3.433909e+04, 9.120592e+03, -1.731682e+05, -3.045624e+04, 3.114684e+04, 1.030870e+04, -9.393385e+04, -3.336297e+04, 2.796966e+04, 1.146998e+04, 5.520659e+04, -3.698224e+04, 2.466929e+04, 1.257910e+04, -3.127735e+04, -2.548739e+04, 2.167580e+04, 1.361953e+04, -2.886510e+04, -2.234154e+04, 1.900618e+04, 1.459990e+04, 4.803892e+04, -2.356220e+04, 1.648513e+04, 1.551250e+04, -6.916297e+04, -1.140155e+04, 1.434094e+04, 1.635055e+04, 2.995112e+04, -1.761090e+04, 1.231851e+04, 1.713096e+04, -1.131187e+04, -1.076782e+04, 1.049085e+04, 1.782950e+04, -5.672132e+03, -9.605872e+03, 8.943086e+03, 1.846438e+04, -2.342928e+02, -8.391650e+03, 7.538626e+03, 1.903310e+04, -1.356312e+04, -5.763390e+03, 6.314320e+03, 1.953688e+04, -1.029218e+04, -5.313462e+03, 5.191616e+03, 1.998094e+04, -4.820491e+03, -4.883491e+03, 4.133093e+03, 2.035985e+04, -1.332017e+04, -3.043612e+03, 3.200526e+03, 2.067237e+04, -1.507804e+04, -2.298738e+03, 2.341341e+03, 2.092387e+04, -3.372668e+04, 2.668844e+02, 1.517180e+03, 2.111023e+04, -1.829462e+04, -1.213923e+02, 6.004736e+02, 2.122965e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.017242e+04, 1.750194e+02, 0, 0, -1.457144e+04, 7.281291e+02, 8.823561e-01, 1.916481e-03, -8.138557e+04, 3.915626e+03, 6.731239e+00, 2.044247e-02, -3.416115e+05, 1.616098e+04, 4.346558e+01, 1.712057e-01, -1.112109e+06, 4.948532e+04, 2.166628e+02, 1.116031e+00, -1.851122e+06, 9.973810e+04, 7.987332e+02, 5.514355e+00, -2.976474e+06, 1.703720e+05, 2.185875e+03, 2.036134e+01, -3.752852e+06, 2.346189e+05, 4.835726e+03, 6.046371e+01, -3.916406e+06, 2.725329e+05, 8.928559e+03, 1.496005e+02, -4.124056e+06, 2.880126e+05, 1.427455e+04, 3.184585e+02, -3.454381e+06, 2.560391e+05, 2.029483e+04, 6.004725e+02, -2.730599e+06, 2.065880e+05, 2.611242e+04, 1.020835e+03, -2.156132e+06, 1.532252e+05, 3.106996e+04, 1.593564e+03, -1.423653e+06, 9.444510e+04, 3.467497e+04, 2.319182e+03, -1.066952e+06, 5.365130e+04, 3.674970e+04, 3.182752e+03, -5.913676e+05, 1.479975e+04, 3.736478e+04, 4.162645e+03, -4.507312e+05, -3.442068e+03, 3.676283e+04, 5.228191e+03, -3.349898e+05, -1.694648e+04, 3.524585e+04, 6.352700e+03, -5.373997e+04, -3.272371e+04, 3.296933e+04, 7.506143e+03, -1.042929e+05, -2.794349e+04, 3.037961e+04, 8.657850e+03, -1.338463e+05, -2.558203e+04, 2.771508e+04, 9.797088e+03, 4.568200e+04, -3.329463e+04, 2.485715e+04, 1.090629e+04, -6.786858e+04, -2.165789e+04, 2.213772e+04, 1.196178e+04, 1.306047e+04, -2.435543e+04, 1.958249e+04, 1.296915e+04, -3.322576e+04, -1.756840e+04, 1.718597e+04, 1.391169e+04, 2.749390e+04, -1.920271e+04, 1.496912e+04, 1.479267e+04, -3.110219e+04, -1.154084e+04, 1.301793e+04, 1.560216e+04, -6.075291e+03, -1.225057e+04, 1.124355e+04, 1.635251e+04, 6.180475e+02, -1.069972e+04, 9.569241e+03, 1.703160e+04, -6.748771e+03, -8.170462e+03, 8.103632e+03, 1.764032e+04, -1.585713e+04, -6.165047e+03, 6.808130e+03, 1.818386e+04, -6.803412e+01, -6.704295e+03, 5.583407e+03, 1.866238e+04, -1.271216e+04, -4.147672e+03, 4.500136e+03, 1.906922e+04, -1.789297e+04, -3.078470e+03, 3.522047e+03, 1.941335e+04, -1.300839e+04, -2.995513e+03, 2.547822e+03, 1.968999e+04, -3.739496e+04, 4.124892e+02, 1.647666e+03, 1.989124e+04, -1.991360e+04, -1.343689e+02, 6.540701e+02, 2.002139e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.836497e+03, 1.200044e+02, 0, 0, -6.317725e+03, 7.299639e+02, 9.947280e-01, 3.194135e-03, -1.879736e+05, 7.112439e+03, 1.009800e+01, 4.216259e-02, -2.264187e+05, 1.783873e+04, 8.824183e+01, 4.893415e-01, -1.027429e+06, 5.516548e+04, 3.642565e+02, 2.717570e+00, -1.310055e+06, 9.297558e+04, 1.199666e+03, 1.188410e+01, -2.088964e+06, 1.472067e+05, 2.903674e+03, 3.864073e+01, -2.404946e+06, 1.832584e+05, 5.807015e+03, 1.028959e+02, -2.419199e+06, 1.963782e+05, 9.802613e+03, 2.313167e+02, -2.144173e+06, 1.846474e+05, 1.448111e+04, 4.529782e+02, -1.755673e+06, 1.566924e+05, 1.925615e+04, 7.929135e+02, -1.556385e+06, 1.260006e+05, 2.357954e+04, 1.267487e+03, -9.670740e+05, 7.884178e+04, 2.693555e+04, 1.882001e+03, -5.837683e+05, 4.472897e+04, 2.907526e+04, 2.623982e+03, -5.604275e+05, 2.840427e+04, 3.020165e+04, 3.477349e+03, -3.582842e+05, 6.067834e+03, 3.034485e+04, 4.425576e+03, -2.245319e+05, -8.290479e+03, 2.953728e+04, 5.439338e+03, -1.015845e+05, -1.802273e+04, 2.804648e+04, 6.490440e+03, -4.708202e+04, -2.097995e+04, 2.617044e+04, 7.553762e+03, -9.140648e+04, -1.778019e+04, 2.415851e+04, 8.612631e+03, -3.474920e+04, -2.078888e+04, 2.200252e+04, 9.655604e+03, 2.006550e+04, -2.169175e+04, 1.976088e+04, 1.066217e+04, -7.457237e+04, -1.281394e+04, 1.769310e+04, 1.162183e+04, 1.660390e+04, -1.849862e+04, 1.562554e+04, 1.253795e+04, -1.242914e+03, -1.387174e+04, 1.364603e+04, 1.338579e+04, -2.136653e+04, -1.038594e+04, 1.192412e+04, 1.417293e+04, 8.461670e+02, -1.092230e+04, 1.029799e+04, 1.490007e+04, -1.726136e+04, -7.648424e+03, 8.804960e+03, 1.555802e+04, -5.951019e+03, -7.711382e+03, 7.418584e+03, 1.615128e+04, -1.124333e+04, -5.937896e+03, 6.131419e+03, 1.667197e+04, -7.000456e+03, -5.382316e+03, 4.953545e+03, 1.712215e+04, -1.739957e+04, -3.384351e+03, 3.889292e+03, 1.749934e+04, -2.766408e+04, -1.885413e+03, 2.872322e+03, 1.780661e+04, -2.473009e+04, -1.511121e+03, 1.795912e+03, 1.803592e+04, -1.893613e+04, -4.433274e+02, 7.896820e+02, 1.817402e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.795339e+03, 1.024806e+02, 0, 0, -2.505222e+04, 1.240280e+03, 1.304988e+00, 5.749444e-03, -4.666245e+04, 4.461716e+03, 1.801239e+01, 1.073229e-01, -2.724635e+05, 1.761495e+04, 9.851115e+01, 7.710643e-01, -4.861356e+05, 3.717743e+04, 4.101052e+02, 4.193261e+00, -6.383714e+05, 6.152061e+04, 1.168007e+03, 1.598473e+01, -1.205391e+06, 9.889684e+04, 2.636565e+03, 4.738883e+01, -1.147720e+06, 1.106241e+05, 5.004828e+03, 1.183715e+02, -1.133494e+06, 1.155726e+05, 8.024451e+03, 2.508700e+02, -1.063750e+06, 1.090501e+05, 1.144213e+04, 4.682622e+02, -7.206625e+05, 8.651512e+04, 1.483243e+04, 7.896286e+02, -8.230661e+05, 7.733914e+04, 1.788080e+04, 1.224383e+03, -3.893929e+05, 4.348949e+04, 2.028440e+04, 1.779031e+03, -4.194027e+05, 3.349138e+04, 2.185878e+04, 2.439030e+03, -1.895883e+05, 1.198418e+04, 2.268839e+04, 3.196090e+03, -2.138071e+05, 6.670906e+03, 2.280864e+04, 4.026859e+03, -6.125361e+04, -6.683706e+03, 2.234923e+04, 4.916377e+03, -1.266566e+05, -5.092214e+03, 2.146339e+04, 5.838900e+03, -3.668092e+04, -1.292182e+04, 2.023530e+04, 6.783060e+03, -4.502149e+04, -1.220835e+04, 1.873724e+04, 7.722602e+03, -6.724879e+03, -1.428205e+04, 1.712856e+04, 8.645906e+03, -3.147242e+04, -1.120290e+04, 1.550800e+04, 9.537867e+03, 4.822493e+03, -1.299009e+04, 1.388952e+04, 1.039406e+04, -3.661611e+04, -8.222351e+03, 1.234509e+04, 1.120095e+04, 7.706524e+02, -1.086522e+04, 1.080666e+04, 1.196049e+04, -1.428372e+04, -7.903936e+03, 9.320418e+03, 1.265373e+04, -1.558705e+04, -6.942237e+03, 7.944124e+03, 1.328427e+04, 3.569541e+03, -7.689284e+03, 6.605008e+03, 1.384543e+04, -2.207606e+04, -3.799092e+03, 5.433831e+03, 1.433020e+04, -2.173362e+04, -3.685308e+03, 4.312741e+03, 1.475032e+04, -1.842206e+04, -3.390404e+03, 3.139013e+03, 1.508986e+04, -4.332377e+04, 1.904433e+02, 2.023367e+03, 1.533848e+04, -2.551285e+04, -6.475346e+01, 8.159825e+02, 1.549771e+04, }; static float solarDataset520[] = { 3.441260e+12, 4.257012e+05, 9.159649e+03, 2.155997e+02, -3.813319e+11, 9.728458e+07, 1.224196e+04, 2.157753e+02, -8.993466e+09, 5.812620e+06, 1.906304e+04, 2.179990e+02, 2.219112e+09, -1.465148e+06, 1.997638e+04, 2.245501e+02, -4.029785e+08, 1.497071e+06, 2.081556e+04, 2.372707e+02, 7.073014e+07, 4.201511e+05, 2.262724e+04, 2.603452e+02, 1.148052e+08, 3.113398e+05, 2.446750e+04, 2.971461e+02, -6.975728e+07, 9.816228e+05, 2.748132e+04, 3.534071e+02, 4.543997e+07, 3.776559e+05, 3.142461e+04, 4.400715e+02, -1.929005e+07, 8.214878e+05, 3.615734e+04, 5.652811e+02, -6.188209e+06, 6.920153e+05, 4.256955e+04, 7.501487e+02, -2.183429e+07, 7.943841e+05, 4.986206e+04, 1.014418e+03, -1.140788e+07, 5.966216e+05, 5.766701e+04, 1.385850e+03, -1.246868e+07, 5.332061e+05, 6.507698e+04, 1.885028e+03, -1.535117e+07, 4.615705e+05, 7.180659e+04, 2.535598e+03, -6.922309e+06, 2.072982e+05, 7.639904e+04, 3.351496e+03, -7.654747e+06, 1.405907e+05, 7.834404e+04, 4.319751e+03, -3.608348e+06, -1.032324e+04, 7.774929e+04, 5.429596e+03, -3.310273e+06, -5.122568e+04, 7.470562e+04, 6.644330e+03, -1.803698e+06, -1.089710e+05, 6.977953e+04, 7.932441e+03, -4.481058e+05, -1.414144e+05, 6.339972e+04, 9.249011e+03, -8.474652e+05, -1.138910e+05, 5.661672e+04, 1.055570e+04, 9.091255e+04, -1.286682e+05, 4.971740e+04, 1.183266e+04, -3.296997e+05, -9.203473e+04, 4.316623e+04, 1.304789e+04, 6.138098e+04, -9.130578e+04, 3.710169e+04, 1.419808e+04, 8.019984e+04, -7.334147e+04, 3.160993e+04, 1.526375e+04, -1.056039e+05, -5.125085e+04, 2.694897e+04, 1.624692e+04, 3.523169e+04, -4.850597e+04, 2.280818e+04, 1.715304e+04, 6.870219e+04, -3.957775e+04, 1.917548e+04, 1.797303e+04, -1.326338e+04, -2.682913e+04, 1.621399e+04, 1.871381e+04, 1.157345e+03, -2.265762e+04, 1.371834e+04, 1.938801e+04, 1.114799e+04, -1.872180e+04, 1.154622e+04, 1.999570e+04, 4.035315e+02, -1.421776e+04, 9.712803e+03, 2.054042e+04, -8.685193e+01, -1.141822e+04, 8.163078e+03, 2.102864e+04, 2.765763e+03, -9.358492e+03, 6.836780e+03, 2.146394e+04, 9.596016e+02, -7.320212e+03, 5.716072e+03, 2.184997e+04, -3.591287e+03, -5.538701e+03, 4.774094e+03, 2.219169e+04, 4.877164e+02, -4.837933e+03, 3.959721e+03, 2.249316e+04, -3.944127e+03, -3.487922e+03, 3.263769e+03, 2.275573e+04, -8.194186e+03, -2.533610e+03, 2.659495e+03, 2.298365e+04, 1.810861e+03, -3.022148e+03, 2.090564e+03, 2.317744e+04, -8.870991e+03, -1.251568e+03, 1.616934e+03, 2.333414e+04, -1.072378e+04, -9.168446e+02, 1.182863e+03, 2.346196e+04, -1.120528e+04, -5.191012e+02, 7.308553e+02, 2.355571e+04, -8.359487e+03, -1.040853e+02, 3.073388e+02, 2.361176e+04, 2.035431e+12, 2.901375e+07, 4.780096e+03, 9.809298e+01, -5.474072e+11, 1.251406e+08, 7.594803e+03, 9.819442e+01, 1.394761e+10, -7.629265e+06, 1.388420e+04, 9.997117e+01, -1.679680e+09, 2.117312e+06, 1.337516e+04, 1.041901e+02, 8.766416e+08, -9.398136e+05, 1.402618e+04, 1.131463e+02, -1.075785e+08, 9.687180e+05, 1.495756e+04, 1.278750e+02, 2.864970e+07, 5.123123e+05, 1.720256e+04, 1.533065e+02, 9.381308e+06, 5.907406e+05, 1.985760e+04, 1.937223e+02, 6.513705e+05, 6.528921e+05, 2.353833e+04, 2.568166e+02, -5.060574e+06, 7.148069e+05, 2.845009e+04, 3.540337e+02, -2.618546e+07, 8.664181e+05, 3.479716e+04, 5.020198e+02, -3.042888e+06, 6.182842e+05, 4.212681e+04, 7.239051e+02, -2.186162e+07, 7.922891e+05, 5.016165e+04, 1.040177e+03, -1.315392e+07, 5.761193e+05, 5.868562e+04, 1.485943e+03, -1.193382e+07, 4.596976e+05, 6.604172e+04, 2.079489e+03, -1.054882e+07, 3.262631e+05, 7.180635e+04, 2.836858e+03, -7.325607e+06, 1.634016e+05, 7.502793e+04, 3.759447e+03, -3.572050e+06, 1.753149e+04, 7.527153e+04, 4.828034e+03, -3.650321e+06, -2.059097e+04, 7.313771e+04, 6.010651e+03, -1.306615e+06, -1.038379e+05, 6.897657e+04, 7.278719e+03, -1.434776e+06, -1.010734e+05, 6.337556e+04, 8.585264e+03, -2.928626e+05, -1.291286e+05, 5.694775e+04, 9.900359e+03, -2.016734e+05, -1.130713e+05, 5.027089e+04, 1.118410e+04, -2.496937e+05, -9.435927e+04, 4.393471e+04, 1.241926e+04, 2.877942e+04, -8.902541e+04, 3.793319e+04, 1.359137e+04, -4.486830e+04, -6.924231e+04, 3.248876e+04, 1.468407e+04, 6.596483e+04, -6.067637e+04, 2.767914e+04, 1.569668e+04, 1.919128e+03, -4.535751e+04, 2.353265e+04, 1.662511e+04, -1.625891e+04, -3.587718e+04, 1.999336e+04, 1.747626e+04, 4.744522e+02, -2.997748e+04, 1.689298e+04, 1.825163e+04, 4.486151e+04, -2.618098e+04, 1.419742e+04, 1.895127e+04, -1.216274e+04, -1.716435e+04, 1.198976e+04, 1.957871e+04, -1.352060e+03, -1.478644e+04, 1.013202e+04, 2.014715e+04, 1.854542e+04, -1.309060e+04, 8.504452e+03, 2.065628e+04, -1.365895e+04, -8.081327e+03, 7.172319e+03, 2.110940e+04, 7.774980e+03, -8.328556e+03, 6.022138e+03, 2.151710e+04, -1.162068e+04, -5.117308e+03, 5.035574e+03, 2.187637e+04, 5.375795e+02, -5.332525e+03, 4.164918e+03, 2.219523e+04, 4.583329e+03, -4.486221e+03, 3.397818e+03, 2.247013e+04, -1.191642e+04, -2.061146e+03, 2.790819e+03, 2.270630e+04, -4.488671e+02, -2.946084e+03, 2.225430e+03, 2.291181e+04, -1.079293e+04, -1.286923e+03, 1.715923e+03, 2.307911e+04, -7.008889e+03, -1.462410e+03, 1.229813e+03, 2.321411e+04, -1.789120e+04, 1.465535e+02, 7.731271e+02, 2.331052e+04, -8.173676e+03, -1.495901e+02, 2.878103e+02, 2.337081e+04, 1.247757e+12, -4.159768e+06, 4.106319e+03, 2.671606e+01, -1.699001e+11, 3.477713e+07, 5.075193e+03, 2.679200e+01, 7.370859e+09, -4.831578e+06, 6.046716e+03, 2.761225e+01, 1.300189e+09, -8.314183e+05, 5.253834e+03, 2.933335e+01, -4.200184e+08, 1.179100e+06, 5.779982e+03, 3.268336e+01, 1.995671e+08, -6.254952e+04, 6.866446e+03, 3.957643e+01, -6.307859e+07, 7.234239e+05, 8.143396e+03, 5.096381e+01, 2.152375e+07, 3.977221e+05, 1.040391e+04, 7.159662e+01, -8.539422e+06, 6.140945e+05, 1.326918e+04, 1.058127e+02, -1.078821e+07, 6.779304e+05, 1.750490e+04, 1.635930e+02, -1.275937e+07, 7.382400e+05, 2.313246e+04, 2.590606e+02, -1.872188e+07, 8.098821e+05, 3.031069e+04, 4.127114e+02, -1.831776e+07, 7.681029e+05, 3.876504e+04, 6.520684e+02, -1.327143e+07, 6.348936e+05, 4.759282e+04, 1.005990e+03, -1.250117e+07, 5.390875e+05, 5.602596e+04, 1.500068e+03, -1.108426e+07, 4.074780e+05, 6.331628e+04, 2.157158e+03, -7.144209e+06, 2.282751e+05, 6.830848e+04, 2.985745e+03, -5.593622e+06, 1.138962e+05, 7.048728e+04, 3.973074e+03, -2.744275e+06, -8.550059e+03, 6.988463e+04, 5.096047e+03, -2.060504e+06, -5.271929e+04, 6.700169e+04, 6.315326e+03, -1.188937e+06, -8.943405e+04, 6.253661e+04, 7.597067e+03, -7.019956e+05, -1.025893e+05, 5.696328e+04, 8.901951e+03, -1.520013e+05, -1.094255e+05, 5.085384e+04, 1.019564e+04, -4.279199e+05, -8.501426e+04, 4.481075e+04, 1.144946e+04, 2.473795e+05, -9.671243e+04, 3.890686e+04, 1.265006e+04, -1.850617e+05, -6.070952e+04, 3.361721e+04, 1.377212e+04, -1.055200e+04, -5.889414e+04, 2.890583e+04, 1.482700e+04, 8.554444e+04, -5.153152e+04, 2.458599e+04, 1.579867e+04, -3.284826e+04, -3.517891e+04, 2.094752e+04, 1.668657e+04, 2.250379e+04, -3.169404e+04, 1.781798e+04, 1.750203e+04, 7.187402e+02, -2.410799e+04, 1.510178e+04, 1.824183e+04, -1.312021e+04, -1.879373e+04, 1.278706e+04, 1.891267e+04, 2.993219e+04, -1.781145e+04, 1.075453e+04, 1.951760e+04, -4.534421e+03, -1.160389e+04, 9.076530e+03, 2.005681e+04, -9.759605e+03, -9.241454e+03, 7.683732e+03, 2.054363e+04, 1.191358e+04, -9.141714e+03, 6.435051e+03, 2.097932e+04, -8.934994e+03, -5.555194e+03, 5.395231e+03, 2.136320e+04, -6.609238e+03, -4.931263e+03, 4.502483e+03, 2.170563e+04, 5.379062e+03, -5.019351e+03, 3.680346e+03, 2.200446e+04, -1.353400e+04, -2.242077e+03, 3.005639e+03, 2.225951e+04, 2.319882e+03, -3.483057e+03, 2.379456e+03, 2.248033e+04, -1.195571e+04, -1.258098e+03, 1.838619e+03, 2.265852e+04, -8.857921e+03, -1.424507e+03, 1.329970e+03, 2.280386e+04, -1.138151e+04, -6.455122e+02, 8.319621e+02, 2.290844e+04, -8.381217e+03, -2.582078e+02, 3.786418e+02, 2.297301e+04, -6.454234e+12, 9.523189e+07, 2.495739e+03, 3.168572e+00, 1.564445e+09, -3.199648e+05, 2.543842e+01, 3.206831e+00, -1.131465e+10, 7.292156e+06, 1.655634e+01, 3.207991e+00, 4.572081e+08, -3.622419e+05, 1.152075e+03, 3.598120e+00, -1.359952e+08, 3.523478e+05, 1.247960e+03, 4.304180e+00, 8.530206e+07, -7.761152e+04, 1.537856e+03, 5.847887e+00, -4.046656e+06, 2.350133e+05, 1.924059e+03, 8.398513e+00, -9.369154e+06, 3.013373e+05, 2.894860e+03, 1.369454e+01, 1.558148e+05, 3.157345e+05, 4.412027e+03, 2.445354e+01, -9.593296e+06, 4.737070e+05, 6.780646e+03, 4.538315e+01, -1.399124e+07, 5.975570e+05, 1.057839e+04, 8.641807e+01, -1.458432e+07, 6.713753e+05, 1.603092e+04, 1.636301e+02, -1.575957e+07, 7.190945e+05, 2.317086e+04, 3.001042e+02, -1.469259e+07, 6.919930e+05, 3.170783e+04, 5.261023e+02, -1.349217e+07, 6.160599e+05, 4.083870e+04, 8.742847e+02, -1.067177e+07, 4.778233e+05, 4.945175e+04, 1.374014e+03, -7.035158e+06, 3.153236e+05, 5.638367e+04, 2.041943e+03, -6.267557e+06, 2.139302e+05, 6.107922e+04, 2.878901e+03, -3.507150e+06, 7.645845e+04, 6.313857e+04, 3.875261e+03, -2.677493e+06, 9.369796e+03, 6.254822e+04, 4.997522e+03, -1.075512e+06, -6.097170e+04, 5.980948e+04, 6.210996e+03, -7.903147e+05, -7.423698e+04, 5.563430e+04, 7.471213e+03, -4.489454e+05, -8.347235e+04, 5.072914e+04, 8.748128e+03, -2.919591e+05, -8.138940e+04, 4.543441e+04, 1.001114e+04, -1.257206e+05, -7.734475e+04, 4.007037e+04, 1.123568e+04, 7.103736e+04, -7.237268e+04, 3.490447e+04, 1.240137e+04, -1.651301e+05, -4.973913e+04, 3.027758e+04, 1.349609e+04, 2.019954e+05, -5.792714e+04, 2.601103e+04, 1.452225e+04, -2.203643e+05, -2.570562e+04, 2.240670e+04, 1.546308e+04, 1.590559e+05, -4.244143e+04, 1.908034e+04, 1.634265e+04, -4.466576e+04, -2.108640e+04, 1.622655e+04, 1.712995e+04, -3.174091e+03, -2.048205e+04, 1.388742e+04, 1.785684e+04, 2.790637e+04, -1.838833e+04, 1.176019e+04, 1.851513e+04, -2.641650e+04, -1.106596e+04, 1.000103e+04, 1.910723e+04, 1.001047e+04, -1.197742e+04, 8.449539e+03, 1.964524e+04, -6.360157e+03, -8.288998e+03, 7.088763e+03, 2.012232e+04, 9.035106e+03, -7.929982e+03, 5.927220e+03, 2.054736e+04, -1.377516e+04, -4.429300e+03, 4.963148e+03, 2.092106e+04, -1.844206e+03, -4.907418e+03, 4.100319e+03, 2.125328e+04, -1.021359e+03, -3.955754e+03, 3.315436e+03, 2.153793e+04, -1.171826e+04, -2.188327e+03, 2.657105e+03, 2.177916e+04, -3.402617e+03, -2.688462e+03, 2.032883e+03, 2.198166e+04, -1.058462e+04, -1.288381e+03, 1.472992e+03, 2.213899e+04, -1.978474e+04, 9.938386e+00, 9.552157e+02, 2.225671e+04, -1.234013e+04, -2.436993e+00, 3.887609e+02, 2.233175e+04, 0, 0, 0, 1.826016e-01, -1.781927e+10, 3.424198e+06, 0, 1.826016e-01, 3.387426e+08, -1.818905e+05, 4.801526e+01, 2.011516e-01, -1.332156e+08, 1.980034e+05, 3.787939e+01, 2.092672e-01, 7.713524e+06, 2.074307e+04, 1.278808e+02, 2.794094e-01, -1.191841e+07, 6.762032e+04, 1.970895e+02, 4.457797e-01, 1.168172e+07, 9.597587e+03, 3.212529e+02, 8.753281e-01, -7.375921e+06, 1.272459e+05, 5.312329e+02, 1.747178e+00, -1.857624e+06, 1.420437e+05, 1.084825e+03, 4.192300e+00, -4.445982e+06, 2.336181e+05, 2.069508e+03, 1.014047e+01, -9.256611e+06, 3.691046e+05, 3.961112e+03, 2.445296e+01, -1.146668e+07, 4.853842e+05, 7.269072e+03, 5.735080e+01, -1.079778e+07, 5.581243e+05, 1.230141e+04, 1.261528e+02, -1.490989e+07, 6.582014e+05, 1.920854e+04, 2.563772e+02, -1.194617e+07, 5.952954e+05, 2.764421e+04, 4.835162e+02, -1.014583e+07, 5.122274e+05, 3.635427e+04, 8.392605e+02, -7.408351e+06, 3.853587e+05, 4.438509e+04, 1.350733e+03, -6.570506e+06, 2.855657e+05, 5.083123e+04, 2.031559e+03, -3.758086e+06, 1.418179e+05, 5.493214e+04, 2.882348e+03, -2.683018e+06, 6.098002e+04, 5.642001e+04, 3.878421e+03, -1.659085e+06, -4.330207e+03, 5.570503e+04, 4.991285e+03, -7.795872e+05, -4.882689e+04, 5.316507e+04, 6.183054e+03, -5.845028e+05, -5.942304e+04, 4.949336e+04, 7.415604e+03, -5.798157e+05, -6.026377e+04, 4.517923e+04, 8.660316e+03, 1.100702e+05, -8.130453e+04, 4.031747e+04, 9.888095e+03, -6.137872e+04, -6.032203e+04, 3.558748e+04, 1.106470e+04, -1.487668e+05, -4.829607e+04, 3.132184e+04, 1.219098e+04, 6.027672e+04, -5.086659e+04, 2.722487e+04, 1.325775e+04, -5.216647e+04, -3.589720e+04, 2.352245e+04, 1.424838e+04, 3.877460e+04, -3.464697e+04, 2.023029e+04, 1.516931e+04, 2.888551e+03, -2.575328e+04, 1.734715e+04, 1.601318e+04, -2.191980e+04, -1.979610e+04, 1.488919e+04, 1.678848e+04, 2.034645e+04, -1.902784e+04, 1.268427e+04, 1.749745e+04, -1.314803e+04, -1.300850e+04, 1.078756e+04, 1.813689e+04, 7.781400e+03, -1.225965e+04, 9.144667e+03, 1.871660e+04, -1.204517e+04, -8.419968e+03, 7.723806e+03, 1.923488e+04, 7.765000e+03, -8.536896e+03, 6.472742e+03, 1.969918e+04, -4.584280e+03, -5.708889e+03, 5.406950e+03, 2.010716e+04, -7.904211e+03, -4.491134e+03, 4.503836e+03, 2.046843e+04, -5.550058e+03, -3.997071e+03, 3.675945e+03, 2.078373e+04, -5.689591e+03, -3.236437e+03, 2.922488e+03, 2.105140e+04, -7.906009e+03, -2.378643e+03, 2.250590e+03, 2.127255e+04, -9.071692e+03, -1.745359e+03, 1.638712e+03, 2.144855e+04, -2.806270e+04, 6.649150e+02, 1.075166e+03, 2.157900e+04, -1.103646e+04, -2.530936e+02, 3.990825e+02, 2.166428e+04, 1.172160e+12, -1.700048e+07, -4.587932e+02, 9.275000e-03, -5.008907e+09, 9.229085e+05, 0, 2.318750e-03, 3.111030e+07, -1.680365e+04, 3.936294e+00, 6.956250e-03, -5.703770e+07, 5.741850e+04, 2.940735e+00, 7.535938e-03, 4.750408e+06, -7.579855e+03, 6.576946e+00, 1.797031e-02, -4.550239e+06, 1.931719e+04, 6.393513e+00, 2.202812e-02, 1.542980e+06, 4.706168e+03, 3.340755e+01, 6.202656e-02, -1.997114e+06, 3.649206e+04, 7.619777e+01, 1.739063e-01, -1.593482e+06, 6.356589e+04, 2.379679e+02, 6.562062e-01, -4.537893e+06, 1.384804e+05, 6.466292e+02, 2.352372e+00, -5.704782e+06, 2.258349e+05, 1.643354e+03, 7.932444e+00, -8.516026e+06, 3.526078e+05, 3.663294e+03, 2.360140e+01, -1.066595e+07, 4.742071e+05, 7.292901e+03, 6.245495e+01, -1.234505e+07, 5.621427e+05, 1.286902e+04, 1.467728e+02, -1.044587e+07, 5.508898e+05, 2.017730e+04, 3.077457e+02, -9.750714e+06, 5.176087e+05, 2.845385e+04, 5.789490e+02, -8.773548e+06, 4.361175e+05, 3.680154e+04, 9.938209e+02, -4.887482e+06, 2.768423e+05, 4.386506e+04, 1.574100e+03, -4.580514e+06, 2.042767e+05, 4.895668e+04, 2.319036e+03, -3.037548e+06, 1.001684e+05, 5.188273e+04, 3.224335e+03, -1.252849e+06, 9.423824e+03, 5.229785e+04, 4.260421e+03, -1.512708e+06, -4.514040e+03, 5.093166e+04, 5.388799e+03, -3.330454e+05, -5.840272e+04, 4.812166e+04, 6.583262e+03, -4.555910e+05, -5.259927e+04, 4.437818e+04, 7.797270e+03, -2.055898e+05, -6.043330e+04, 4.025830e+04, 9.011318e+03, -6.518244e+04, -5.931446e+04, 3.591151e+04, 1.019675e+04, -4.788129e+04, -5.148756e+04, 3.170073e+04, 1.133492e+04, -1.294721e+04, -4.516239e+04, 2.777118e+04, 1.241608e+04, -4.132531e+04, -3.650926e+04, 2.417892e+04, 1.343242e+04, 4.353457e+04, -3.480201e+04, 2.089273e+04, 1.438065e+04, -3.999510e+04, -2.363060e+04, 1.802457e+04, 1.525446e+04, 1.132551e+04, -2.302607e+04, 1.547307e+04, 1.606249e+04, 2.024966e+04, -1.900290e+04, 1.319929e+04, 1.679741e+04, -2.275982e+04, -1.253345e+04, 1.130444e+04, 1.746504e+04, 2.065540e+03, -1.244152e+04, 9.619555e+03, 1.807448e+04, 1.308942e+04, -1.073860e+04, 8.111327e+03, 1.861996e+04, -1.540943e+04, -6.359948e+03, 6.878335e+03, 1.910663e+04, -6.509802e+03, -6.323129e+03, 5.782487e+03, 1.954531e+04, 2.137483e+03, -5.897918e+03, 4.759477e+03, 1.992990e+04, -1.089014e+04, -3.529000e+03, 3.892929e+03, 2.026106e+04, -7.464418e+03, -3.372208e+03, 3.110704e+03, 2.054648e+04, -4.499778e+03, -2.965848e+03, 2.377458e+03, 2.078153e+04, -1.809100e+04, -9.389300e+02, 1.742044e+03, 2.096658e+04, -1.603605e+04, -8.315728e+02, 1.093057e+03, 2.110637e+04, -1.205302e+04, -2.096724e+02, 4.696001e+02, 2.119034e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.475609e+04, 3.371635e+02, 0, 0, 1.073009e+04, 4.374122e+02, 5.797537e-01, 5.796875e-04, -1.153454e+05, 2.841920e+03, 2.649198e+00, 4.057812e-03, -4.687182e+05, 1.144817e+04, 1.627061e+01, 3.304219e-02, -6.252477e+05, 3.031476e+04, 8.224170e+01, 2.295562e-01, -3.526268e+06, 9.906712e+04, 3.245361e+02, 1.211547e+00, -3.609003e+06, 1.630030e+05, 1.110639e+03, 5.633403e+00, -5.915653e+06, 2.810662e+05, 2.834579e+03, 1.971111e+01, -9.862311e+06, 4.241441e+05, 6.219224e+03, 5.787194e+01, -8.614873e+06, 4.527786e+05, 1.158730e+04, 1.459555e+02, -7.889704e+06, 4.557367e+05, 1.837941e+04, 3.144735e+02, -7.157548e+06, 4.205437e+05, 2.605154e+04, 5.981511e+02, -6.360659e+06, 3.497342e+05, 3.363796e+04, 1.028460e+03, -4.118223e+06, 2.292622e+05, 3.992991e+04, 1.623818e+03, -2.878278e+06, 1.400867e+05, 4.417527e+04, 2.379710e+03, -1.927495e+06, 6.762589e+04, 4.634548e+04, 3.280857e+03, -1.164354e+06, 1.289313e+04, 4.655326e+04, 4.300420e+03, -7.359802e+05, -1.922557e+04, 4.517303e+04, 5.404912e+03, -4.551779e+05, -3.785206e+04, 4.265242e+04, 6.561340e+03, -2.858538e+05, -4.634143e+04, 3.937600e+04, 7.738135e+03, -3.103799e+04, -5.354515e+04, 3.567211e+04, 8.907358e+03, -1.299037e+05, -4.253021e+04, 3.196524e+04, 1.004530e+04, -2.685978e+04, -4.253756e+04, 2.836175e+04, 1.114396e+04, -1.368389e+04, -3.669976e+04, 2.491097e+04, 1.218658e+04, -2.352848e+04, -3.043266e+04, 2.175512e+04, 1.316727e+04, -1.339091e+03, -2.684603e+04, 1.887271e+04, 1.408263e+04, 1.046307e+04, -2.278972e+04, 1.628025e+04, 1.492832e+04, 9.352423e+03, -1.845807e+04, 1.402391e+04, 1.570518e+04, -4.319180e+04, -1.193961e+04, 1.209103e+04, 1.641770e+04, 4.028668e+04, -1.613776e+04, 1.026860e+04, 1.707080e+04, -3.050514e+04, -7.295972e+03, 8.739795e+03, 1.765114e+04, 8.928799e+03, -9.664089e+03, 7.399996e+03, 1.818133e+04, -7.753111e+03, -6.276519e+03, 6.195452e+03, 1.864823e+04, -6.909366e+03, -5.375705e+03, 5.159494e+03, 1.906262e+04, -3.726578e+03, -4.729953e+03, 4.213524e+03, 1.942343e+04, -9.907304e+03, -3.262236e+03, 3.377412e+03, 1.973067e+04, -4.707397e+03, -3.194871e+03, 2.610089e+03, 1.998764e+04, -2.459705e+04, -5.431231e+02, 1.928936e+03, 2.019144e+04, -1.504684e+04, -1.268530e+03, 1.183585e+03, 2.034684e+04, -1.274940e+04, -2.357602e+02, 5.030266e+02, 2.043642e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.625111e+03, 1.942406e+02, 0, 0, -7.931768e+04, 2.359336e+03, 1.133080e+00, 2.318750e-03, -4.492099e+05, 1.342479e+04, 1.798340e+01, 5.101250e-02, -7.104236e+05, 3.641425e+04, 1.273072e+02, 5.072266e-01, -2.419312e+06, 1.031931e+05, 5.258904e+02, 2.856120e+00, -3.805147e+06, 1.873084e+05, 1.720050e+03, 1.257400e+01, -5.317208e+06, 2.798090e+05, 4.237425e+03, 4.225574e+01, -5.851424e+06, 3.374836e+05, 8.437182e+03, 1.146083e+02, -5.507526e+06, 3.474492e+05, 1.411444e+04, 2.603661e+02, -4.895399e+06, 3.204240e+05, 2.062382e+04, 5.126727e+02, -3.869675e+06, 2.596800e+05, 2.709028e+04, 9.003364e+02, -3.250395e+06, 1.961919e+05, 3.264631e+04, 1.439837e+03, -1.719326e+06, 1.064571e+05, 3.659167e+04, 2.133101e+03, -1.508329e+06, 6.693764e+04, 3.878265e+04, 2.961132e+03, -7.388517e+05, 1.449523e+04, 3.939682e+04, 3.906030e+03, -7.540220e+05, -5.614775e+02, 3.863621e+04, 4.934280e+03, -7.321527e+04, -3.634823e+04, 3.675864e+04, 6.019820e+03, -3.975025e+05, -2.269491e+04, 3.429005e+04, 7.123780e+03, 3.467499e+04, -4.367236e+04, 3.141477e+04, 8.236199e+03, -1.266303e+05, -3.044243e+04, 2.837963e+04, 9.321237e+03, -4.572541e+04, -3.225554e+04, 2.541711e+04, 1.037709e+04, 8.047126e+03, -3.069461e+04, 2.246501e+04, 1.138452e+04, 2.719321e+02, -2.520116e+04, 1.975091e+04, 1.233417e+04, -3.455116e+04, -1.935606e+04, 1.732791e+04, 1.322610e+04, -4.689464e+03, -1.871996e+04, 1.506835e+04, 1.405968e+04, 1.058268e+04, -1.648905e+04, 1.298115e+04, 1.482619e+04, -7.793109e+03, -1.216890e+04, 1.117406e+04, 1.552613e+04, -1.325167e+04, -9.935753e+03, 9.587327e+03, 1.616604e+04, 5.085932e+03, -9.803685e+03, 8.123301e+03, 1.674503e+04, -3.985046e+03, -7.120467e+03, 6.844793e+03, 1.725984e+04, -1.845867e+04, -4.797864e+03, 5.745869e+03, 1.771845e+04, 5.144229e+03, -6.303880e+03, 4.684891e+03, 1.812240e+04, -1.572588e+04, -2.947990e+03, 3.768049e+03, 1.846208e+04, -1.031994e+04, -3.174327e+03, 2.928434e+03, 1.875090e+04, -1.099561e+04, -2.380398e+03, 2.117366e+03, 1.897926e+04, -3.437355e+04, 6.816807e+02, 1.384817e+03, 1.914731e+04, -1.532091e+04, -2.375851e+02, 5.307093e+02, 1.925714e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.099496e+03, 3.170007e+01, 0, 0, -4.582160e+03, 2.717530e+02, 2.241895e-01, 5.796875e-04, -3.585634e+04, 2.139538e+03, 2.877762e+00, 9.854688e-03, -2.609433e+05, 1.233333e+04, 2.712355e+01, 1.182562e-01, -6.784321e+05, 3.792404e+04, 1.753766e+02, 1.005758e+00, -1.704870e+06, 9.086509e+04, 7.096012e+02, 5.462395e+00, -2.182629e+06, 1.428588e+05, 2.081180e+03, 2.173712e+01, -3.045174e+06, 2.017171e+05, 4.620780e+03, 6.547976e+01, -3.120058e+06, 2.258261e+05, 8.490531e+03, 1.620580e+02, -2.909976e+06, 2.219603e+05, 1.329642e+04, 3.408296e+02, -2.611518e+06, 1.958497e+05, 1.841926e+04, 6.296374e+02, -1.382570e+06, 1.339214e+05, 2.309259e+04, 1.047807e+03, -1.998218e+06, 1.265819e+05, 2.695490e+04, 1.598845e+03, -5.702259e+05, 4.570461e+04, 2.958101e+04, 2.288355e+03, -8.368829e+05, 3.927422e+04, 3.080162e+04, 3.084010e+03, -1.837335e+05, -2.241597e+03, 3.099690e+04, 3.976339e+03, -5.682648e+05, 6.527088e+03, 3.032646e+04, 4.930989e+03, 5.233127e+04, -2.991358e+04, 2.883729e+04, 5.936664e+03, -1.539996e+05, -1.717267e+04, 2.687146e+04, 6.947084e+03, -8.235537e+04, -2.202557e+04, 2.482136e+04, 7.962612e+03, -7.507519e+04, -2.154411e+04, 2.253483e+04, 8.960347e+03, 3.590736e+04, -2.572879e+04, 2.013928e+04, 9.924107e+03, -6.467983e+03, -1.870191e+04, 1.791295e+04, 1.083747e+04, -6.478698e+04, -1.295785e+04, 1.594240e+04, 1.170658e+04, 2.068703e+04, -1.780974e+04, 1.394673e+04, 1.252823e+04, 1.440187e+03, -1.297839e+04, 1.208844e+04, 1.328175e+04, -2.660685e+04, -8.967767e+03, 1.050701e+04, 1.397703e+04, 7.110755e+03, -1.063004e+04, 8.998969e+03, 1.461637e+04, -5.590234e+03, -7.510638e+03, 7.635425e+03, 1.518826e+04, -2.267292e+04, -5.019825e+03, 6.454280e+03, 1.570168e+04, 7.270321e+03, -7.162343e+03, 5.284981e+03, 1.615674e+04, -1.519724e+04, -3.427299e+03, 4.271128e+03, 1.654037e+04, -1.855140e+04, -2.800418e+03, 3.361608e+03, 1.686874e+04, -6.231274e+03, -3.489017e+03, 2.421245e+03, 1.713283e+04, -4.271753e+04, 1.261302e+03, 1.606297e+03, 1.732348e+04, -1.812555e+04, -2.715809e+02, 6.259157e+02, 1.745271e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.063987e+03, 3.054462e+02, 0, 0, -2.813574e+04, 1.877042e+03, 3.553681e+00, 1.623125e-02, -1.257337e+05, 8.447415e+03, 3.144681e+01, 1.930359e-01, -3.207497e+05, 2.447929e+04, 1.705861e+02, 1.372700e+00, -8.991627e+05, 5.794734e+04, 6.304306e+02, 6.658291e+00, -8.788635e+05, 7.984047e+04, 1.727592e+03, 2.451846e+01, -1.340991e+06, 1.142918e+05, 3.595521e+03, 6.842863e+01, -1.502817e+06, 1.295800e+05, 6.381372e+03, 1.604604e+02, -1.121162e+06, 1.171558e+05, 9.734555e+03, 3.246644e+02, -1.189577e+06, 1.116388e+05, 1.323854e+04, 5.801037e+02, -7.285780e+05, 8.048449e+04, 1.653685e+04, 9.441805e+02, -7.755311e+05, 6.738083e+04, 1.925313e+04, 1.419287e+03, -3.489333e+05, 3.413203e+04, 2.120419e+04, 2.006116e+03, -3.711578e+05, 2.473199e+04, 2.231455e+04, 2.686863e+03, -1.949665e+05, 6.860180e+03, 2.271868e+04, 3.451178e+03, -2.043607e+05, 1.205191e+03, 2.244544e+04, 4.276031e+03, -2.253753e+04, -1.242250e+04, 2.160182e+04, 5.143546e+03, -1.162624e+05, -7.671662e+03, 2.043880e+04, 6.027415e+03, -1.819840e+04, -1.508886e+04, 1.904169e+04, 6.921183e+03, -3.748045e+04, -1.282426e+04, 1.746345e+04, 7.800341e+03, -2.463956e+04, -1.307192e+04, 1.585114e+04, 8.657676e+03, 1.800068e+04, -1.453209e+04, 1.420241e+04, 9.480546e+03, -5.751030e+04, -7.191141e+03, 1.269744e+04, 1.025942e+04, 2.143863e+04, -1.325078e+04, 1.115837e+04, 1.100036e+04, -2.937991e+04, -6.800654e+03, 9.704313e+03, 1.167727e+04, 6.744357e+03, -9.354022e+03, 8.348776e+03, 1.230400e+04, -1.635229e+04, -5.637506e+03, 7.095223e+03, 1.286429e+04, -9.355270e+03, -5.739525e+03, 5.942650e+03, 1.336770e+04, -1.379714e+04, -4.465673e+03, 4.833668e+03, 1.380493e+04, -1.440112e+04, -3.753966e+03, 3.778207e+03, 1.417440e+04, -1.584389e+04, -2.861359e+03, 2.766756e+03, 1.447096e+04, -4.596605e+04, 9.777166e+02, 1.817438e+03, 1.469152e+04, -1.955254e+04, -3.565949e+02, 6.882263e+02, 1.483566e+04, }; static float solarDataset560[] = { 9.427478e+12, -2.974054e+07, 3.050751e+04, 6.870437e+02, -1.142007e+12, 2.473531e+08, 3.788610e+04, 6.876090e+02, 6.030303e+10, -3.189085e+07, 4.769687e+04, 6.937756e+02, -1.001912e+10, 1.190166e+07, 4.621301e+04, 7.080949e+02, 2.017518e+09, -2.733973e+06, 4.916779e+04, 7.398116e+02, -1.421427e+08, 1.460792e+06, 5.011031e+04, 7.908346e+02, -1.387029e+07, 8.966726e+05, 5.364395e+04, 8.724855e+02, 9.871561e+06, 7.113724e+05, 5.737052e+04, 9.940749e+02, 1.877554e+07, 6.336258e+05, 6.176658e+04, 1.167487e+03, -3.308155e+07, 8.873357e+05, 6.729500e+04, 1.408380e+03, -9.604436e+06, 6.024616e+05, 7.341952e+04, 1.738737e+03, -2.182764e+07, 6.203282e+05, 7.935645e+04, 2.175477e+03, -1.396323e+07, 4.168430e+05, 8.478006e+04, 2.740602e+03, -1.869470e+07, 3.550893e+05, 8.878213e+04, 3.445876e+03, -8.924426e+06, 9.938325e+04, 9.049216e+04, 4.298909e+03, -6.077214e+06, -9.169328e+03, 8.948659e+04, 5.283471e+03, -9.030289e+06, -1.361099e+04, 8.644249e+04, 6.382569e+03, -6.018017e+05, -2.166279e+05, 8.068593e+04, 7.572041e+03, -2.261151e+06, -1.582668e+05, 7.336941e+04, 8.793475e+03, -1.285988e+06, -1.711686e+05, 6.563977e+04, 1.003020e+04, -3.781520e+05, -1.714659e+05, 5.741413e+04, 1.124523e+04, 6.312955e+04, -1.524940e+05, 4.942384e+04, 1.240834e+04, -2.965801e+05, -1.122897e+05, 4.224018e+04, 1.350369e+04, 3.140122e+04, -1.022589e+05, 3.574972e+04, 1.452741e+04, 6.861713e+04, -8.171721e+04, 2.998492e+04, 1.546584e+04, 8.598786e+04, -6.438726e+04, 2.510945e+04, 1.632002e+04, -5.450437e+04, -4.482419e+04, 2.107040e+04, 1.709492e+04, 3.899927e+04, -4.009451e+04, 1.759867e+04, 1.779846e+04, 3.081603e+04, -3.072117e+04, 1.464125e+04, 1.842779e+04, 2.777883e+04, -2.372218e+04, 1.222329e+04, 1.899091e+04, -2.403858e+04, -1.592528e+04, 1.025673e+04, 1.949554e+04, 2.604334e+04, -1.580705e+04, 8.557456e+03, 1.994946e+04, -6.779180e+03, -1.020950e+04, 7.140866e+03, 2.035049e+04, 1.072751e+04, -9.367305e+03, 5.964755e+03, 2.070901e+04, -7.568154e+03, -6.091544e+03, 4.985814e+03, 2.102574e+04, 7.747026e+03, -6.090631e+03, 4.149838e+03, 2.130780e+04, -5.115560e+03, -3.749778e+03, 3.454636e+03, 2.155454e+04, 2.055488e+03, -3.682627e+03, 2.865067e+03, 2.177309e+04, -8.313760e+03, -2.062212e+03, 2.362034e+03, 2.196277e+04, 2.244934e+03, -2.716908e+03, 1.899309e+03, 2.212797e+04, -8.606358e+03, -1.085119e+03, 1.504703e+03, 2.226472e+04, 7.692302e+02, -1.849182e+03, 1.134821e+03, 2.237930e+04, -4.992822e+03, -7.414604e+02, 8.237234e+02, 2.246625e+04, -2.212781e+04, 1.130582e+03, 5.545028e+02, 2.253265e+04, -2.342747e+03, -3.239579e+02, 1.400637e+02, 2.257701e+04, -5.454661e+13, 6.695227e+08, 7.553013e+04, 3.151823e+02, 1.134950e+12, -2.733669e+08, 4.998801e+04, 3.164039e+02, 2.457067e+09, -5.372394e+05, 3.359107e+04, 3.204494e+02, 1.705050e+09, -3.885735e+05, 3.402986e+04, 3.314798e+02, -4.762097e+08, 1.872482e+06, 3.561497e+04, 3.534683e+02, 2.502076e+08, 3.098756e+05, 3.797324e+04, 3.924344e+02, 9.657814e+05, 9.594652e+05, 4.079242e+04, 4.537291e+02, 2.387841e+07, 8.134300e+05, 4.500723e+04, 5.476404e+02, -3.806754e+07, 1.053126e+06, 5.035453e+04, 6.862488e+02, 1.459099e+06, 7.335645e+05, 5.663526e+04, 8.873484e+02, -2.588512e+07, 8.852511e+05, 6.358440e+04, 1.168074e+03, -2.562254e+07, 7.542671e+05, 7.115830e+04, 1.554880e+03, -1.380731e+07, 5.011328e+05, 7.788194e+04, 2.068958e+03, -1.739894e+07, 4.295264e+05, 8.327746e+04, 2.724056e+03, -1.402960e+07, 2.469259e+05, 8.673685e+04, 3.532888e+03, -5.683137e+06, 1.809832e+04, 8.712896e+04, 4.487490e+03, -7.386279e+06, -5.267831e+03, 8.494526e+04, 5.562255e+03, -2.550597e+06, -1.428422e+05, 8.040191e+04, 6.736888e+03, -2.244178e+06, -1.494782e+05, 7.395598e+04, 7.964592e+03, -9.741098e+05, -1.707178e+05, 6.655347e+04, 9.214554e+03, -7.847748e+05, -1.541107e+05, 5.870751e+04, 1.045010e+04, 4.829605e+04, -1.529932e+05, 5.089533e+04, 1.164534e+04, -2.588837e+05, -1.146882e+05, 4.366237e+04, 1.277539e+04, 8.471593e+04, -1.046703e+05, 3.712384e+04, 1.383538e+04, -3.204309e+04, -7.873300e+04, 3.135177e+04, 1.481233e+04, 3.884792e+04, -6.547482e+04, 2.637054e+04, 1.570881e+04, 3.311172e+04, -5.122588e+04, 2.209839e+04, 1.652310e+04, 5.272904e+04, -4.098012e+04, 1.850837e+04, 1.725973e+04, -2.098666e+04, -2.870596e+04, 1.554469e+04, 1.792411e+04, -7.645698e+03, -2.392850e+04, 1.302179e+04, 1.852490e+04, 4.529440e+04, -2.168625e+04, 1.082138e+04, 1.906182e+04, 7.563854e+03, -1.438042e+04, 9.049216e+03, 1.953729e+04, -2.029968e+04, -9.904209e+03, 7.633053e+03, 1.996482e+04, 2.455605e+04, -1.104624e+04, 6.369259e+03, 2.034892e+04, -2.217501e+04, -5.312960e+03, 5.335176e+03, 2.068618e+04, 1.389523e+04, -7.222185e+03, 4.429009e+03, 2.098929e+04, 3.350305e+03, -4.596824e+03, 3.664659e+03, 2.125113e+04, -1.643678e+04, -2.165698e+03, 3.078933e+03, 2.148290e+04, 8.244762e+03, -4.103965e+03, 2.503118e+03, 2.168904e+04, -4.309852e+03, -1.906462e+03, 2.019271e+03, 2.186052e+04, -4.502906e+03, -1.615093e+03, 1.627422e+03, 2.200877e+04, -6.673494e+03, -1.145054e+03, 1.256210e+03, 2.213245e+04, -4.431929e+03, -1.125020e+03, 8.934107e+02, 2.223054e+04, -1.277831e+04, 1.017818e+02, 5.672148e+02, 2.230057e+04, -6.550689e+03, -6.795150e+01, 2.200245e+02, 2.234508e+04, 7.028093e+11, -5.632931e+06, 1.212518e+04, 8.786962e+01, 1.096934e+10, 3.427657e+06, 1.255748e+04, 8.808056e+01, -8.620693e+09, 6.311300e+06, 1.386382e+04, 8.966498e+01, 1.905895e+09, -7.785063e+05, 1.522377e+04, 9.457978e+01, -6.642623e+08, 2.069152e+06, 1.655659e+04, 1.044673e+02, 2.755384e+08, 1.270856e+05, 1.870469e+04, 1.233922e+02, -1.858521e+07, 9.802503e+05, 2.113739e+04, 1.541094e+02, 1.127113e+07, 8.555788e+05, 2.516211e+04, 2.048864e+02, -2.155426e+07, 1.035915e+06, 3.043400e+04, 2.857281e+02, -2.670990e+07, 1.046843e+06, 3.727913e+04, 4.129363e+02, -2.064658e+07, 9.583745e+05, 4.531105e+04, 6.072056e+02, -2.771027e+07, 9.488663e+05, 5.423102e+04, 8.931027e+02, -2.275812e+07, 7.675189e+05, 6.332478e+04, 1.299785e+03, -1.807120e+07, 5.679364e+05, 7.127246e+04, 1.849876e+03, -1.307118e+07, 3.611235e+05, 7.716269e+04, 2.557254e+03, -1.108885e+07, 2.095800e+05, 8.037925e+04, 3.422462e+03, -4.138438e+06, -1.246738e+03, 8.045019e+04, 4.432538e+03, -5.721080e+06, -1.375766e+04, 7.795263e+04, 5.553735e+03, -1.846673e+06, -1.340584e+05, 7.320954e+04, 6.762429e+03, -7.381453e+05, -1.533237e+05, 6.672674e+04, 8.006215e+03, -1.220612e+06, -1.255252e+05, 5.983885e+04, 9.253691e+03, -4.493834e+05, -1.350154e+05, 5.265160e+04, 1.048256e+04, 2.241188e+05, -1.320572e+05, 4.542483e+04, 1.165807e+04, -1.586451e+05, -9.300775e+04, 3.897017e+04, 1.276097e+04, -8.185331e+04, -7.944104e+04, 3.326870e+04, 1.379450e+04, 1.437491e+05, -7.221282e+04, 2.809949e+04, 1.474832e+04, -8.452171e+04, -4.730130e+04, 2.373007e+04, 1.561713e+04, 7.065088e+04, -4.526031e+04, 1.995960e+04, 1.641256e+04, -1.228967e+04, -3.137736e+04, 1.674335e+04, 1.712822e+04, 8.313530e+04, -2.961873e+04, 1.404205e+04, 1.777530e+04, -9.556767e+04, -1.350497e+04, 1.188112e+04, 1.835489e+04, 7.279899e+04, -2.152115e+04, 9.918036e+03, 1.888459e+04, -1.801529e+04, -1.047619e+04, 8.284368e+03, 1.934672e+04, 1.422292e+04, -1.081166e+04, 6.978533e+03, 1.976507e+04, -1.971096e+04, -6.232236e+03, 5.867255e+03, 2.013646e+04, 2.555580e+04, -8.493675e+03, 4.875924e+03, 2.046942e+04, -2.220971e+04, -2.736626e+03, 4.094432e+03, 2.075821e+04, 6.086730e+03, -4.963141e+03, 3.401028e+03, 2.102006e+04, -4.421174e+03, -2.900042e+03, 2.775707e+03, 2.124349e+04, -4.520515e+03, -2.411202e+03, 2.253152e+03, 2.143723e+04, -2.508622e+03, -2.146013e+03, 1.775733e+03, 2.160097e+04, -2.936199e+03, -1.618598e+03, 1.357499e+03, 2.173462e+04, -9.367685e+03, -6.231229e+02, 9.992896e+02, 2.184062e+04, -1.206672e+04, -1.719530e+02, 6.376552e+02, 2.192089e+04, -8.102102e+03, -5.838292e+00, 2.573335e+02, 2.197034e+04, -4.403129e+12, 5.670988e+07, 4.522792e+03, 1.062499e+01, 1.009104e+11, -2.052389e+07, 2.552832e+03, 1.069725e+01, -1.358716e+10, 8.667774e+06, 2.007574e+03, 1.088375e+01, 9.860870e+08, -7.696195e+05, 3.312868e+03, 1.199369e+01, -7.263205e+07, 5.079683e+05, 3.534528e+03, 1.404941e+01, 6.095618e+07, 2.370154e+05, 4.361871e+03, 1.824319e+01, 1.451466e+07, 4.286776e+05, 5.555429e+03, 2.590389e+01, -1.400850e+07, 6.184504e+05, 7.641043e+03, 4.027263e+01, -1.241073e+07, 6.950653e+05, 1.088771e+04, 6.743470e+01, -1.795027e+07, 8.260387e+05, 1.556669e+04, 1.172372e+02, -2.319572e+07, 9.411195e+05, 2.210913e+04, 2.061525e+02, -3.010013e+07, 1.015888e+06, 3.058323e+04, 3.586307e+02, -2.022242e+07, 8.484787e+05, 4.025853e+04, 6.058539e+02, -1.910299e+07, 7.492166e+05, 5.001245e+04, 9.760963e+02, -1.557142e+07, 5.745389e+05, 5.904610e+04, 1.498265e+03, -1.230740e+07, 3.873126e+05, 6.601791e+04, 2.188449e+03, -6.940073e+06, 1.748956e+05, 6.994206e+04, 3.045149e+03, -5.177292e+06, 6.314485e+04, 7.073880e+04, 4.045467e+03, -2.366516e+06, -4.755500e+04, 6.884163e+04, 5.161344e+03, -2.358205e+06, -6.773915e+04, 6.493284e+04, 6.352030e+03, -5.046368e+05, -1.245616e+05, 5.953143e+04, 7.585005e+03, -7.352958e+05, -1.050440e+05, 5.340095e+04, 8.814996e+03, -4.712122e+04, -1.140651e+05, 4.711703e+04, 1.002166e+04, -1.940792e+05, -9.000891e+04, 4.104669e+04, 1.117633e+04, -5.334300e+04, -8.040981e+04, 3.542982e+04, 1.227079e+04, 3.617207e+04, -6.882656e+04, 3.028288e+04, 1.329163e+04, 3.113110e+04, -5.478774e+04, 2.577621e+04, 1.423360e+04, -6.129565e+04, -4.010649e+04, 2.191962e+04, 1.509901e+04, 8.799100e+04, -3.960913e+04, 1.850097e+04, 1.589132e+04, -3.273914e+04, -2.471044e+04, 1.563896e+04, 1.660515e+04, 5.062606e+04, -2.465741e+04, 1.321567e+04, 1.725598e+04, -4.331664e+04, -1.394978e+04, 1.119464e+04, 1.784036e+04, 2.151457e+04, -1.584838e+04, 9.420701e+03, 1.837225e+04, 2.057252e+04, -1.209662e+04, 7.881816e+03, 1.884308e+04, -3.218097e+04, -5.996226e+03, 6.685549e+03, 1.926382e+04, 1.272473e+04, -8.675284e+03, 5.581521e+03, 1.964513e+04, 1.293397e+04, -6.525058e+03, 4.612838e+03, 1.997558e+04, -2.512579e+04, -2.085553e+03, 3.897889e+03, 2.026666e+04, 9.631166e+03, -5.124486e+03, 3.195860e+03, 2.052944e+04, -8.369392e+03, -2.217471e+03, 2.579994e+03, 2.074865e+04, -4.945385e+03, -2.272369e+03, 2.058660e+03, 2.093800e+04, -3.084443e+03, -1.973310e+03, 1.566386e+03, 2.109326e+04, -7.303688e+03, -1.067347e+03, 1.141462e+03, 2.121494e+04, -1.970787e+04, 4.640662e+02, 7.508659e+02, 2.130630e+04, -7.520008e+03, -1.899019e+02, 2.755003e+02, 2.136575e+04, 1.985745e+12, -2.912097e+07, -7.661830e+02, 6.684121e-01, -6.636634e+08, 2.990354e+05, 0, 6.567228e-01, -2.343986e+09, 1.611661e+06, 4.317728e+01, 6.599108e-01, 2.254208e+07, 4.359743e+04, 3.445681e+02, 7.645827e-01, 1.156883e+07, 5.539843e+04, 4.276905e+02, 1.007931e+00, 1.328478e+07, 6.727963e+04, 5.825680e+02, 1.532353e+00, -1.427828e+06, 1.497926e+05, 8.917103e+02, 2.663022e+00, 9.122115e+05, 2.061081e+05, 1.527034e+03, 5.318074e+00, -1.436027e+07, 3.894326e+05, 2.751124e+03, 1.153834e+01, -1.297819e+07, 4.891972e+05, 5.061759e+03, 2.652661e+01, -1.440164e+07, 6.231437e+05, 8.782631e+03, 5.952481e+01, -2.071955e+07, 7.895515e+05, 1.448705e+04, 1.272475e+02, -2.105556e+07, 8.342286e+05, 2.238247e+04, 2.567244e+02, -1.730582e+07, 7.638287e+05, 3.174262e+04, 4.810755e+02, -1.649409e+07, 6.787079e+05, 4.153117e+04, 8.337819e+02, -1.213281e+07, 4.915370e+05, 5.044160e+04, 1.344592e+03, -7.204027e+06, 2.923513e+05, 5.703735e+04, 2.024137e+03, -6.395770e+06, 1.876444e+05, 6.098537e+04, 2.865273e+03, -3.652266e+06, 5.084202e+04, 6.211538e+04, 3.853040e+03, -1.242084e+06, -4.545439e+04, 6.048160e+04, 4.948354e+03, -2.077700e+06, -3.761168e+04, 5.725210e+04, 6.110893e+03, -4.035125e+05, -9.878235e+04, 5.267188e+04, 7.316266e+03, -2.774259e+05, -9.184399e+04, 4.725635e+04, 8.513608e+03, -7.489327e+04, -8.630250e+04, 4.187600e+04, 9.683030e+03, -1.824318e+05, -6.931827e+04, 3.676257e+04, 1.080698e+04, -2.043178e+04, -6.528394e+04, 3.193106e+04, 1.187602e+04, -2.125564e+04, -5.356901e+04, 2.747061e+04, 1.287528e+04, 3.802628e+04, -4.622590e+04, 2.349523e+04, 1.380133e+04, -1.011949e+04, -3.479996e+04, 2.005371e+04, 1.465185e+04, 1.957445e+04, -2.979789e+04, 1.707635e+04, 1.543211e+04, -2.310000e+04, -2.169519e+04, 1.451302e+04, 1.614210e+04, 4.887815e+04, -2.176628e+04, 1.226507e+04, 1.678755e+04, -3.010570e+04, -1.212523e+04, 1.041726e+04, 1.736624e+04, 1.141261e+04, -1.307324e+04, 8.823028e+03, 1.789421e+04, 2.115730e+03, -9.658469e+03, 7.420827e+03, 1.836449e+04, -3.130044e+03, -7.419199e+03, 6.255799e+03, 1.878518e+04, -1.015496e+04, -5.605767e+03, 5.248800e+03, 1.916053e+04, 1.197197e+04, -6.387298e+03, 4.331709e+03, 1.949224e+04, -9.451760e+03, -3.045742e+03, 3.592623e+03, 1.977809e+04, -9.143314e+03, -2.779727e+03, 2.959049e+03, 2.003133e+04, -4.060531e+02, -3.138927e+03, 2.331861e+03, 2.024720e+04, -8.374759e+03, -1.630913e+03, 1.790562e+03, 2.042217e+04, -9.631227e+03, -1.214229e+03, 1.300725e+03, 2.056279e+04, -1.757971e+04, -7.909526e+00, 8.217597e+02, 2.066585e+04, -9.360190e+03, -1.008561e+02, 3.151603e+02, 2.072972e+04, 7.057544e+11, -1.002630e+07, -2.834657e+02, 2.019051e-02, -5.762712e+09, 1.096773e+06, 0, 1.593987e-02, 9.580494e+07, -5.116182e+04, 1.296875e+01, 2.178450e-02, -7.314732e+07, 8.930245e+04, 1.028639e+01, 2.390981e-02, 1.212836e+07, -1.522072e+04, 3.493413e+01, 4.781962e-02, 1.107723e+06, 1.523353e+04, 4.315452e+01, 8.182469e-02, -3.122114e+06, 4.692205e+04, 9.912353e+01, 1.912785e-01, -1.218946e+05, 6.710879e+04, 2.596781e+02, 6.004020e-01, -7.767512e+06, 1.781769e+05, 6.475762e+02, 1.923412e+00, -7.081599e+06, 2.703169e+05, 1.654503e+03, 6.432271e+00, -1.388268e+07, 4.599894e+05, 3.716433e+03, 1.933826e+01, -1.677008e+07, 6.152583e+05, 7.609712e+03, 5.293951e+01, -1.773788e+07, 7.158283e+05, 1.367450e+04, 1.284552e+02, -1.673161e+07, 7.330517e+05, 2.177075e+04, 2.764208e+02, -1.582636e+07, 6.844310e+05, 3.113206e+04, 5.328466e+02, -1.143484e+07, 5.250286e+05, 4.040399e+04, 9.320810e+02, -7.912410e+06, 3.651709e+05, 4.815568e+04, 1.493388e+03, -6.534461e+06, 2.459158e+05, 5.373328e+04, 2.221905e+03, -3.824178e+06, 1.046254e+05, 5.660509e+04, 3.108860e+03, -2.225738e+06, 1.563807e+04, 5.671396e+04, 4.122526e+03, -1.458328e+06, -3.221722e+04, 5.474607e+04, 5.227111e+03, -8.183570e+05, -6.333746e+04, 5.127832e+04, 6.386920e+03, -2.794557e+05, -7.986545e+04, 4.684627e+04, 7.565535e+03, -3.250386e+05, -7.038672e+04, 4.208904e+04, 8.732396e+03, -1.754872e+05, -6.847775e+04, 3.727257e+04, 9.869589e+03, 1.159607e+05, -6.912938e+04, 3.251333e+04, 1.095548e+04, -9.178916e+04, -4.742331e+04, 2.825702e+04, 1.197515e+04, -3.478289e+04, -4.291868e+04, 2.444894e+04, 1.293450e+04, 4.096451e+04, -3.883179e+04, 2.093198e+04, 1.382302e+04, 1.018149e+04, -2.939198e+04, 1.788632e+04, 1.463685e+04, -6.312718e+03, -2.298834e+04, 1.530245e+04, 1.538327e+04, 8.853193e+01, -1.922555e+04, 1.304664e+04, 1.606557e+04, -4.315150e+03, -1.538511e+04, 1.107414e+04, 1.668446e+04, 2.613878e+04, -1.434570e+04, 9.354640e+03, 1.724279e+04, -3.056698e+04, -7.440654e+03, 7.953552e+03, 1.774252e+04, 1.201257e+04, -9.709738e+03, 6.690044e+03, 1.819679e+04, 2.315698e+03, -6.742600e+03, 5.577442e+03, 1.859490e+04, -9.440768e+03, -4.516726e+03, 4.681297e+03, 1.894793e+04, 1.196941e+03, -4.741381e+03, 3.874527e+03, 1.926086e+04, -7.702191e+03, -2.981726e+03, 3.168711e+03, 1.953055e+04, -8.882011e+03, -2.461540e+03, 2.537074e+03, 1.976277e+04, -1.422894e+03, -2.714319e+03, 1.927726e+03, 1.995485e+04, -1.333538e+04, -8.409366e+02, 1.410345e+03, 2.010401e+04, -1.909208e+04, -3.880590e+01, 9.041545e+02, 2.021755e+04, -1.040053e+04, -1.016679e+02, 3.480591e+02, 2.028776e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.747318e+05, 3.472389e+03, 0, 0, 4.067195e+05, -3.625279e+02, 3.698487e+00, 4.781962e-03, -2.201325e+05, 7.112541e+03, 7.958936e+00, 1.540855e-02, -1.375506e+06, 3.099300e+04, 4.379474e+01, 9.351393e-02, -2.748196e+06, 8.093983e+04, 2.179212e+02, 6.189985e-01, -4.968397e+06, 1.759744e+05, 7.942168e+02, 3.123153e+00, -9.224231e+06, 3.310828e+05, 2.317096e+03, 1.246073e+01, -1.172345e+07, 4.760308e+05, 5.552592e+03, 4.086665e+01, -1.364940e+07, 5.855323e+05, 1.095084e+04, 1.106753e+02, -1.160214e+07, 5.818835e+05, 1.835230e+04, 2.545476e+02, -1.186484e+07, 5.618680e+05, 2.689271e+04, 5.080793e+02, -8.404699e+06, 4.221755e+05, 3.536085e+04, 9.063264e+02, -5.194575e+06, 2.784763e+05, 4.225115e+04, 1.464581e+03, -5.350129e+06, 2.094167e+05, 4.716334e+04, 2.183139e+03, -1.602308e+06, 5.042204e+04, 4.954778e+04, 3.054031e+03, -2.214826e+06, 3.646787e+04, 4.967168e+04, 4.035868e+03, -9.356126e+05, -3.084597e+04, 4.811762e+04, 5.110060e+03, -4.549349e+05, -5.386665e+04, 4.503815e+04, 6.230077e+03, -3.040345e+05, -5.796460e+04, 4.128150e+04, 7.364268e+03, -1.176667e+05, -6.013046e+04, 3.722607e+04, 8.489020e+03, -2.285004e+05, -4.899339e+04, 3.315231e+04, 9.583239e+03, 1.171614e+05, -5.738783e+04, 2.908158e+04, 1.063408e+04, -6.209781e+04, -3.832039e+04, 2.537658e+04, 1.162023e+04, -2.092407e+04, -3.477457e+04, 2.209397e+04, 1.255044e+04, 7.150074e+03, -3.032506e+04, 1.906153e+04, 1.341566e+04, -1.872806e+04, -2.346902e+04, 1.637525e+04, 1.421280e+04, 3.845397e+04, -2.256213e+04, 1.398698e+04, 1.494422e+04, -2.212050e+04, -1.416819e+04, 1.197514e+04, 1.560777e+04, 1.117884e+04, -1.415931e+04, 1.022919e+04, 1.621605e+04, -9.805903e+03, -9.936432e+03, 8.698553e+03, 1.676423e+04, -6.284957e+03, -8.619152e+03, 7.363785e+03, 1.725975e+04, 8.194854e+03, -8.133936e+03, 6.160163e+03, 1.770134e+04, -1.348632e+03, -5.585066e+03, 5.156021e+03, 1.808984e+04, -2.129218e+04, -3.033875e+03, 4.322259e+03, 1.843476e+04, 1.090528e+04, -5.636095e+03, 3.481772e+03, 1.873867e+04, -1.576162e+04, -1.719787e+03, 2.785226e+03, 1.898864e+04, -3.646745e+03, -2.827982e+03, 2.153210e+03, 1.920291e+04, -1.365574e+04, -1.131453e+03, 1.562656e+03, 1.936968e+04, -1.907849e+04, -2.359625e+02, 9.938042e+02, 1.949465e+04, -1.267951e+04, -2.792363e+00, 3.995119e+02, 1.957176e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.253495e+03, 7.499863e+01, 0, 0, -1.750552e+04, 6.611353e+02, 3.286766e-01, 5.313292e-04, -1.773001e+05, 5.748574e+03, 4.539952e+00, 1.009525e-02, -9.223470e+05, 2.879966e+04, 4.664094e+01, 1.386769e-01, -1.930323e+06, 7.899737e+04, 2.852048e+02, 1.171049e+00, -4.376965e+06, 1.804810e+05, 1.095224e+03, 6.203799e+00, -6.199410e+06, 2.925007e+05, 3.155202e+03, 2.454156e+01, -8.265951e+06, 3.988727e+05, 7.017706e+03, 7.510072e+01, -7.418139e+06, 4.164357e+05, 1.276099e+04, 1.879864e+02, -7.040578e+06, 4.038613e+05, 1.967473e+04, 3.966702e+02, -5.686102e+06, 3.336694e+05, 2.686086e+04, 7.341906e+02, -4.304528e+06, 2.438082e+05, 3.315168e+04, 1.220839e+03, -2.692813e+06, 1.463149e+05, 3.773689e+04, 1.860259e+03, -1.797320e+06, 7.842619e+04, 4.036734e+04, 2.638594e+03, -1.480552e+06, 3.567044e+04, 4.122917e+04, 3.534651e+03, -4.691014e+05, -1.943763e+04, 4.039585e+04, 4.520549e+03, -4.771614e+05, -2.551283e+04, 3.841306e+04, 5.556536e+03, -2.993912e+05, -3.669547e+04, 3.578773e+04, 6.621797e+03, -7.863820e+04, -4.472026e+04, 3.264362e+04, 7.688512e+03, -7.947163e+04, -3.968368e+04, 2.936882e+04, 8.732777e+03, -4.626689e+04, -3.655540e+04, 2.617168e+04, 9.743299e+03, -3.298749e+04, -3.228438e+04, 2.309979e+04, 1.070825e+04, 7.557068e+03, -2.951923e+04, 2.021271e+04, 1.161922e+04, -1.131117e+04, -2.346075e+04, 1.760143e+04, 1.246985e+04, -8.138479e+02, -2.029297e+04, 1.526546e+04, 1.326110e+04, -6.482612e+03, -1.648920e+04, 1.317628e+04, 1.399093e+04, -9.595959e+02, -1.408842e+04, 1.131675e+04, 1.466044e+04, -8.934017e+03, -1.109881e+04, 9.671678e+03, 1.526962e+04, 1.509275e+04, -1.089459e+04, 8.203717e+03, 1.582083e+04, -1.453210e+04, -6.361619e+03, 6.975921e+03, 1.631342e+04, -1.009911e+04, -6.003604e+03, 5.892338e+03, 1.675910e+04, 4.806694e+03, -6.254916e+03, 4.858851e+03, 1.715199e+04, -1.071047e+04, -3.527770e+03, 3.984625e+03, 1.748987e+04, -8.640748e+03, -3.280218e+03, 3.206107e+03, 1.778279e+04, -5.456272e+03, -2.969433e+03, 2.463075e+03, 1.802588e+04, -1.521043e+04, -1.321653e+03, 1.804258e+03, 1.821785e+04, -2.367697e+04, -9.087804e+01, 1.159175e+03, 1.836246e+04, -1.433487e+04, -4.953068e+01, 4.611681e+02, 1.845283e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.175559e+04, 9.319479e+02, 0, 0, -1.155952e+05, 5.362912e+03, 7.533434e+00, 2.444114e-02, -4.781473e+05, 2.294213e+04, 6.469392e+01, 2.901057e-01, -1.186903e+06, 6.363668e+04, 3.418921e+02, 2.059963e+00, -2.457058e+06, 1.339813e+05, 1.225389e+03, 9.946482e+00, -3.689532e+06, 2.089429e+05, 3.267949e+03, 3.596461e+01, -3.635500e+06, 2.440573e+05, 6.751900e+03, 1.017719e+02, -4.240893e+06, 2.702413e+05, 1.146298e+04, 2.351121e+02, -2.806952e+06, 2.203272e+05, 1.683224e+04, 4.676621e+02, -2.755320e+06, 1.948001e+05, 2.199412e+04, 8.191252e+02, -2.060483e+06, 1.377770e+05, 2.645927e+04, 1.306106e+03, -1.097631e+06, 7.499210e+04, 2.952827e+04, 1.925185e+03, -1.000923e+06, 4.815843e+04, 3.123190e+04, 2.659039e+03, -4.315165e+05, 8.335406e+03, 3.169514e+04, 3.491872e+03, -4.699637e+05, -3.883861e+02, 3.111515e+04, 4.393927e+03, -1.358086e+05, -2.181426e+04, 2.973216e+04, 5.345470e+03, -2.102148e+05, -1.969387e+04, 2.780408e+04, 6.315553e+03, -2.056386e+03, -3.015444e+04, 2.554160e+04, 7.289349e+03, -1.214515e+05, -2.109060e+04, 2.317332e+04, 8.242094e+03, 2.283767e+04, -2.752130e+04, 2.075837e+04, 9.169350e+03, 7.777847e+02, -2.167302e+04, 1.841980e+04, 1.004997e+04, -5.404760e+04, -1.555831e+04, 1.633979e+04, 1.088609e+04, 2.732346e+04, -1.905176e+04, 1.431599e+04, 1.167632e+04, -2.032427e+04, -1.233088e+04, 1.247912e+04, 1.240595e+04, -1.714066e+04, -1.113399e+04, 1.084237e+04, 1.308473e+04, 1.575944e+04, -1.185483e+04, 9.276789e+03, 1.370596e+04, -1.758306e+04, -6.912145e+03, 7.932318e+03, 1.426459e+04, -4.249523e+03, -7.239515e+03, 6.729422e+03, 1.477256e+04, -2.329697e+03, -6.114440e+03, 5.608986e+03, 1.522204e+04, -5.910026e+03, -4.665776e+03, 4.630493e+03, 1.561502e+04, -1.798960e+04, -2.846416e+03, 3.762089e+03, 1.595518e+04, -3.910095e+03, -3.884273e+03, 2.890839e+03, 1.624284e+04, -1.926873e+04, -1.391269e+03, 2.105855e+03, 1.646675e+04, -2.740709e+04, -1.634349e+02, 1.341530e+03, 1.663561e+04, -1.586965e+04, -1.115448e+02, 5.221589e+02, 1.673964e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.127396e+02, 4.028231e+01, 0, 0, -2.922208e+03, 3.533675e+02, 4.231000e-01, 1.593987e-03, -7.834748e+04, 3.913683e+03, 5.563741e+00, 2.656646e-02, -1.794238e+05, 1.330030e+04, 5.847158e+01, 3.613038e-01, -7.133529e+05, 4.140932e+04, 2.841249e+02, 2.339974e+00, -8.219289e+05, 6.765098e+04, 9.828657e+02, 1.089809e+01, -1.608881e+06, 1.135553e+05, 2.399301e+03, 3.586206e+01, -1.380790e+06, 1.250011e+05, 4.785818e+03, 9.597186e+01, -1.681694e+06, 1.416683e+05, 7.913429e+03, 2.122113e+02, -1.342164e+06, 1.248846e+05, 1.153453e+04, 4.098636e+02, -1.138530e+06, 1.048019e+05, 1.506125e+04, 7.058108e+02, -7.560038e+05, 7.458648e+04, 1.812017e+04, 1.110256e+03, -7.365586e+05, 5.736215e+04, 2.047117e+04, 1.622284e+03, -2.829319e+05, 2.385083e+04, 2.194529e+04, 2.236639e+03, -3.746521e+05, 1.866296e+04, 2.260812e+04, 2.932459e+03, -2.109677e+05, 1.572390e+03, 2.259219e+04, 3.699650e+03, -4.422227e+04, -1.078135e+04, 2.187151e+04, 4.512166e+03, -1.480152e+05, -6.663066e+03, 2.082518e+04, 5.348479e+03, -3.470247e+04, -1.527565e+04, 1.948176e+04, 6.200584e+03, -1.374575e+04, -1.543198e+04, 1.789581e+04, 7.043310e+03, -4.756536e+04, -1.215076e+04, 1.631547e+04, 7.867040e+03, -2.328940e+03, -1.445670e+04, 1.469261e+04, 8.665875e+03, -2.943259e+04, -1.086144e+04, 1.309232e+04, 9.424964e+03, 2.219356e+04, -1.335516e+04, 1.153409e+04, 1.014250e+04, -3.753978e+04, -6.601135e+03, 1.014219e+04, 1.080706e+04, 6.462929e+03, -9.897952e+03, 8.803313e+03, 1.142966e+04, -1.185789e+04, -6.587254e+03, 7.531425e+03, 1.199133e+04, -5.585795e+03, -6.310054e+03, 6.385138e+03, 1.249966e+04, -1.095521e+04, -4.847504e+03, 5.319253e+03, 1.294953e+04, -1.433834e+04, -3.906517e+03, 4.322975e+03, 1.334142e+04, -3.995946e+03, -4.280124e+03, 3.350694e+03, 1.367127e+04, -2.687799e+04, -1.046360e+03, 2.493151e+03, 1.393293e+04, -3.083327e+04, -4.093439e+02, 1.594075e+03, 1.413478e+04, -1.950779e+04, -7.012349e+01, 6.281431e+02, 1.425796e+04, }; static float solarDataset600[] = { 1.454828e+13, -1.753873e+07, 4.108891e+04, 1.618972e+03, -1.384284e+12, 3.644504e+08, 5.345299e+04, 1.619749e+03, -5.626237e+10, 3.552050e+07, 8.094015e+04, 1.629074e+03, 3.728997e+09, -3.217893e+06, 8.610187e+04, 1.657417e+03, -1.341046e+09, 2.537266e+06, 8.654787e+04, 1.711991e+03, 1.037406e+09, -1.842154e+06, 8.743552e+04, 1.804243e+03, -2.281591e+08, 1.692114e+06, 8.931420e+04, 1.940869e+03, 4.381924e+07, 4.651551e+05, 9.344253e+04, 2.142112e+03, -4.759171e+07, 8.163875e+05, 9.726835e+04, 2.419359e+03, -1.821050e+07, 4.964279e+05, 1.013782e+05, 2.792134e+03, -2.368294e+07, 4.294862e+05, 1.048241e+05, 3.274694e+03, -1.941022e+07, 2.763683e+05, 1.074121e+05, 3.882373e+03, -1.590314e+07, 1.381601e+05, 1.084676e+05, 4.624161e+03, -1.691643e+07, 5.407009e+04, 1.075833e+05, 5.501698e+03, -9.692053e+06, -1.241486e+05, 1.040909e+05, 6.506736e+03, -4.836417e+06, -2.247011e+05, 9.795019e+04, 7.611780e+03, -5.822942e+06, -2.072205e+05, 9.012361e+04, 8.785157e+03, -4.934677e+05, -2.953874e+05, 8.082216e+04, 9.997030e+03, -1.972241e+06, -2.181519e+05, 7.109185e+04, 1.120129e+04, -2.891157e+05, -2.240168e+05, 6.151353e+04, 1.238053e+04, -4.966324e+05, -1.758467e+05, 5.236592e+04, 1.350154e+04, 1.641487e+05, -1.585700e+05, 4.401724e+04, 1.455163e+04, 8.034773e+04, -1.203842e+05, 3.671628e+04, 1.551563e+04, -1.271137e+04, -9.085232e+04, 3.057720e+04, 1.639592e+04, 3.823284e+04, -7.282635e+04, 2.535605e+04, 1.719488e+04, 4.041914e+04, -5.648343e+04, 2.094476e+04, 1.791302e+04, 9.493516e+04, -4.559175e+04, 1.728272e+04, 1.855507e+04, -5.146686e+04, -2.872101e+04, 1.434663e+04, 1.912718e+04, 7.274758e+04, -2.868041e+04, 1.186372e+04, 1.964130e+04, -1.137111e+04, -1.752581e+04, 9.839214e+03, 2.009446e+04, -1.008472e+04, -1.422576e+04, 8.192508e+03, 2.050076e+04, 2.515788e+04, -1.323360e+04, 6.753657e+03, 2.086086e+04, 1.584386e+04, -9.397442e+03, 5.594194e+03, 2.117599e+04, -1.982323e+04, -5.090890e+03, 4.709331e+03, 2.145612e+04, 9.160687e+03, -6.384271e+03, 3.918052e+03, 2.170842e+04, 6.487543e+03, -4.632844e+03, 3.236203e+03, 2.192755e+04, -1.558850e+04, -2.009499e+03, 2.714977e+03, 2.212059e+04, 1.214568e+04, -4.063965e+03, 2.216067e+03, 2.229301e+04, -9.387616e+03, -1.151481e+03, 1.817672e+03, 2.243736e+04, 1.549500e+03, -2.094099e+03, 1.475644e+03, 2.256570e+04, -4.531227e+03, -1.034617e+03, 1.167963e+03, 2.267195e+04, -2.936346e+03, -1.036553e+03, 8.946197e+02, 2.276081e+04, -4.991516e+03, -5.847746e+02, 6.400900e+02, 2.283020e+04, -8.686370e+03, -8.226384e+00, 4.001762e+02, 2.288082e+04, -4.282608e+03, -6.966287e+01, 1.490135e+02, 2.291176e+04, -8.258616e+13, 9.904778e+08, 1.318286e+05, 7.747884e+02, 2.062665e+12, -4.786463e+08, 9.235644e+04, 7.769322e+02, -3.538830e+10, 2.205724e+07, 6.694206e+04, 7.847311e+02, 4.058662e+09, -3.295631e+06, 7.000223e+04, 8.077786e+02, -1.994471e+07, 1.416720e+06, 7.075137e+04, 8.521384e+02, -1.187269e+08, 1.283696e+06, 7.366460e+04, 9.280772e+02, 2.540619e+08, 2.026807e+05, 7.681548e+04, 1.046331e+03, -1.391960e+08, 1.579054e+06, 8.135576e+04, 1.218133e+03, 2.530622e+07, 5.920718e+05, 8.701200e+04, 1.465097e+03, -3.251666e+07, 8.728196e+05, 9.250368e+04, 1.800184e+03, -4.349050e+07, 7.754678e+05, 9.852956e+04, 2.248042e+03, -2.011892e+07, 3.930905e+05, 1.031312e+05, 2.827391e+03, -1.799797e+07, 2.525175e+05, 1.056848e+05, 3.545122e+03, -1.574729e+07, 1.139525e+05, 1.062387e+05, 4.406529e+03, -1.205118e+07, -2.983359e+04, 1.041875e+05, 5.405193e+03, -6.697812e+06, -1.674924e+05, 9.926112e+04, 6.519409e+03, -4.384345e+06, -2.195876e+05, 9.199400e+04, 7.714342e+03, -1.862072e+06, -2.540928e+05, 8.320020e+04, 8.954122e+03, -1.908592e+06, -2.218975e+05, 7.374786e+04, 1.020097e+04, -6.595484e+05, -2.191046e+05, 6.409677e+04, 1.142642e+04, 5.591668e+05, -2.065625e+05, 5.471249e+04, 1.259732e+04, -8.093373e+05, -1.264564e+05, 4.652504e+04, 1.369474e+04, 1.688527e+05, -1.334041e+05, 3.909025e+04, 1.472375e+04, 2.419749e+05, -1.045422e+05, 3.245138e+04, 1.565887e+04, -1.230208e+05, -6.804517e+04, 2.707154e+04, 1.650613e+04, 1.126806e+05, -6.300250e+04, 2.249086e+04, 1.727731e+04, -7.142991e+04, -4.118624e+04, 1.863553e+04, 1.796673e+04, 1.675606e+05, -4.267365e+04, 1.536107e+04, 1.858582e+04, -6.485362e+04, -2.110609e+04, 1.279192e+04, 1.913137e+04, 2.637560e+04, -2.212235e+04, 1.067530e+04, 1.962669e+04, 7.981750e+03, -1.608272e+04, 8.844225e+03, 2.006475e+04, 1.871909e+04, -1.315898e+04, 7.352146e+03, 2.045392e+04, -1.840475e+04, -8.056233e+03, 6.149474e+03, 2.079909e+04, 1.957039e+04, -9.075917e+03, 5.104541e+03, 2.110797e+04, -8.536233e+03, -4.982923e+03, 4.248788e+03, 2.137749e+04, 3.499200e+03, -5.020523e+03, 3.538293e+03, 2.161816e+04, -2.000849e+03, -3.512066e+03, 2.928448e+03, 2.182841e+04, 3.638545e+03, -3.264362e+03, 2.415994e+03, 2.201285e+04, -1.015257e+04, -1.420977e+03, 1.998918e+03, 2.217269e+04, 4.403337e+03, -2.590383e+03, 1.602086e+03, 2.231300e+04, -7.875874e+03, -7.971346e+02, 1.270059e+03, 2.242772e+04, 2.108760e+03, -1.686184e+03, 9.648043e+02, 2.252491e+04, -9.024057e+03, -1.121285e+02, 7.146217e+02, 2.259896e+04, -1.078560e+04, 5.370255e+01, 4.574484e+02, 2.265738e+04, -4.144847e+03, -1.351749e+02, 1.580973e+02, 2.269255e+04, -7.925848e+12, 7.954113e+07, 4.342033e+04, 2.306639e+02, 2.269955e+11, -6.495581e+07, 3.909724e+04, 2.313954e+02, 3.302993e+10, -1.552044e+07, 3.333664e+04, 2.355661e+02, -4.784910e+09, 7.541830e+06, 3.379938e+04, 2.459800e+02, 3.613537e+08, 7.051546e+05, 3.758040e+04, 2.693637e+02, 2.012123e+08, 9.047518e+05, 4.026196e+04, 3.100796e+02, -3.247217e+07, 1.458624e+06, 4.458575e+04, 3.762391e+02, 3.509220e+07, 1.133284e+06, 5.050532e+04, 4.804963e+02, -6.375528e+07, 1.554986e+06, 5.800171e+04, 6.381134e+02, -2.892941e+07, 1.197304e+06, 6.695868e+04, 8.734957e+02, -5.164969e+07, 1.213830e+06, 7.625104e+04, 1.209469e+03, -2.739672e+07, 7.928510e+05, 8.505819e+04, 1.674458e+03, -2.787464e+07, 6.247649e+05, 9.206065e+04, 2.284897e+03, -1.871019e+07, 3.383328e+05, 9.669688e+04, 3.055270e+03, -1.379705e+07, 1.369205e+05, 9.808678e+04, 3.981429e+03, -8.704135e+06, -3.571846e+04, 9.616835e+04, 5.046769e+03, -4.155272e+06, -1.581929e+05, 9.124700e+04, 6.219767e+03, -4.104771e+06, -1.676177e+05, 8.431879e+04, 7.461843e+03, -1.265230e+06, -2.229547e+05, 7.591780e+04, 8.739201e+03, -9.083431e+05, -2.002438e+05, 6.683417e+04, 1.000630e+04, -5.255757e+05, -1.783831e+05, 5.790308e+04, 1.123644e+04, 4.993118e+05, -1.719879e+05, 4.940310e+04, 1.240539e+04, -7.487545e+05, -9.942973e+04, 4.203530e+04, 1.349507e+04, 3.978438e+05, -1.195978e+05, 3.528825e+04, 1.451412e+04, -2.047206e+04, -7.632391e+04, 2.942983e+04, 1.543376e+04, 6.154258e+04, -6.346317e+04, 2.463164e+04, 1.627325e+04, -2.863798e+04, -4.606248e+04, 2.057180e+04, 1.703219e+04, 7.388099e+04, -4.085648e+04, 1.711248e+04, 1.771723e+04, -2.064163e+04, -2.712556e+04, 1.425554e+04, 1.832846e+04, 3.328744e+04, -2.433972e+04, 1.186725e+04, 1.887791e+04, 1.002028e+04, -1.754222e+04, 9.878580e+03, 1.936576e+04, 8.911729e+03, -1.374369e+04, 8.260222e+03, 1.980154e+04, -2.085488e+04, -9.181720e+03, 6.920058e+03, 2.019044e+04, 2.914076e+04, -1.070749e+04, 5.730227e+03, 2.053766e+04, -1.293038e+04, -5.174966e+03, 4.781798e+03, 2.083987e+04, 5.221232e+03, -5.721930e+03, 3.997709e+03, 2.111160e+04, 2.329131e+03, -4.209210e+03, 3.318380e+03, 2.134929e+04, -1.120600e+04, -2.323414e+03, 2.771525e+03, 2.155871e+04, 4.077728e+03, -3.348798e+03, 2.255768e+03, 2.174367e+04, -4.397494e+03, -1.781340e+03, 1.814239e+03, 2.189875e+04, -2.371566e+03, -1.679149e+03, 1.440870e+03, 2.203123e+04, -3.509356e+03, -1.211255e+03, 1.104800e+03, 2.213993e+04, -6.401342e+03, -6.643209e+02, 8.055120e+02, 2.222624e+04, -9.121022e+03, -1.798506e+02, 5.138316e+02, 2.229047e+04, -6.114652e+03, -5.727757e+01, 2.165918e+02, 2.233048e+04, 9.465569e+11, 2.157107e+07, 2.323822e+03, 3.141042e+01, -3.198079e+11, 7.414625e+07, 3.911285e+03, 3.146173e+01, 9.476628e+09, -4.475969e+06, 7.835770e+03, 3.245139e+01, -8.928972e+08, 1.881666e+06, 7.953473e+03, 3.487056e+01, 3.171872e+08, 2.635279e+05, 9.264064e+03, 4.047706e+01, -5.849106e+07, 9.732834e+05, 1.087038e+04, 5.087843e+01, 8.242971e+07, 6.037953e+05, 1.349207e+04, 7.009928e+01, -3.032662e+07, 1.159453e+06, 1.732089e+04, 1.033948e+02, -3.561716e+07, 1.251423e+06, 2.330419e+04, 1.629440e+02, -3.448639e+07, 1.286417e+06, 3.117127e+04, 2.657617e+02, -3.649510e+07, 1.300592e+06, 4.093241e+04, 4.359338e+02, -4.363745e+07, 1.276591e+06, 5.220971e+04, 7.050447e+02, -2.840810e+07, 9.451539e+05, 6.355126e+04, 1.108138e+03, -2.581926e+07, 7.360833e+05, 7.326328e+04, 1.668684e+03, -1.354418e+07, 3.883004e+05, 8.025788e+04, 2.403289e+03, -1.377454e+07, 2.590663e+05, 8.389776e+04, 3.304769e+03, -6.998331e+06, 2.378317e+04, 8.395422e+04, 4.361063e+03, -3.017568e+06, -1.031107e+05, 8.045998e+04, 5.528584e+03, -3.053944e+06, -1.159054e+05, 7.492129e+04, 6.765323e+03, -9.988790e+05, -1.670190e+05, 6.794613e+04, 8.038403e+03, -7.984465e+05, -1.523819e+05, 6.021692e+04, 9.302581e+03, -9.338634e+04, -1.494507e+05, 5.246052e+04, 1.053131e+04, -1.035431e+05, -1.215806e+05, 4.515398e+04, 1.169887e+04, -7.357601e+04, -9.990059e+04, 3.857402e+04, 1.279598e+04, 1.792570e+03, -8.319324e+04, 3.268700e+04, 1.381455e+04, 3.874347e+04, -6.749650e+04, 2.752666e+04, 1.474920e+04, 4.244814e+04, -5.329079e+04, 2.311818e+04, 1.560008e+04, -7.930994e+03, -3.984100e+04, 1.941511e+04, 1.637147e+04, 8.733277e+04, -3.589956e+04, 1.626214e+04, 1.706943e+04, -7.640893e+04, -1.973546e+04, 1.370832e+04, 1.769570e+04, 6.465562e+04, -2.412718e+04, 1.146747e+04, 1.826574e+04, -1.257959e+04, -1.387134e+04, 9.594876e+03, 1.876880e+04, -3.216704e+03, -1.199645e+04, 8.071823e+03, 1.922295e+04, 1.185898e+04, -1.055074e+04, 6.732374e+03, 1.962756e+04, -8.043290e+02, -7.356438e+03, 5.627495e+03, 1.998509e+04, -1.628058e+03, -5.891328e+03, 4.712682e+03, 2.030343e+04, -3.439586e+03, -4.645427e+03, 3.923985e+03, 2.058511e+04, 3.075924e+03, -4.271196e+03, 3.234865e+03, 2.083229e+04, -1.635081e+03, -2.923961e+03, 2.662415e+03, 2.104614e+04, -7.090127e+03, -1.933064e+03, 2.185308e+03, 2.123232e+04, -4.437563e+03, -1.933243e+03, 1.734860e+03, 2.139234e+04, -3.653738e+02, -1.892874e+03, 1.311083e+03, 2.152288e+04, -1.354368e+04, -1.252045e+02, 9.651989e+02, 2.162438e+04, -6.525776e+03, -7.519351e+02, 5.872714e+02, 2.170241e+04, -6.046958e+03, -1.425454e+02, 2.526236e+02, 2.174657e+04, 7.685478e+11, -3.587368e+06, -5.614277e+02, 2.176726e+00, -6.325697e+10, 1.540102e+07, 0, 2.169919e+00, 6.037976e+08, -1.269417e+05, 9.536601e+02, 2.283023e+00, -1.231879e+08, 2.884108e+05, 1.064814e+03, 2.602961e+00, 1.338161e+08, -3.138454e+04, 1.282376e+03, 3.367459e+00, -8.742091e+06, 3.029956e+05, 1.660242e+03, 4.836763e+00, 4.214728e+05, 3.431726e+05, 2.546292e+03, 8.152906e+00, -8.769409e+06, 4.935859e+05, 4.054901e+03, 1.537637e+01, -2.118875e+07, 7.043190e+05, 6.707452e+03, 3.116117e+01, -1.956295e+07, 8.532277e+05, 1.108718e+04, 6.499704e+01, -3.731153e+07, 1.135945e+06, 1.777807e+04, 1.334155e+02, -3.091261e+07, 1.121036e+06, 2.709678e+04, 2.649024e+02, -3.270901e+07, 1.105922e+06, 3.809708e+04, 4.929304e+02, -2.200409e+07, 8.529194e+05, 4.956525e+04, 8.559269e+02, -2.038642e+07, 6.855276e+05, 5.978076e+04, 1.380667e+03, -1.117204e+07, 3.795010e+05, 6.745803e+04, 2.085776e+03, -9.901093e+06, 2.365954e+05, 7.171413e+04, 2.961349e+03, -4.354972e+06, 3.054048e+04, 7.248689e+04, 3.990590e+03, -3.140714e+06, -3.946535e+04, 7.017581e+04, 5.129246e+03, -1.994865e+06, -9.051388e+04, 6.582553e+04, 6.341791e+03, -5.803806e+05, -1.294484e+05, 5.994991e+04, 7.586278e+03, -8.405790e+05, -1.086236e+05, 5.349962e+04, 8.822279e+03, 2.303613e+05, -1.273856e+05, 4.686398e+04, 1.002781e+04, -4.101851e+05, -8.285763e+04, 4.066681e+04, 1.117171e+04, 2.025071e+05, -9.176353e+04, 3.492952e+04, 1.225612e+04, -1.241871e+05, -6.014883e+04, 2.981741e+04, 1.325813e+04, 7.450568e+04, -5.766421e+04, 2.535029e+04, 1.418817e+04, -3.498195e+04, -4.081103e+04, 2.145641e+04, 1.503639e+04, 5.737509e+04, -3.728994e+04, 1.810341e+04, 1.581109e+04, 1.553564e+04, -2.696393e+04, 1.527417e+04, 1.651003e+04, -3.264956e+04, -1.915601e+04, 1.294140e+04, 1.714428e+04, 2.039836e+04, -1.885321e+04, 1.087146e+04, 1.771893e+04, 3.616331e+04, -1.547233e+04, 9.097636e+03, 1.822993e+04, -4.400956e+04, -6.947860e+03, 7.730975e+03, 1.868663e+04, 2.524433e+04, -1.107087e+04, 6.479718e+03, 1.910332e+04, -1.159559e+04, -5.722883e+03, 5.403721e+03, 1.946613e+04, 8.803311e+03, -6.362971e+03, 4.509957e+03, 1.979080e+04, -7.832658e+03, -3.602953e+03, 3.758517e+03, 2.007421e+04, -6.382527e+03, -3.252304e+03, 3.110174e+03, 2.032548e+04, 1.111503e+03, -3.330009e+03, 2.499038e+03, 2.054191e+04, -6.645172e+03, -1.857684e+03, 1.983350e+03, 2.072246e+04, -4.647336e+02, -2.123280e+03, 1.524736e+03, 2.087328e+04, -1.619462e+04, -7.161461e+01, 1.135444e+03, 2.099191e+04, -1.145722e+04, -5.148367e+02, 6.981336e+02, 2.108415e+04, -8.317955e+03, -3.174918e+01, 2.682136e+02, 2.113680e+04, 6.686770e+09, -5.232905e+04, 9.004540e+01, 8.220978e-02, -1.221062e+09, 1.938090e+05, 9.420210e+01, 8.378067e-02, 9.327238e+07, -6.870038e+04, 8.763799e+01, 9.582414e-02, 5.996937e+07, -4.274478e+04, 7.265223e+01, 1.204347e-01, -1.133786e+07, 6.147611e+04, 9.131150e+01, 1.649432e-01, 3.386784e+05, 5.305621e+04, 1.829889e+02, 3.157484e-01, 3.484062e+06, 8.082698e+04, 3.519414e+02, 7.346517e-01, -8.136297e+06, 2.145670e+05, 7.559280e+02, 1.929050e+00, -1.422495e+07, 3.782352e+05, 1.798927e+03, 5.751019e+00, -1.921481e+07, 5.817554e+05, 4.031473e+03, 1.702790e+01, -2.466374e+07, 8.092501e+05, 8.208813e+03, 4.659724e+01, -2.957367e+07, 9.988951e+05, 1.503472e+04, 1.151984e+02, -2.934849e+07, 1.043498e+06, 2.455141e+04, 2.553897e+02, -2.437625e+07, 9.281228e+05, 3.566919e+04, 5.065714e+02, -1.808598e+07, 7.249953e+05, 4.667018e+04, 9.049815e+02, -1.413967e+07, 5.250627e+05, 5.602253e+04, 1.475116e+03, -9.253251e+06, 3.021326e+05, 6.252165e+04, 2.225350e+03, -4.436136e+06, 1.093543e+05, 6.552585e+04, 3.139939e+03, -4.814005e+06, 5.669314e+04, 6.565072e+04, 4.187778e+03, -1.840489e+06, -6.337635e+04, 6.313183e+04, 5.341067e+03, -6.904183e+05, -1.012176e+05, 5.850287e+04, 6.544246e+03, -7.497582e+05, -9.311380e+04, 5.312391e+04, 7.761001e+03, -4.210654e+05, -9.618680e+04, 4.738566e+04, 8.967658e+03, 8.995083e+04, -9.946898e+04, 4.148243e+04, 1.013491e+04, -2.075976e+05, -7.103257e+04, 3.602031e+04, 1.124072e+04, 8.338291e+04, -7.078879e+04, 3.100960e+04, 1.228431e+04, -2.730415e+04, -5.205078e+04, 2.653114e+04, 1.325030e+04, 2.150946e+04, -4.459231e+04, 2.264211e+04, 1.414394e+04, -1.423980e+04, -3.417936e+04, 1.925258e+04, 1.496260e+04, 1.473821e+04, -2.918906e+04, 1.630554e+04, 1.571000e+04, 3.220392e+04, -2.405451e+04, 1.376762e+04, 1.638610e+04, -2.684524e+04, -1.571254e+04, 1.167668e+04, 1.699638e+04, 3.088042e+04, -1.651758e+04, 9.851958e+03, 1.755058e+04, -1.721349e+04, -9.750730e+03, 8.323807e+03, 1.804451e+04, 1.345637e+04, -1.027197e+04, 7.017991e+03, 1.849141e+04, -2.174811e+04, -5.602956e+03, 5.906349e+03, 1.888762e+04, 1.177125e+04, -7.439854e+03, 4.898836e+03, 1.924275e+04, 1.647970e+03, -4.795697e+03, 4.041270e+03, 1.954881e+04, -5.843917e+03, -3.222697e+03, 3.369872e+03, 1.981799e+04, -9.789821e+03, -2.446804e+03, 2.772770e+03, 2.005474e+04, -1.378097e+03, -2.879752e+03, 2.186681e+03, 2.025740e+04, -6.290251e+03, -1.724383e+03, 1.668369e+03, 2.042133e+04, -1.101343e+04, -9.097999e+02, 1.211492e+03, 2.055181e+04, -1.111452e+04, -5.639870e+02, 7.532181e+02, 2.064806e+04, -8.320836e+03, -1.432660e+02, 3.235242e+02, 2.070595e+04, 0, 0, 0, 0, 0, 0, 0, 0, -1.472727e+07, 9.704940e+03, 0, 0, -2.351848e+05, 1.879504e+02, 1.617783e+00, 5.236292e-04, 8.699198e+05, -9.875575e+02, 1.570521e+00, 1.570887e-03, -6.250379e+05, 4.145386e+03, 2.379199e+00, 3.141775e-03, 4.286236e+05, 4.412056e+03, 1.077048e+01, 1.466162e-02, -2.043447e+06, 3.157819e+04, 3.625093e+01, 6.388276e-02, -1.085061e+06, 6.162908e+04, 1.682113e+02, 3.869620e-01, -6.697354e+06, 1.915110e+05, 5.837246e+02, 1.821706e+00, -1.347910e+07, 3.939200e+05, 1.934535e+03, 8.045039e+00, -1.740487e+07, 5.943821e+05, 5.113283e+03, 2.940335e+01, -2.005659e+07, 7.567963e+05, 1.080316e+04, 8.665382e+01, -1.933757e+07, 8.074300e+05, 1.910717e+04, 2.128584e+02, -1.922524e+07, 7.785521e+05, 2.917605e+04, 4.485973e+02, -1.197210e+07, 5.629568e+05, 3.928913e+04, 8.333176e+02, -9.951533e+06, 4.244022e+05, 4.773463e+04, 1.385596e+03, -6.709627e+06, 2.506304e+05, 5.376726e+04, 2.114235e+03, -3.571100e+06, 9.933375e+04, 5.665657e+04, 3.002215e+03, -2.574425e+06, 2.579319e+04, 5.681603e+04, 4.016538e+03, -1.456834e+06, -3.525546e+04, 5.484294e+04, 5.124406e+03, -8.939211e+05, -6.390266e+04, 5.124523e+04, 6.284900e+03, -1.101180e+05, -8.746416e+04, 4.665656e+04, 7.461369e+03, -4.681458e+05, -6.529437e+04, 4.184970e+04, 8.621092e+03, -4.045757e+03, -7.596463e+04, 3.697388e+04, 9.752269e+03, -1.734660e+04, -6.231731e+04, 3.224549e+04, 1.082680e+04, -9.987665e+04, -4.861101e+04, 2.799504e+04, 1.184010e+04, 7.265535e+04, -4.826171e+04, 2.406867e+04, 1.278797e+04, -1.134999e+04, -3.441852e+04, 2.062683e+04, 1.365988e+04, 6.090832e+03, -2.914563e+04, 1.767500e+04, 1.446480e+04, -6.974627e+02, -2.329559e+04, 1.508844e+04, 1.520183e+04, -1.472800e+04, -1.825859e+04, 1.284207e+04, 1.587375e+04, 3.206836e+04, -1.770135e+04, 1.085176e+04, 1.648269e+04, -2.032028e+03, -1.153400e+04, 9.204911e+03, 1.702789e+04, -2.968679e+04, -7.797147e+03, 7.845514e+03, 1.752289e+04, 3.245165e+04, -1.117046e+04, 6.548123e+03, 1.796936e+04, -1.709462e+04, -4.558688e+03, 5.505584e+03, 1.835768e+04, -9.796017e+03, -4.811111e+03, 4.633948e+03, 1.870978e+04, 3.674447e+03, -5.128812e+03, 3.778722e+03, 1.901758e+04, 1.967537e+02, -3.600181e+03, 3.057183e+03, 1.927876e+04, -1.317163e+04, -1.679278e+03, 2.480028e+03, 1.950210e+04, -2.183190e+03, -2.611229e+03, 1.910794e+03, 1.969236e+04, -1.531156e+04, -6.658682e+02, 1.393683e+03, 1.984029e+04, -1.371122e+04, -5.957229e+02, 8.684685e+02, 1.995218e+04, -1.023819e+04, -8.502304e+01, 3.579622e+02, 2.001862e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.585623e+03, 2.130250e+02, 0, 0, -1.935079e+05, 3.900197e+03, 9.971148e-01, 1.570887e-03, -6.527066e+05, 1.858015e+04, 2.205255e+01, 4.974477e-02, -1.500053e+06, 6.028248e+04, 1.529140e+02, 4.916878e-01, -4.974313e+06, 1.764505e+05, 6.943200e+02, 3.048045e+00, -8.678217e+06, 3.342531e+05, 2.410493e+03, 1.446892e+01, -1.052839e+07, 4.688102e+05, 6.113438e+03, 5.121774e+01, -1.280428e+07, 5.701865e+05, 1.214618e+04, 1.417166e+02, -9.465653e+06, 5.125406e+05, 2.000545e+04, 3.248129e+02, -9.176467e+06, 4.685079e+05, 2.835925e+04, 6.344485e+02, -6.639283e+06, 3.383421e+05, 3.609536e+04, 1.101131e+03, -3.945560e+06, 2.017257e+05, 4.181661e+04, 1.731452e+03, -3.291661e+06, 1.255684e+05, 4.524933e+04, 2.513072e+03, -1.322687e+06, 2.510134e+04, 4.636870e+04, 3.426583e+03, -1.300582e+06, 1.614129e+03, 4.558508e+04, 4.432770e+03, -4.698930e+05, -4.109357e+04, 4.343189e+04, 5.505804e+03, -4.863562e+05, -4.316647e+04, 4.031339e+04, 6.606426e+03, -1.901139e+05, -5.444630e+04, 3.665707e+04, 7.711348e+03, 5.980810e+04, -5.772322e+04, 3.272677e+04, 8.791214e+03, -1.495518e+05, -3.987647e+04, 2.904712e+04, 9.828835e+03, -6.078588e+04, -3.976407e+04, 2.555865e+04, 1.082406e+04, 5.486112e+04, -3.893029e+04, 2.216912e+04, 1.175926e+04, 1.144987e+04, -2.896840e+04, 1.918876e+04, 1.262592e+04, -5.371250e+04, -2.059823e+04, 1.665072e+04, 1.343193e+04, 5.297801e+04, -2.371871e+04, 1.429575e+04, 1.417935e+04, -5.458191e+04, -1.220823e+04, 1.227995e+04, 1.485766e+04, 2.920703e+04, -1.633866e+04, 1.045753e+04, 1.548314e+04, -2.082029e+03, -1.050044e+04, 8.856110e+03, 1.604077e+04, -2.664664e+03, -8.621342e+03, 7.539708e+03, 1.654564e+04, -1.404636e+04, -6.326128e+03, 6.381937e+03, 1.699969e+04, 1.024075e+04, -7.296601e+03, 5.310162e+03, 1.740478e+04, -1.510660e+04, -3.541083e+03, 4.411345e+03, 1.775632e+04, 3.804952e+03, -4.830017e+03, 3.602141e+03, 1.806686e+04, -1.490810e+04, -2.032319e+03, 2.896991e+03, 1.832807e+04, -1.242364e+03, -3.160581e+03, 2.230378e+03, 1.855009e+04, -1.894988e+04, -6.198991e+02, 1.637798e+03, 1.872279e+04, -1.737924e+04, -5.863084e+02, 1.025930e+03, 1.885493e+04, -1.268231e+04, -3.096204e+01, 4.118873e+02, 1.893342e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.049934e+03, 5.631291e+01, 0, 0, 6.967623e+03, 1.862467e+01, 2.093108e-01, 5.236292e-04, -7.322636e+04, 2.442067e+03, 8.394707e-01, 2.618146e-03, -3.181040e+05, 1.374125e+04, 2.155526e+01, 7.330808e-02, -1.148779e+06, 5.153572e+04, 1.649367e+02, 7.624041e-01, -2.733073e+06, 1.274952e+05, 7.729699e+02, 4.857184e+00, -4.098947e+06, 2.168990e+05, 2.448323e+03, 2.118970e+01, -5.332313e+06, 2.988307e+05, 5.711927e+03, 6.820689e+01, -5.635984e+06, 3.325101e+05, 1.066895e+04, 1.751199e+02, -4.580008e+06, 3.018134e+05, 1.668111e+04, 3.755809e+02, -3.996023e+06, 2.577529e+05, 2.279537e+04, 6.973693e+02, -2.766915e+06, 1.817487e+05, 2.816438e+04, 1.159531e+03, -1.990806e+06, 1.182930e+05, 3.210268e+04, 1.762734e+03, -1.289423e+06, 6.188542e+04, 3.442340e+04, 2.495993e+03, -8.057612e+05, 2.131305e+04, 3.517139e+04, 3.336770e+03, -4.410684e+05, -6.496765e+03, 3.463019e+04, 4.257853e+03, -4.309360e+05, -1.502963e+04, 3.317952e+04, 5.231419e+03, -1.311448e+05, -3.210778e+04, 3.100030e+04, 6.234108e+03, -4.415939e+04, -3.380143e+04, 2.839568e+04, 7.235375e+03, -1.499349e+05, -2.599550e+04, 2.576558e+04, 8.220003e+03, 1.383474e+04, -3.242390e+04, 2.304396e+04, 9.179023e+03, -2.218020e+04, -2.541662e+04, 2.039304e+04, 1.009087e+04, -1.073837e+04, -2.250757e+04, 1.797035e+04, 1.095521e+04, -2.943186e+03, -1.953326e+04, 1.573007e+04, 1.176649e+04, -1.123711e+04, -1.592828e+04, 1.370204e+04, 1.252187e+04, 2.490499e+03, -1.435292e+04, 1.186123e+04, 1.322100e+04, -1.794959e+04, -1.053958e+04, 1.022032e+04, 1.386157e+04, 7.179634e+03, -1.085313e+04, 8.718724e+03, 1.444657e+04, 8.523870e+02, -8.182112e+03, 7.395488e+03, 1.497070e+04, -1.097305e+04, -5.802531e+03, 6.280139e+03, 1.544169e+04, -8.647890e+03, -5.258780e+03, 5.262032e+03, 1.586351e+04, -5.795295e+03, -4.678129e+03, 4.303340e+03, 1.623208e+04, -6.554213e+03, -3.732850e+03, 3.435184e+03, 1.654581e+04, -7.571927e+03, -2.901504e+03, 2.660403e+03, 1.680635e+04, -2.053198e+04, -1.047036e+03, 1.963335e+03, 1.701494e+04, -2.185000e+04, -5.709901e+02, 1.230253e+03, 1.717247e+04, -1.551733e+04, -6.146695e+00, 4.907671e+02, 1.726691e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.205704e+02, 2.019571e+01, 0, 0, 5.648551e+02, 8.455095e+01, 1.600871e-01, 5.236292e-04, -2.062497e+04, 1.347926e+03, 1.396682e+00, 5.759921e-03, -1.861333e+05, 9.330316e+03, 1.914727e+01, 9.425325e-02, -4.557963e+05, 2.826252e+04, 1.454540e+02, 9.482924e-01, -9.818830e+05, 6.498886e+04, 5.985040e+02, 5.287607e+00, -1.707438e+06, 1.141619e+05, 1.758923e+03, 2.087971e+01, -2.036629e+06, 1.496179e+05, 3.958518e+03, 6.352460e+01, -2.012618e+06, 1.637584e+05, 7.165573e+03, 1.556844e+02, -1.950650e+06, 1.617404e+05, 1.107139e+04, 3.226943e+02, -1.667168e+06, 1.387401e+05, 1.516993e+04, 5.881769e+02, -1.142383e+06, 1.009370e+05, 1.883831e+04, 9.663550e+02, -7.952061e+05, 6.944554e+04, 2.170582e+04, 1.458843e+03, -7.726009e+05, 5.004691e+04, 2.370696e+04, 2.060531e+03, -2.850905e+05, 1.452110e+04, 2.467497e+04, 2.760501e+03, -3.098623e+05, 7.430022e+03, 2.475227e+04, 3.532009e+03, -2.339934e+05, -3.779062e+03, 2.420063e+04, 4.361069e+03, 9.185211e+03, -1.890242e+04, 2.300010e+04, 5.223842e+03, -1.739850e+05, -8.944235e+03, 2.156361e+04, 6.095069e+03, -2.235243e+04, -1.943860e+04, 1.989104e+04, 6.972243e+03, 1.198136e+04, -1.908709e+04, 1.800541e+04, 7.826082e+03, -5.284415e+04, -1.280211e+04, 1.625202e+04, 8.649491e+03, 7.936083e+03, -1.590172e+04, 1.452061e+04, 9.442641e+03, -3.481822e+04, -1.076757e+04, 1.285434e+04, 1.018969e+04, 2.668691e+04, -1.397913e+04, 1.125258e+04, 1.089268e+04, -4.318571e+04, -6.253629e+03, 9.834934e+03, 1.153860e+04, 1.098736e+04, -1.042348e+04, 8.469408e+03, 1.214108e+04, -2.425142e+02, -7.313199e+03, 7.189537e+03, 1.267873e+04, -2.017386e+04, -4.486061e+03, 6.121964e+03, 1.316283e+04, -2.992189e+03, -5.709493e+03, 5.078553e+03, 1.359667e+04, -9.666249e+03, -3.987421e+03, 4.098707e+03, 1.396771e+04, -1.813279e+04, -2.576703e+03, 3.213557e+03, 1.428080e+04, -1.133652e+04, -2.823670e+03, 2.323008e+03, 1.453377e+04, -3.741587e+04, 7.057299e+02, 1.498721e+03, 1.471689e+04, -1.584264e+04, -3.098032e+02, 5.619166e+02, 1.483525e+04, }; static float solarDataset640[] = { -4.439940e+13, 4.727269e+08, 1.531960e+05, 2.789585e+03, 1.591240e+12, -3.752929e+08, 1.299147e+05, 2.792139e+03, -1.520825e+10, 9.464386e+06, 1.088507e+05, 2.805146e+03, 4.968166e+09, -3.484485e+06, 1.101562e+05, 2.841278e+03, -1.879797e+09, 4.089612e+06, 1.117743e+05, 2.911407e+03, 3.175884e+08, -3.936103e+05, 1.141396e+05, 3.031274e+03, -1.247720e+08, 7.638848e+05, 1.152491e+05, 3.210576e+03, -5.488648e+07, 3.411906e+05, 1.167998e+05, 3.465231e+03, 7.500485e+07, -2.624350e+05, 1.173902e+05, 3.807030e+03, -7.626345e+07, 6.188938e+05, 1.185754e+05, 4.246394e+03, -3.559987e+07, 1.218147e+05, 1.193649e+05, 4.806045e+03, -5.712451e+04, -2.445439e+05, 1.172780e+05, 5.484460e+03, -2.917238e+07, 2.280130e+04, 1.139230e+05, 6.275571e+03, -5.538333e+06, -3.268659e+05, 1.085716e+05, 7.182661e+03, -1.121999e+07, -2.401591e+05, 1.009303e+05, 8.172688e+03, -2.076868e+06, -3.706500e+05, 9.172349e+04, 9.227661e+03, -3.291261e+06, -2.970064e+05, 8.154785e+04, 1.030640e+04, -1.434784e+06, -2.886252e+05, 7.122383e+04, 1.138676e+04, -1.028562e+06, -2.454059e+05, 6.099909e+04, 1.243693e+04, 5.490447e+05, -2.301291e+05, 5.134306e+04, 1.343419e+04, -3.430376e+05, -1.558810e+05, 4.292772e+04, 1.435918e+04, 1.571421e+03, -1.323344e+05, 3.566474e+04, 1.521511e+04, 9.796970e+04, -1.046920e+05, 2.933950e+04, 1.599219e+04, 3.387552e+04, -7.798390e+04, 2.405845e+04, 1.669041e+04, 8.586974e+04, -6.144906e+04, 1.968644e+04, 1.731476e+04, 2.430737e+04, -4.445872e+04, 1.611932e+04, 1.786927e+04, 8.554925e+04, -3.643019e+04, 1.321141e+04, 1.836202e+04, -4.184780e+04, -2.225372e+04, 1.090368e+04, 1.879790e+04, 1.450911e+04, -2.047436e+04, 8.970817e+03, 1.918782e+04, 5.758854e+04, -1.762438e+04, 7.327434e+03, 1.952962e+04, -2.647884e+04, -8.760163e+03, 6.090933e+03, 1.982896e+04, 9.619644e+03, -9.392713e+03, 5.064150e+03, 2.009878e+04, 1.331023e+04, -7.397082e+03, 4.176136e+03, 2.033522e+04, -1.686056e+04, -3.825364e+03, 3.487137e+03, 2.054344e+04, 1.693753e+04, -5.541195e+03, 2.872701e+03, 2.072965e+04, -8.264414e+03, -2.280044e+03, 2.383048e+03, 2.088944e+04, 4.622434e+03, -2.963743e+03, 1.980519e+03, 2.103278e+04, -5.561131e+03, -1.469762e+03, 1.637947e+03, 2.115668e+04, -5.453383e+02, -1.717846e+03, 1.335926e+03, 2.126589e+04, -4.010140e+02, -1.347042e+03, 1.062944e+03, 2.135796e+04, 1.078165e+02, -1.080735e+03, 8.377248e+02, 2.143475e+04, -4.695232e+03, -3.873397e+02, 6.567006e+02, 2.149810e+04, -3.120412e+03, -5.195693e+02, 4.759587e+02, 2.155020e+04, -6.441655e+03, 1.058743e+00, 2.972071e+02, 2.158758e+04, -3.280148e+03, -4.465469e+01, 1.123506e+02, 2.161064e+04, -2.992526e+13, 3.093632e+08, 1.285107e+05, 1.370598e+03, 1.480405e+12, -3.114235e+08, 1.125000e+05, 1.372752e+03, -1.218458e+11, 6.632321e+07, 1.020083e+05, 1.384393e+03, 1.665317e+10, -1.847940e+07, 1.062419e+05, 1.420637e+03, -9.113149e+08, 3.008784e+06, 1.029925e+05, 1.485201e+03, 1.490734e+08, 6.212466e+05, 1.062972e+05, 1.595766e+03, -1.105384e+08, 1.142941e+06, 1.093467e+05, 1.764612e+03, -5.228906e+06, 5.746185e+05, 1.127616e+05, 2.008312e+03, -4.552848e+07, 6.442601e+05, 1.159764e+05, 2.341555e+03, -3.742689e+07, 4.419059e+05, 1.188852e+05, 2.782009e+03, -3.101838e+07, 2.582848e+05, 1.205636e+05, 3.343203e+03, -2.861615e+07, 1.118720e+05, 1.204816e+05, 4.033752e+03, -1.284625e+07, -1.383981e+05, 1.179923e+05, 4.854326e+03, -1.827905e+07, -1.249114e+05, 1.132356e+05, 5.792405e+03, -3.759817e+06, -3.523765e+05, 1.060046e+05, 6.833684e+03, -8.330140e+06, -2.577154e+05, 9.700446e+04, 7.940175e+03, -1.445189e+06, -3.560434e+05, 8.673825e+04, 9.089991e+03, -2.022213e+06, -2.868506e+05, 7.584981e+04, 1.023690e+04, -2.065185e+05, -2.739897e+05, 6.523903e+04, 1.135845e+04, -2.118780e+05, -2.174656e+05, 5.534385e+04, 1.242638e+04, -3.909280e+05, -1.684039e+05, 4.654358e+04, 1.342916e+04, 1.510131e+05, -1.471904e+05, 3.866829e+04, 1.435729e+04, 1.105359e+05, -1.114876e+05, 3.188896e+04, 1.519973e+04, 2.486681e+04, -8.288938e+04, 2.627788e+04, 1.596027e+04, 8.548810e+04, -6.590200e+04, 2.160359e+04, 1.664380e+04, 1.020428e+04, -4.763506e+04, 1.775888e+04, 1.725353e+04, 9.132896e+04, -3.989775e+04, 1.458947e+04, 1.779729e+04, -5.893551e+04, -2.401330e+04, 1.205272e+04, 1.827892e+04, 8.786788e+04, -2.590156e+04, 9.903800e+03, 1.871007e+04, -4.375724e+04, -1.286701e+04, 8.192812e+03, 1.908692e+04, 3.806013e+04, -1.494288e+04, 6.768657e+03, 1.942561e+04, -2.022679e+04, -7.996085e+03, 5.595118e+03, 1.972091e+04, 4.406976e+04, -1.028506e+04, 4.614651e+03, 1.998424e+04, -3.557882e+04, -2.482117e+03, 3.885495e+03, 2.021282e+04, 1.494002e+04, -6.049385e+03, 3.237819e+03, 2.042301e+04, -4.199329e+03, -3.113389e+03, 2.662895e+03, 2.060288e+04, 3.034471e+03, -3.103970e+03, 2.203542e+03, 2.076205e+04, 1.633791e+03, -2.268264e+03, 1.819033e+03, 2.090013e+04, -1.012340e+04, -8.623465e+02, 1.515031e+03, 2.102106e+04, 2.750467e+03, -2.003038e+03, 1.204360e+03, 2.112756e+04, -6.190024e-03, -1.186111e+03, 9.348330e+02, 2.121315e+04, -5.805871e+03, -3.823047e+02, 7.336037e+02, 2.128391e+04, -3.542666e+03, -5.948154e+02, 5.273264e+02, 2.134212e+04, -5.934580e+03, -1.228610e+02, 3.234636e+02, 2.138330e+04, -4.084604e+03, -1.983933e+00, 1.289217e+02, 2.140821e+04, -3.727579e+12, 5.679231e+08, -1.625664e+04, 4.250653e+02, -4.419365e+12, 1.046109e+09, 0, 4.249347e+02, 3.326869e+10, -2.023689e+07, 5.941925e+04, 4.324018e+02, 3.471040e+09, -1.203176e+06, 5.686938e+04, 4.508607e+02, -6.372727e+08, 3.160899e+06, 5.957054e+04, 4.875431e+02, 2.755881e+08, 1.055176e+06, 6.410412e+04, 5.529359e+02, -1.275647e+08, 1.970311e+06, 6.944887e+04, 6.571524e+02, 5.075274e+07, 1.126893e+06, 7.624159e+04, 8.172947e+02, -8.482724e+07, 1.658999e+06, 8.409947e+04, 1.050219e+03, -6.311669e+07, 1.260619e+06, 9.295005e+04, 1.383576e+03, -4.552108e+07, 8.872372e+05, 1.005958e+05, 1.838863e+03, -3.875198e+07, 6.047687e+05, 1.062746e+05, 2.433263e+03, -1.845368e+07, 2.163822e+05, 1.091074e+05, 3.176447e+03, -2.407756e+07, 1.539447e+05, 1.089878e+05, 4.062922e+03, -9.843639e+06, -1.515457e+05, 1.054688e+05, 5.084079e+03, -6.115161e+06, -2.330786e+05, 9.867827e+04, 6.200673e+03, -4.041083e+06, -2.626724e+05, 9.005089e+04, 7.379350e+03, -2.210499e+06, -2.717189e+05, 8.024778e+04, 8.584178e+03, -7.206211e+05, -2.613685e+05, 6.997467e+04, 9.778451e+03, -3.314310e+05, -2.216301e+05, 6.004300e+04, 1.093132e+04, -3.603027e+05, -1.775358e+05, 5.094016e+04, 1.202401e+04, 1.605319e+04, -1.514987e+05, 4.271129e+04, 1.304370e+04, 2.002792e+05, -1.228584e+05, 3.549450e+04, 1.397850e+04, -8.648454e+04, -8.570485e+04, 2.947253e+04, 1.482726e+04, 1.357791e+05, -7.475766e+04, 2.436487e+04, 1.559714e+04, -3.989941e+03, -5.194180e+04, 2.011571e+04, 1.628557e+04, 8.306635e+04, -4.386703e+04, 1.660847e+04, 1.690318e+04, -2.096461e+04, -2.912937e+04, 1.375069e+04, 1.745251e+04, 5.301057e+04, -2.639084e+04, 1.137582e+04, 1.794452e+04, -3.157995e+04, -1.607394e+04, 9.439187e+03, 1.837976e+04, 5.385344e+04, -1.741312e+04, 7.800361e+03, 1.876916e+04, -2.015355e+04, -8.869094e+03, 6.498800e+03, 1.911013e+04, -2.198646e+03, -8.557864e+03, 5.429310e+03, 1.941755e+04, 2.183501e+04, -8.210271e+03, 4.474652e+03, 1.968824e+04, -1.617257e+04, -3.638040e+03, 3.742270e+03, 1.992456e+04, 1.241488e+04, -5.232775e+03, 3.110539e+03, 2.013736e+04, -1.201730e+04, -2.114134e+03, 2.586648e+03, 2.032131e+04, 4.745978e+03, -3.261955e+03, 2.124178e+03, 2.048556e+04, 1.127970e+03, -2.123757e+03, 1.725024e+03, 2.062462e+04, -7.597785e+03, -9.417226e+02, 1.419309e+03, 2.074488e+04, 1.883744e+03, -1.753948e+03, 1.118928e+03, 2.084928e+04, -6.322678e+03, -5.176974e+02, 8.620266e+02, 2.093272e+04, -1.605836e+03, -9.285398e+02, 6.193314e+02, 2.100093e+04, -1.097960e+04, 3.171899e+02, 4.038220e+02, 2.104937e+04, -4.141973e+03, -9.836002e+01, 1.504665e+02, 2.108164e+04, -2.330422e+13, 2.884024e+08, 3.068028e+04, 6.138150e+01, 4.881998e+11, -1.148322e+08, 1.984912e+04, 6.187669e+01, 1.916792e+09, 9.729664e+05, 1.346125e+04, 6.345753e+01, -6.675440e+08, 2.022162e+06, 1.471542e+04, 6.803805e+01, 3.159170e+08, 5.956514e+05, 1.648024e+04, 7.807293e+01, 1.478614e+08, 9.030786e+05, 1.878080e+04, 9.642790e+01, -3.518216e+07, 1.443802e+06, 2.270551e+04, 1.286811e+02, 1.119347e+07, 1.312378e+06, 2.852122e+04, 1.849385e+02, -7.701323e+07, 1.801352e+06, 3.645263e+04, 2.794408e+02, -4.292657e+07, 1.527104e+06, 4.669619e+04, 4.369697e+02, -5.878099e+07, 1.547497e+06, 5.815348e+04, 6.840577e+02, -4.645158e+07, 1.228475e+06, 7.007176e+04, 1.055326e+03, -3.318499e+07, 8.600360e+05, 8.035939e+04, 1.577501e+03, -2.625219e+07, 5.584589e+05, 8.775849e+04, 2.265846e+03, -1.490142e+07, 2.204949e+05, 9.128794e+04, 3.120972e+03, -9.255229e+06, 2.252877e+04, 9.079563e+04, 4.120827e+03, -7.977564e+06, -6.768208e+04, 8.706674e+04, 5.234990e+03, -1.201566e+06, -2.257152e+05, 8.041358e+04, 6.425469e+03, -2.557683e+06, -1.738737e+05, 7.235760e+04, 7.637924e+03, -6.451356e+05, -2.017795e+05, 6.379658e+04, 8.850205e+03, -3.054659e+05, -1.757830e+05, 5.511053e+04, 1.002201e+04, 4.282739e+03, -1.507765e+05, 4.703559e+04, 1.113375e+04, -6.875119e+04, -1.179384e+05, 3.983315e+04, 1.217219e+04, -6.539296e+04, -9.429366e+04, 3.351548e+04, 1.313309e+04, 1.390880e+05, -8.139794e+04, 2.796880e+04, 1.401195e+04, 1.433916e+04, -5.814147e+04, 2.331691e+04, 1.480596e+04, 4.800799e+04, -4.699949e+04, 1.945486e+04, 1.552491e+04, 3.355324e+04, -3.590662e+04, 1.623079e+04, 1.617181e+04, -4.753516e+04, -2.457913e+04, 1.357598e+04, 1.675372e+04, 4.184174e+04, -2.433031e+04, 1.125925e+04, 1.727713e+04, 1.681958e+04, -1.719019e+04, 9.323416e+03, 1.773841e+04, 1.359243e+04, -1.318457e+04, 7.786144e+03, 1.814905e+04, -1.223584e+04, -8.858780e+03, 6.540344e+03, 1.851573e+04, 6.675612e+03, -8.506817e+03, 5.462955e+03, 1.884458e+04, 9.691761e+03, -6.794523e+03, 4.542950e+03, 1.913430e+04, -1.311304e+04, -3.705444e+03, 3.816631e+03, 1.939046e+04, 3.177047e+03, -4.478421e+03, 3.166507e+03, 1.961984e+04, 1.744567e+02, -3.216510e+03, 2.594630e+03, 1.981779e+04, -3.774980e+03, -2.236340e+03, 2.129548e+03, 1.998954e+04, 7.002038e+02, -2.227548e+03, 1.720140e+03, 2.013795e+04, -5.785630e+03, -1.144891e+03, 1.374334e+03, 2.026261e+04, -1.111106e+03, -1.431800e+03, 1.055204e+03, 2.036742e+04, -9.405081e+03, -2.669856e+02, 7.737057e+02, 2.044926e+04, -7.953502e+03, -3.131021e+02, 4.776272e+02, 2.051154e+04, -5.955234e+03, -2.333631e+00, 1.878496e+02, 2.054783e+04, 5.900736e+12, -6.184322e+07, -3.127993e+03, 4.662247e+00, -2.586883e+11, 5.655632e+07, 0, 4.620175e+00, 6.674828e+09, -3.908526e+06, 2.349221e+03, 4.989151e+00, 1.823458e+08, 2.419007e+05, 1.936986e+03, 5.573806e+00, -9.320896e+07, 5.604882e+05, 2.468082e+03, 6.954925e+00, 7.579802e+07, 2.506737e+05, 3.337623e+03, 1.006148e+01, -1.611317e+07, 6.330473e+05, 4.683591e+03, 1.620640e+01, -1.376354e+07, 7.637402e+05, 7.223657e+03, 2.932462e+01, -2.583591e+07, 1.010277e+06, 1.132308e+04, 5.650986e+01, -4.465643e+07, 1.303261e+06, 1.779668e+04, 1.116488e+02, -4.722198e+07, 1.403819e+06, 2.704938e+04, 2.186730e+02, -4.285916e+07, 1.335126e+06, 3.845701e+04, 4.099392e+02, -3.417982e+07, 1.121722e+06, 5.070906e+04, 7.219074e+02, -2.901563e+07, 8.791541e+05, 6.214431e+04, 1.187121e+03, -1.838120e+07, 5.316987e+05, 7.098441e+04, 1.826925e+03, -1.217421e+07, 2.767583e+05, 7.602698e+04, 2.638278e+03, -7.803981e+06, 8.631945e+04, 7.726482e+04, 3.602555e+03, -4.483355e+06, -4.639403e+04, 7.505263e+04, 4.686021e+03, -2.447868e+06, -1.176936e+05, 7.020737e+04, 5.845505e+03, -1.057698e+06, -1.499728e+05, 6.373873e+04, 7.037935e+03, -5.877838e+05, -1.450739e+05, 5.661180e+04, 8.225507e+03, -3.775252e+05, -1.299298e+05, 4.947172e+04, 9.381489e+03, -4.735522e+04, -1.179415e+05, 4.261136e+04, 1.048487e+04, -3.826733e+04, -9.552913e+04, 3.633754e+04, 1.151890e+04, 7.634655e+04, -8.044760e+04, 3.078666e+04, 1.247799e+04, -1.166207e+04, -6.027152e+04, 2.601237e+04, 1.335852e+04, -3.488352e+04, -4.748362e+04, 2.191882e+04, 1.416472e+04, 1.451432e+05, -4.532720e+04, 1.833155e+04, 1.489651e+04, -1.018718e+05, -2.331123e+04, 1.545194e+04, 1.555285e+04, 6.092841e+04, -2.791611e+04, 1.295407e+04, 1.615327e+04, 9.914125e+03, -1.852473e+04, 1.081145e+04, 1.668531e+04, -1.018421e+04, -1.364660e+04, 9.097815e+03, 1.716368e+04, 2.677632e+04, -1.320567e+04, 7.616752e+03, 1.759324e+04, -3.190707e+04, -6.537187e+03, 6.413697e+03, 1.797428e+04, 3.224420e+04, -1.002234e+04, 5.332416e+03, 1.831827e+04, -1.790675e+04, -3.819177e+03, 4.465077e+03, 1.861606e+04, 5.741706e+03, -5.269812e+03, 3.739037e+03, 1.888589e+04, -7.215146e+03, -3.071621e+03, 3.094632e+03, 1.912037e+04, -1.751587e+03, -3.077939e+03, 2.533371e+03, 1.932641e+04, 1.684196e+03, -2.713112e+03, 2.030604e+03, 1.950173e+04, -5.727454e+03, -1.411693e+03, 1.625658e+03, 1.964880e+04, -4.801342e+03, -1.316339e+03, 1.262519e+03, 1.977305e+04, -6.741413e+03, -8.448004e+02, 9.137641e+02, 1.987167e+04, -1.490630e+04, 2.471177e+02, 5.794638e+02, 1.994416e+04, -5.125526e+03, -1.870754e+02, 1.995830e+02, 1.998926e+04, -2.869444e+12, 4.196504e+07, 1.111129e+03, 1.914998e-01, 7.156578e+09, -1.295320e+06, 0, 2.084253e-01, -1.403689e+09, 9.962077e+05, 0, 2.021387e-01, -8.216375e+07, 1.203012e+05, 2.008386e+02, 2.596854e-01, 6.555093e+07, -5.683459e+04, 2.540250e+02, 4.153999e-01, -1.211732e+07, 1.476175e+05, 3.519336e+02, 6.958794e-01, 6.522379e+05, 1.744630e+05, 7.256024e+02, 1.564399e+00, -1.052628e+07, 3.516827e+05, 1.498850e+03, 3.995866e+00, -2.574797e+07, 6.281950e+05, 3.279889e+03, 1.108668e+01, -3.086743e+07, 8.810812e+05, 6.898743e+03, 3.079762e+01, -3.884285e+07, 1.142616e+06, 1.310979e+04, 7.910539e+01, -3.943960e+07, 1.250215e+06, 2.235506e+04, 1.838892e+02, -3.665357e+07, 1.197647e+06, 3.392539e+04, 3.827845e+02, -2.694963e+07, 9.520602e+05, 4.610324e+04, 7.159656e+02, -2.036503e+07, 6.966329e+05, 5.686927e+04, 1.212730e+03, -1.444636e+07, 4.337031e+05, 6.479572e+04, 1.887513e+03, -7.699672e+06, 1.790196e+05, 6.888180e+04, 2.732083e+03, -5.257205e+06, 4.882563e+04, 6.934273e+04, 3.716165e+03, -3.250320e+06, -4.591330e+04, 6.693171e+04, 4.806015e+03, -1.348332e+06, -1.107657e+05, 6.225009e+04, 5.958500e+03, -6.591738e+05, -1.229398e+05, 5.632815e+04, 7.129749e+03, -5.308371e+05, -1.127866e+05, 5.004913e+04, 8.289289e+03, -2.262225e+05, -1.068280e+05, 4.374560e+04, 9.414179e+03, 3.731957e+04, -9.700161e+04, 3.768587e+04, 1.048232e+04, -1.736652e+04, -7.613110e+04, 3.223589e+04, 1.148048e+04, -2.414547e+04, -6.138152e+04, 2.745864e+04, 1.240735e+04, 6.789920e+04, -5.299159e+04, 2.324807e+04, 1.326047e+04, -1.736037e+04, -3.809564e+04, 1.966746e+04, 1.403819e+04, 2.647414e+04, -3.277573e+04, 1.660775e+04, 1.474812e+04, 8.534694e+03, -2.499570e+04, 1.399418e+04, 1.538991e+04, -7.165778e+03, -1.917919e+04, 1.179604e+04, 1.596990e+04, 1.820885e+04, -1.685831e+04, 9.900832e+03, 1.649223e+04, 5.374457e+03, -1.240641e+04, 8.314451e+03, 1.695838e+04, -6.216827e+03, -9.208817e+03, 7.007123e+03, 1.737642e+04, 6.178700e+03, -8.349800e+03, 5.875342e+03, 1.775088e+04, -5.600157e+03, -5.764635e+03, 4.917613e+03, 1.808234e+04, 6.164147e+03, -5.602643e+03, 4.094812e+03, 1.837682e+04, -9.844895e+03, -3.124692e+03, 3.410559e+03, 1.863437e+04, 1.870561e+03, -3.694799e+03, 2.799852e+03, 1.886209e+04, -1.653556e+03, -2.538690e+03, 2.266366e+03, 1.905585e+04, -7.849600e+03, -1.504537e+03, 1.824372e+03, 1.922132e+04, -6.752870e+03, -1.437372e+03, 1.399671e+03, 1.936046e+04, -3.301713e+03, -1.417094e+03, 9.829110e+02, 1.946895e+04, -1.406390e+04, 1.486421e+02, 6.317347e+02, 1.954571e+04, -8.038091e+03, -1.892693e+01, 2.567819e+02, 1.959578e+04, 8.092438e+10, -1.162467e+06, -3.206142e+01, 9.671708e-04, -5.505060e+08, 9.964000e+04, 0, 4.835854e-04, 2.752931e+07, -1.352454e+04, 0, 9.671708e-04, -1.833317e+07, 2.120320e+04, 0, 4.835854e-04, 2.571019e+06, -3.649190e+03, 4.673637e+00, 4.352269e-03, -7.491211e+04, 4.848017e+03, 5.527414e+00, 8.220952e-03, -7.418260e+05, 1.692347e+04, 2.018402e+01, 2.853154e-02, -2.336180e+06, 5.229333e+04, 8.361598e+01, 1.460428e-01, -4.201515e+06, 1.305820e+05, 3.288177e+02, 7.756710e-01, -1.289169e+07, 3.289640e+05, 1.129365e+03, 3.612867e+00, -1.762035e+07, 5.566023e+05, 3.358858e+03, 1.475322e+01, -2.747414e+07, 8.490401e+05, 7.989587e+03, 4.876524e+01, -2.619987e+07, 9.449800e+05, 1.575022e+04, 1.343985e+02, -2.483176e+07, 9.407079e+05, 2.589242e+04, 3.096513e+02, -2.096394e+07, 7.980703e+05, 3.700925e+04, 6.166125e+02, -1.260854e+07, 5.301678e+05, 4.692981e+04, 1.086607e+03, -1.011947e+07, 3.644354e+05, 5.426536e+04, 1.727560e+03, -6.162520e+06, 1.740138e+05, 5.850899e+04, 2.535811e+03, -3.372106e+06, 4.020494e+04, 5.938275e+04, 3.481855e+03, -2.254455e+06, -2.599647e+04, 5.763576e+04, 4.527013e+03, -9.857144e+05, -7.745357e+04, 5.399678e+04, 5.633404e+03, -5.863116e+05, -8.788475e+04, 4.923235e+04, 6.760406e+03, -1.620644e+05, -9.249139e+04, 4.402444e+04, 7.879244e+03, -2.699903e+05, -7.601326e+04, 3.884746e+04, 8.965668e+03, -1.358876e+05, -7.057037e+04, 3.384431e+04, 1.000696e+04, 1.675314e+05, -6.959774e+04, 2.906964e+04, 1.098559e+04, -9.302058e+04, -4.442220e+04, 2.495681e+04, 1.189088e+04, 7.251168e+03, -4.169873e+04, 2.136185e+04, 1.273426e+04, 5.481866e+04, -3.555078e+04, 1.813324e+04, 1.350642e+04, -3.479656e+04, -2.368568e+04, 1.543658e+04, 1.420950e+04, 1.551094e+04, -2.236704e+04, 1.309303e+04, 1.485312e+04, 1.826623e+04, -1.782883e+04, 1.104855e+04, 1.543299e+04, 1.003366e+04, -1.355278e+04, 9.363013e+03, 1.595548e+04, -3.906669e+04, -7.936198e+03, 7.972150e+03, 1.642815e+04, 3.712882e+04, -1.211740e+04, 6.656119e+03, 1.685648e+04, -2.359586e+04, -4.682025e+03, 5.586378e+03, 1.722895e+04, 1.313605e+04, -7.041172e+03, 4.675363e+03, 1.756662e+04, -8.595405e+03, -3.626245e+03, 3.892172e+03, 1.785962e+04, -4.083225e+03, -3.541047e+03, 3.228339e+03, 1.812020e+04, -2.079108e+03, -3.062724e+03, 2.613468e+03, 1.834503e+04, -4.585763e+03, -2.207125e+03, 2.078593e+03, 1.853488e+04, -8.379371e+03, -1.445921e+03, 1.605151e+03, 1.869252e+04, -3.288252e+03, -1.643252e+03, 1.148159e+03, 1.881809e+04, -1.880134e+04, 4.395417e+02, 7.550833e+02, 1.890833e+04, -9.040297e+03, -8.067476e+01, 3.009619e+02, 1.896881e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.709387e+03, 1.221581e+02, 0, 0, -5.051096e+04, 1.037139e+03, 3.952580e-01, 4.835854e-04, -1.390577e+05, 5.605787e+03, 5.152017e+00, 9.188123e-03, -1.185086e+06, 3.357945e+04, 4.125296e+01, 9.961860e-02, -3.324630e+06, 1.101904e+05, 2.773980e+02, 9.043047e-01, -7.853728e+06, 2.688967e+05, 1.210126e+03, 5.456778e+00, -1.227331e+07, 4.602241e+05, 3.787044e+03, 2.381416e+01, -1.502364e+07, 6.070524e+05, 8.821902e+03, 7.802554e+01, -1.336220e+07, 6.235281e+05, 1.626265e+04, 2.025851e+02, -1.337434e+07, 5.982898e+05, 2.508429e+04, 4.360495e+02, -8.551671e+06, 4.261216e+05, 3.375827e+04, 8.145489e+02, -6.484517e+06, 2.997790e+05, 4.067227e+04, 1.350606e+03, -3.892800e+06, 1.628204e+05, 4.528823e+04, 2.044370e+03, -3.174152e+06, 8.617744e+04, 4.739307e+04, 2.875549e+03, -7.858401e+05, -1.795473e+04, 4.709930e+04, 3.816879e+03, -1.506677e+06, -1.051765e+04, 4.520483e+04, 4.824117e+03, -1.654844e+05, -6.662056e+04, 4.211810e+04, 5.878308e+03, -3.325870e+05, -5.482462e+04, 3.828890e+04, 6.932492e+03, -1.669931e+05, -5.691599e+04, 3.434296e+04, 7.973661e+03, 3.176809e+04, -5.704259e+04, 3.032616e+04, 8.979996e+03, -1.281974e+05, -4.107245e+04, 2.659716e+04, 9.936586e+03, 5.251609e+04, -4.338252e+04, 2.310631e+04, 1.084227e+04, -3.310454e+04, -3.100850e+04, 1.995372e+04, 1.168280e+04, 1.373580e+04, -2.826584e+04, 1.717322e+04, 1.246385e+04, 1.486695e+04, -2.286523e+04, 1.471232e+04, 1.318078e+04, -2.699775e+04, -1.623475e+04, 1.261542e+04, 1.383733e+04, 3.280403e+04, -1.719400e+04, 1.073590e+04, 1.443831e+04, -2.669848e+04, -9.678436e+03, 9.151064e+03, 1.497882e+04, 1.838055e+04, -1.142924e+04, 7.757786e+03, 1.547212e+04, -1.527434e+04, -6.522392e+03, 6.559644e+03, 1.591064e+04, 6.134069e+03, -7.241503e+03, 5.514782e+03, 1.630624e+04, -6.323445e+03, -4.711065e+03, 4.604267e+03, 1.665383e+04, -4.073073e+03, -4.157336e+03, 3.818693e+03, 1.696133e+04, -3.689038e+03, -3.435628e+03, 3.109516e+03, 1.722780e+04, -5.989523e+03, -2.575961e+03, 2.483016e+03, 1.745440e+04, -7.028686e+03, -2.007072e+03, 1.916696e+03, 1.764283e+04, -1.237906e+04, -1.066394e+03, 1.391888e+03, 1.779266e+04, -1.530568e+04, -3.931004e+02, 8.686103e+02, 1.790328e+04, -1.075759e+04, -3.241883e+01, 3.519534e+02, 1.797018e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.054978e+04, 7.410320e+02, 0, 0, -9.722180e+04, 4.326381e+03, 4.923375e+00, 1.305681e-02, -3.957187e+05, 2.108857e+04, 4.479837e+01, 1.639355e-01, -2.217090e+06, 8.601666e+04, 2.778367e+02, 1.331311e+00, -3.595510e+06, 1.730620e+05, 1.233921e+03, 8.028002e+00, -5.986757e+06, 2.900617e+05, 3.538550e+03, 3.203512e+01, -6.769567e+06, 3.551039e+05, 7.723701e+03, 9.713732e+01, -5.667593e+06, 3.457250e+05, 1.341347e+04, 2.349867e+02, -5.458172e+06, 3.222378e+05, 1.977905e+04, 4.766324e+02, -3.782412e+06, 2.373311e+05, 2.587928e+04, 8.491315e+02, -2.850464e+06, 1.657680e+05, 3.072606e+04, 1.360673e+03, -2.076195e+06, 9.869617e+04, 3.393877e+04, 2.007443e+03, -8.459967e+05, 2.822829e+04, 3.528651e+04, 2.770476e+03, -7.874505e+05, 9.303483e+03, 3.518552e+04, 3.618710e+03, -4.961071e+05, -1.453427e+04, 3.405307e+04, 4.532258e+03, -2.021158e+05, -3.136214e+04, 3.200853e+04, 5.481500e+03, -1.413239e+05, -3.330948e+04, 2.947684e+04, 6.438940e+03, -1.032936e+05, -3.292416e+04, 2.675684e+04, 7.387225e+03, -2.743197e+04, -3.315766e+04, 2.395645e+04, 8.310655e+03, -4.213430e+04, -2.797667e+04, 2.123679e+04, 9.195288e+03, 1.688152e+04, -2.708199e+04, 1.866320e+04, 1.003492e+04, -3.945755e+04, -1.950281e+04, 1.632798e+04, 1.082159e+04, 3.775898e+04, -2.118019e+04, 1.417740e+04, 1.155761e+04, -3.951332e+04, -1.232675e+04, 1.230190e+04, 1.223448e+04, 1.628466e+04, -1.456907e+04, 1.060143e+04, 1.286326e+04, 2.475050e+03, -1.062776e+04, 9.074832e+03, 1.343267e+04, -2.958304e+04, -6.604437e+03, 7.794557e+03, 1.395159e+04, 2.382873e+04, -9.973204e+03, 6.556652e+03, 1.442337e+04, -1.898300e+04, -4.141927e+03, 5.521709e+03, 1.483557e+04, -6.649303e+02, -5.415087e+03, 4.618044e+03, 1.520793e+04, -5.006126e+03, -3.945080e+03, 3.776118e+03, 1.552981e+04, -8.901394e+03, -2.910036e+03, 3.041676e+03, 1.580619e+04, -1.200711e+04, -2.169750e+03, 2.355820e+03, 1.603784e+04, -4.968676e+03, -2.395668e+03, 1.683550e+03, 1.622197e+04, -2.774133e+04, 6.568597e+02, 1.105917e+03, 1.635428e+04, -1.302099e+04, -1.357563e+02, 4.374897e+02, 1.644280e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.717292e+02, 3.525304e+01, 0, 0, -5.304463e+03, 3.218125e+02, 3.073832e-01, 9.671708e-04, -1.934360e+04, 2.085146e+03, 3.966715e+00, 1.644190e-02, -3.180464e+05, 1.510232e+04, 3.388872e+01, 1.745743e-01, -6.480828e+05, 4.043076e+04, 2.338605e+02, 1.570202e+00, -1.516090e+06, 9.036847e+04, 8.833714e+02, 8.063303e+00, -2.034832e+06, 1.366083e+05, 2.427098e+03, 3.009062e+01, -2.361191e+06, 1.706568e+05, 5.064127e+03, 8.568311e+01, -2.387942e+06, 1.804522e+05, 8.693407e+03, 1.993470e+02, -2.155769e+06, 1.647391e+05, 1.283741e+04, 3.965541e+02, -1.303862e+06, 1.206826e+05, 1.681586e+04, 6.963707e+02, -1.382930e+06, 1.028904e+05, 2.021420e+04, 1.105526e+03, -7.363076e+05, 5.682299e+04, 2.276260e+04, 1.628739e+03, -7.293309e+05, 3.878596e+04, 2.422386e+04, 2.250501e+03, -1.958146e+05, 3.375079e+03, 2.465448e+04, 2.957056e+03, -2.527096e+05, 3.571719e+02, 2.429786e+04, 3.719856e+03, -1.824193e+05, -8.454398e+03, 2.346440e+04, 4.527808e+03, -1.207450e+05, -1.454655e+04, 2.212836e+04, 5.360145e+03, -1.873828e+04, -2.014348e+04, 2.043631e+04, 6.196165e+03, -6.547356e+04, -1.592640e+04, 1.864471e+04, 7.017728e+03, 1.538025e+04, -1.940620e+04, 1.681319e+04, 7.818656e+03, -3.081477e+04, -1.380759e+04, 1.505269e+04, 8.584346e+03, -3.688264e+04, -1.237202e+04, 1.339212e+04, 9.316279e+03, 3.700757e+04, -1.579093e+04, 1.171025e+04, 1.000491e+04, -3.096457e+04, -7.862788e+03, 1.025124e+04, 1.063862e+04, -3.624742e+03, -9.431423e+03, 8.931243e+03, 1.123263e+04, -7.771562e+02, -8.102068e+03, 7.655642e+03, 1.177367e+04, -9.869735e+03, -6.022230e+03, 6.528116e+03, 1.226242e+04, -4.868512e+03, -5.631664e+03, 5.495559e+03, 1.270154e+04, -9.937763e+03, -4.263030e+03, 4.546326e+03, 1.308752e+04, -4.005424e+03, -4.161767e+03, 3.664244e+03, 1.342139e+04, -1.613158e+04, -2.200682e+03, 2.871716e+03, 1.369982e+04, -1.400113e+04, -2.118312e+03, 2.095777e+03, 1.392675e+04, -2.681191e+04, -1.270264e+02, 1.333515e+03, 1.409262e+04, -1.703298e+04, -1.198066e+01, 5.383685e+02, 1.419677e+04, }; static float solarDataset680[] = { -352468042275216, 4.565228e+09, 3.493754e+05, 4.079590e+03, 5.683662e+12, -1.328402e+09, 1.925649e+05, 4.085164e+03, -7.764229e+10, 4.963131e+07, 1.202445e+05, 4.099044e+03, 5.563528e+09, -4.324424e+06, 1.277691e+05, 4.141022e+03, -3.769498e+09, 6.005153e+06, 1.290424e+05, 4.222198e+03, 9.852032e+08, -2.967738e+06, 1.291679e+05, 4.360144e+03, -3.875109e+07, 1.836524e+05, 1.271300e+05, 4.559262e+03, -1.192922e+08, 3.590793e+05, 1.273769e+05, 4.838049e+03, 5.235498e+06, -2.993428e+05, 1.264319e+05, 5.209221e+03, -3.536095e+07, -5.551723e+04, 1.244122e+05, 5.678238e+03, -3.682262e+07, -1.175068e+05, 1.215785e+05, 6.254607e+03, -1.683494e+07, -3.365406e+05, 1.166413e+05, 6.937634e+03, -6.725039e+06, -4.184973e+05, 1.096698e+05, 7.714702e+03, -1.347547e+07, -3.110082e+05, 1.015845e+05, 8.570426e+03, -5.796493e+06, -3.962767e+05, 9.212522e+04, 9.489327e+03, -1.470687e+06, -3.999603e+05, 8.144721e+04, 1.043704e+04, -3.891564e+06, -2.924573e+05, 7.082390e+04, 1.138470e+04, 1.268637e+06, -3.320372e+05, 6.027083e+04, 1.231325e+04, -1.553830e+06, -2.010288e+05, 5.070597e+04, 1.318976e+04, 6.401092e+05, -2.083886e+05, 4.212731e+04, 1.401579e+04, -4.089157e+05, -1.325947e+05, 3.467286e+04, 1.476862e+04, 4.689382e+05, -1.255255e+05, 2.832884e+04, 1.545545e+04, -2.414026e+05, -7.345191e+04, 2.313068e+04, 1.606742e+04, 2.093406e+05, -7.131366e+04, 1.878759e+04, 1.661838e+04, 8.730097e+04, -4.851327e+04, 1.522608e+04, 1.710171e+04, -2.825615e+04, -3.260464e+04, 1.246629e+04, 1.753026e+04, 9.246158e+03, -2.696444e+04, 1.017736e+04, 1.791157e+04, 5.845154e+04, -2.256224e+04, 8.255250e+03, 1.824608e+04, -1.623206e+03, -1.409944e+04, 6.758571e+03, 1.853795e+04, 1.397299e+04, -1.179690e+04, 5.565383e+03, 1.879686e+04, 9.810044e+03, -8.809613e+03, 4.588390e+03, 1.902473e+04, -1.056924e+04, -5.731825e+03, 3.808836e+03, 1.922618e+04, 1.867460e+04, -6.355988e+03, 3.137056e+03, 1.940511e+04, -2.207924e+04, -2.223620e+03, 2.609823e+03, 1.956056e+04, 2.317944e+04, -5.069146e+03, 2.128577e+03, 1.970022e+04, -1.315186e+04, -9.880525e+02, 1.767994e+03, 1.981745e+04, 4.416039e+03, -2.401660e+03, 1.471594e+03, 1.992484e+04, 2.469023e+02, -1.450777e+03, 1.203539e+03, 2.001628e+04, -7.126793e+03, -5.842061e+02, 9.964367e+02, 2.009623e+04, 5.680761e+03, -1.675038e+03, 7.812342e+02, 2.016597e+04, -3.303117e+03, -3.317838e+02, 6.218765e+02, 2.022109e+04, -3.628281e+03, -3.367296e+02, 4.942834e+02, 2.026943e+04, -1.932363e+03, -4.513063e+02, 3.479496e+02, 2.030822e+04, -2.905107e+03, -1.741303e+02, 2.130510e+02, 2.033521e+04, -2.186812e+03, -6.044464e+01, 9.550916e+01, 2.035167e+04, 2.566491e+12, -2.160143e+07, 1.253489e+05, 2.094745e+03, 1.072830e+11, 3.373914e+06, 1.268921e+05, 2.096912e+03, -6.278151e+10, 3.625360e+07, 1.323924e+05, 2.112461e+03, 5.355040e+09, -6.437409e+06, 1.359364e+05, 2.157505e+03, 6.328454e+08, -3.831994e+05, 1.342600e+05, 2.242976e+03, -3.525021e+08, 1.289271e+06, 1.355533e+05, 2.384464e+03, 7.237564e+06, 1.315110e+05, 1.369959e+05, 2.598910e+03, -8.490662e+07, 3.829063e+05, 1.376758e+05, 2.899528e+03, -3.478052e+07, 3.597080e+04, 1.377450e+05, 3.301754e+03, -5.179258e+07, 5.107895e+04, 1.365542e+05, 3.815687e+03, -2.559535e+07, -2.211796e+05, 1.336407e+05, 4.449428e+03, -2.591427e+07, -2.568699e+05, 1.286169e+05, 5.199989e+03, -1.373490e+07, -3.999240e+05, 1.214603e+05, 6.059833e+03, -1.260242e+07, -3.952445e+05, 1.123008e+05, 7.008387e+03, -2.957989e+06, -4.813305e+05, 1.014858e+05, 8.021575e+03, -5.251237e+06, -3.746148e+05, 8.996501e+04, 9.064690e+03, -4.198038e+05, -3.933644e+05, 7.821981e+04, 1.011487e+04, -1.996456e+06, -2.874528e+05, 6.689029e+04, 1.113727e+04, 4.266078e+05, -2.786719e+05, 5.627982e+04, 1.211684e+04, -3.919704e+05, -1.965459e+05, 4.681414e+04, 1.302821e+04, 1.091816e+05, -1.649710e+05, 3.862777e+04, 1.386995e+04, 3.750077e+05, -1.318222e+05, 3.161062e+04, 1.463277e+04, -2.406655e+05, -8.206026e+04, 2.595029e+04, 1.531832e+04, 2.170257e+05, -7.837065e+04, 2.115790e+04, 1.593722e+04, -7.134165e+04, -4.885270e+04, 1.721207e+04, 1.648268e+04, 1.378171e+05, -4.537327e+04, 1.397250e+04, 1.696781e+04, 3.258145e+04, -2.938905e+04, 1.138823e+04, 1.739164e+04, 1.146137e+03, -2.126903e+04, 9.382346e+03, 1.776806e+04, 1.883121e+04, -1.738343e+04, 7.723831e+03, 1.810256e+04, -1.217855e+04, -1.191290e+04, 6.363021e+03, 1.839774e+04, 1.663010e+04, -1.094152e+04, 5.216659e+03, 1.865889e+04, 1.933224e+04, -8.372961e+03, 4.279327e+03, 1.888639e+04, -6.277107e+03, -4.826426e+03, 3.572708e+03, 1.908656e+04, -1.213908e+04, -3.694135e+03, 2.989211e+03, 1.926630e+04, 1.843629e+04, -5.074897e+03, 2.437722e+03, 1.942497e+04, -3.720726e+03, -2.060727e+03, 2.022513e+03, 1.956010e+04, -7.571230e+03, -1.529007e+03, 1.706477e+03, 1.968213e+04, 3.388922e+03, -2.219310e+03, 1.387955e+03, 1.978997e+04, -8.136688e+02, -1.296765e+03, 1.118924e+03, 1.988048e+04, -2.113553e+00, -1.105284e+03, 9.057690e+02, 1.995827e+04, -5.605613e+03, -3.817953e+02, 7.273565e+02, 2.002416e+04, 2.555659e+03, -1.135591e+03, 5.415747e+02, 2.007969e+04, -7.323743e+03, 1.792085e+02, 4.001082e+02, 2.012072e+04, -1.158262e+03, -4.852916e+02, 2.418730e+02, 2.015369e+04, -1.923105e+03, -1.119911e+02, 1.136166e+02, 2.017163e+04, -4.453960e+13, 4.901918e+08, 1.224067e+05, 6.971794e+02, 1.428199e+12, -3.402263e+08, 9.960258e+04, 6.992069e+02, 2.850891e+09, 1.332939e+06, 7.987958e+04, 7.087809e+02, 3.653290e+09, -2.318826e+05, 8.167014e+04, 7.351861e+02, -1.710126e+09, 5.205901e+06, 8.583269e+04, 7.881288e+02, 3.500513e+08, 7.327072e+05, 9.110828e+04, 8.821503e+02, -3.667415e+07, 1.644077e+06, 9.599104e+04, 1.028221e+03, -6.427903e+07, 1.499947e+06, 1.026622e+05, 1.245859e+03, -8.902301e+07, 1.348587e+06, 1.097649e+05, 1.556074e+03, -5.458529e+07, 8.715855e+05, 1.161171e+05, 1.980872e+03, -7.078158e+07, 7.296954e+05, 1.206867e+05, 2.536762e+03, -2.407104e+07, 9.613678e+04, 1.221006e+05, 3.235974e+03, -2.892878e+07, 3.067619e+04, 1.200345e+05, 4.068347e+03, -1.424189e+07, -2.367188e+05, 1.148582e+05, 5.025490e+03, -8.468524e+06, -3.287116e+05, 1.065955e+05, 6.075512e+03, -4.418101e+06, -3.647176e+05, 9.643889e+04, 7.185170e+03, -3.842678e+06, -3.284474e+05, 8.532578e+04, 8.318939e+03, -5.278715e+05, -3.366958e+05, 7.378807e+04, 9.444730e+03, -3.937578e+05, -2.707005e+05, 6.272309e+04, 1.052705e+04, -4.639425e+05, -2.130327e+05, 5.276832e+04, 1.155043e+04, 2.817660e+05, -1.847892e+05, 4.384989e+04, 1.250236e+04, 2.903034e+04, -1.344634e+05, 3.621580e+04, 1.337110e+04, 4.635096e+03, -1.030736e+05, 2.983586e+04, 1.416051e+04, 2.047168e+05, -8.515824e+04, 2.444758e+04, 1.487116e+04, -1.279274e+05, -5.337031e+04, 2.008387e+04, 1.550475e+04, 1.415452e+05, -5.181761e+04, 1.640018e+04, 1.607299e+04, 5.602843e+04, -3.510271e+04, 1.339511e+04, 1.657132e+04, -1.127698e+04, -2.404607e+04, 1.106697e+04, 1.701421e+04, 1.253660e+04, -2.007243e+04, 9.134211e+03, 1.740961e+04, 1.780279e+04, -1.574977e+04, 7.514154e+03, 1.775883e+04, 5.640618e+03, -1.147763e+04, 6.204614e+03, 1.806675e+04, 2.936546e+03, -8.829144e+03, 5.139387e+03, 1.833932e+04, 5.299726e+03, -7.061936e+03, 4.256417e+03, 1.858020e+04, 5.686652e+03, -5.507486e+03, 3.532321e+03, 1.879251e+04, -7.404946e+03, -3.452414e+03, 2.950484e+03, 1.898008e+04, 3.770764e+03, -3.682956e+03, 2.441272e+03, 1.914689e+04, 3.794749e+03, -2.805228e+03, 2.009244e+03, 1.929140e+04, -9.089152e+03, -1.190131e+03, 1.676729e+03, 1.941776e+04, 3.011825e+03, -2.138990e+03, 1.359400e+03, 1.952992e+04, 1.428751e+02, -1.319583e+03, 1.084559e+03, 1.962291e+04, -4.913817e+03, -5.934187e+02, 8.743950e+02, 1.970191e+04, -5.071407e+02, -9.664004e+02, 6.676441e+02, 1.976881e+04, -4.650836e+03, -3.007170e+02, 4.834242e+02, 1.982025e+04, -5.376321e+03, -1.327924e+02, 3.054971e+02, 1.985899e+04, -3.742214e+03, -1.749535e+01, 1.250497e+02, 1.988258e+04, -7.893237e+12, 8.288681e+07, 3.010748e+04, 1.136166e+02, 3.103597e+11, -7.118740e+07, 2.592881e+04, 1.141198e+02, 8.428280e+09, -8.028634e+05, 2.230568e+04, 1.167572e+02, -3.605961e+09, 5.798521e+06, 2.449204e+04, 1.242727e+02, 8.783630e+08, -1.200222e+04, 2.748804e+04, 1.413170e+02, 1.044530e+08, 1.460532e+06, 3.037633e+04, 1.712288e+02, -9.170265e+05, 1.717708e+06, 3.572950e+04, 2.228753e+02, -4.501713e+07, 1.862117e+06, 4.323714e+04, 3.093172e+02, -7.396908e+07, 1.935003e+06, 5.294040e+04, 4.499654e+02, -6.169410e+07, 1.717830e+06, 6.431161e+04, 6.711980e+02, -7.366754e+07, 1.587813e+06, 7.632218e+04, 1.002824e+03, -4.663231e+07, 1.055055e+06, 8.724662e+04, 1.476305e+03, -4.048764e+07, 7.247687e+05, 9.513528e+04, 2.107835e+03, -1.960904e+07, 2.489285e+05, 9.891534e+04, 2.902937e+03, -1.894416e+07, 9.872926e+04, 9.837949e+04, 3.841311e+03, -4.442386e+06, -2.116653e+05, 9.380338e+04, 4.898693e+03, -5.834290e+06, -1.885613e+05, 8.648343e+04, 6.023302e+03, -1.719788e+06, -2.613590e+05, 7.770079e+04, 7.187578e+03, -1.691541e+06, -2.251616e+05, 6.812535e+04, 8.346053e+03, -5.227803e+05, -2.157890e+05, 5.856276e+04, 9.472141e+03, 4.814127e+05, -1.960903e+05, 4.946763e+04, 1.053652e+04, -4.579357e+05, -1.276666e+05, 4.162523e+04, 1.152409e+04, 1.805291e+05, -1.211531e+05, 3.473519e+04, 1.244006e+04, 1.359116e+05, -9.125698e+04, 2.876191e+04, 1.326975e+04, -8.572899e+04, -6.301636e+04, 2.388140e+04, 1.401999e+04, 1.408473e+05, -5.792684e+04, 1.972080e+04, 1.469810e+04, -3.746225e+04, -3.691816e+04, 1.630243e+04, 1.530117e+04, 6.587470e+04, -3.359362e+04, 1.347244e+04, 1.584278e+04, 1.012335e+04, -2.298597e+04, 1.114689e+04, 1.632227e+04, 6.639102e+03, -1.787249e+04, 9.269274e+03, 1.675072e+04, -6.477797e+02, -1.369067e+04, 7.700812e+03, 1.713232e+04, 2.142191e+04, -1.198949e+04, 6.378977e+03, 1.747105e+04, -4.414359e+03, -7.644321e+03, 5.317687e+03, 1.776972e+04, 1.533924e+03, -6.582866e+03, 4.443001e+03, 1.803667e+04, 1.981630e+03, -5.240241e+03, 3.694367e+03, 1.827267e+04, -1.052148e+03, -3.932107e+03, 3.071754e+03, 1.848069e+04, 7.306138e+02, -3.290251e+03, 2.545786e+03, 1.866390e+04, 4.229719e+02, -2.571537e+03, 2.102797e+03, 1.882392e+04, -7.944393e+03, -1.390188e+03, 1.735472e+03, 1.896341e+04, 4.214760e+03, -2.291285e+03, 1.382288e+03, 1.908470e+04, -5.750642e+03, -7.694022e+02, 1.094846e+03, 1.918353e+04, 1.100272e+02, -1.256194e+03, 8.401738e+02, 1.926736e+04, -1.010048e+04, 6.181541e+01, 6.190195e+02, 1.933230e+04, -3.820373e+03, -5.389325e+02, 3.661653e+02, 1.938243e+04, -3.917769e+03, -6.433621e+01, 1.509301e+02, 1.940952e+04, -8.070633e+12, 1.076138e+08, 6.631032e+03, 1.018617e+01, 1.369399e+11, -2.815586e+07, 3.146703e+03, 1.029111e+01, -1.827832e+10, 1.209860e+07, 2.333390e+03, 1.050144e+01, 9.521666e+08, -5.255783e+05, 4.376365e+03, 1.192131e+01, 1.173580e+07, 6.003251e+05, 4.867928e+03, 1.474579e+01, 1.090046e+08, 4.481858e+05, 6.169347e+03, 2.054185e+01, -8.730001e+06, 9.393270e+05, 8.380095e+03, 3.174291e+01, -3.942600e+07, 1.234005e+06, 1.236733e+04, 5.449888e+01, -5.058522e+07, 1.455714e+06, 1.855333e+04, 1.000252e+02, -5.517395e+07, 1.596469e+06, 2.732046e+04, 1.871469e+02, -5.839261e+07, 1.629707e+06, 3.862401e+04, 3.439872e+02, -5.114727e+07, 1.444003e+06, 5.151836e+04, 6.065740e+02, -3.969641e+07, 1.116577e+06, 6.409615e+04, 1.010369e+03, -3.222007e+07, 7.829705e+05, 7.436652e+04, 1.580560e+03, -1.492637e+07, 3.287719e+05, 8.053808e+04, 2.324370e+03, -1.367783e+07, 1.737145e+05, 8.239238e+04, 3.220077e+03, -5.409060e+06, -6.916228e+04, 8.037208e+04, 4.244663e+03, -3.749200e+06, -1.294274e+05, 7.520553e+04, 5.347740e+03, -1.438150e+06, -1.808190e+05, 6.828222e+04, 6.491727e+03, -1.031219e+06, -1.695525e+05, 6.052789e+04, 7.635895e+03, -5.897295e+05, -1.566876e+05, 5.266149e+04, 8.752942e+03, 2.142786e+05, -1.502598e+05, 4.501376e+04, 9.817549e+03, -3.080940e+05, -1.038003e+05, 3.819615e+04, 1.081081e+04, 2.489975e+05, -1.015549e+05, 3.212658e+04, 1.173425e+04, -1.029353e+05, -6.635146e+04, 2.693457e+04, 1.257483e+04, 1.251409e+05, -6.152113e+04, 2.251714e+04, 1.334400e+04, -3.664596e+04, -4.097680e+04, 1.880373e+04, 1.403645e+04, 5.410562e+04, -3.659535e+04, 1.568214e+04, 1.466359e+04, -8.388199e+03, -2.544703e+04, 1.306777e+04, 1.522421e+04, 3.381060e+04, -2.226293e+04, 1.088538e+04, 1.572764e+04, 8.123732e+03, -1.580665e+04, 9.086832e+03, 1.617555e+04, -5.569137e+02, -1.204825e+04, 7.622303e+03, 1.657705e+04, -3.528642e+03, -9.509650e+03, 6.381344e+03, 1.693640e+04, 1.153206e+04, -8.551674e+03, 5.310794e+03, 1.725604e+04, -7.248790e+03, -5.378741e+03, 4.434661e+03, 1.753772e+04, 3.681099e+03, -5.223851e+03, 3.690070e+03, 1.778863e+04, 1.885868e+03, -3.926101e+03, 3.056040e+03, 1.800796e+04, -4.915319e+03, -2.588201e+03, 2.541884e+03, 1.820050e+04, 4.294262e+02, -2.621170e+03, 2.087430e+03, 1.836978e+04, -5.053803e+03, -1.594382e+03, 1.693140e+03, 1.851459e+04, -1.007074e+02, -1.793775e+03, 1.337123e+03, 1.863817e+04, -7.506678e+03, -6.792374e+02, 1.030627e+03, 1.873863e+04, 8.309197e+02, -1.383974e+03, 7.309777e+02, 1.881973e+04, -1.813795e+04, 9.635944e+02, 4.941701e+02, 1.887662e+04, -3.621577e+03, -2.330195e+02, 1.616740e+02, 1.891720e+04, 6.535480e+11, -5.929338e+06, -3.781728e+02, 5.184347e-01, -3.304103e+10, 7.713900e+06, 0, 5.135015e-01, 1.605064e+08, -1.634788e+05, 4.183612e+02, 5.677667e-01, 3.242006e+08, -2.400051e+05, 3.629284e+02, 6.928907e-01, -1.079961e+08, 3.789254e+05, 4.524209e+02, 9.108485e-01, 1.466292e+07, 1.653131e+05, 8.910833e+02, 1.679980e+00, 5.139923e+06, 3.030831e+05, 1.517958e+03, 3.541142e+00, -2.137928e+07, 6.141632e+05, 2.918879e+03, 8.370747e+00, -4.382682e+07, 9.923543e+05, 5.952912e+03, 2.155764e+01, -4.591369e+07, 1.251039e+06, 1.153723e+04, 5.541645e+01, -5.599871e+07, 1.504362e+06, 2.021971e+04, 1.319322e+02, -4.905457e+07, 1.461205e+06, 3.191749e+04, 2.858732e+02, -4.156802e+07, 1.274441e+06, 4.502474e+04, 5.570078e+02, -3.338034e+07, 9.727163e+05, 5.748065e+04, 9.823445e+02, -1.872780e+07, 5.500384e+05, 6.692099e+04, 1.582833e+03, -1.333256e+07, 3.021913e+05, 7.223951e+04, 2.351712e+03, -6.921961e+06, 7.087433e+04, 7.357275e+04, 3.270621e+03, -5.394556e+06, -2.381757e+04, 7.145035e+04, 4.301491e+03, -2.089262e+06, -1.282498e+05, 6.663436e+04, 5.405952e+03, -6.847307e+05, -1.546674e+05, 6.012913e+04, 6.533810e+03, -7.349015e+05, -1.335175e+05, 5.325038e+04, 7.651409e+03, -2.879821e+05, -1.272674e+05, 4.640416e+04, 8.738273e+03, -8.462746e+03, -1.130442e+05, 3.982467e+04, 9.771057e+03, -1.063739e+05, -8.787637e+04, 3.388731e+04, 1.073618e+04, 1.343560e+05, -7.883937e+04, 2.860691e+04, 1.162993e+04, 1.389387e+04, -5.691194e+04, 2.410021e+04, 1.244608e+04, -5.177439e+04, -4.289378e+04, 2.031934e+04, 1.319275e+04, 8.139572e+04, -4.013155e+04, 1.699864e+04, 1.387169e+04, 2.468899e+04, -2.814082e+04, 1.423289e+04, 1.448002e+04, -6.571990e+04, -1.805698e+04, 1.199929e+04, 1.503010e+04, 8.726906e+04, -2.301298e+04, 9.974486e+03, 1.552759e+04, -3.911454e+04, -9.959665e+03, 8.366133e+03, 1.596392e+04, 2.754859e+04, -1.261897e+04, 7.034917e+03, 1.636173e+04, -2.143616e+04, -6.578940e+03, 5.902874e+03, 1.671286e+04, 1.445855e+04, -8.060233e+03, 4.922564e+03, 1.702911e+04, -1.068146e+03, -5.007837e+03, 4.094606e+03, 1.730495e+04, -1.446239e+03, -4.042107e+03, 3.428210e+03, 1.755026e+04, -7.646742e+03, -2.833790e+03, 2.850615e+03, 1.776680e+04, 6.036580e+03, -3.510960e+03, 2.317098e+03, 1.795618e+04, -5.012745e+03, -1.656924e+03, 1.885239e+03, 1.811589e+04, -4.810884e+03, -1.478773e+03, 1.519931e+03, 1.825459e+04, -6.234266e+03, -1.106439e+03, 1.165198e+03, 1.836994e+04, -2.823139e+03, -1.181941e+03, 8.197310e+02, 1.846054e+04, -1.258697e+04, 2.043762e+02, 5.250146e+02, 1.852450e+04, -5.978057e+03, -7.475415e+01, 2.034009e+02, 1.856604e+04, -8.418277e+10, 1.154661e+06, 5.714404e+01, 4.036256e-03, -2.687024e+07, -8.592069e+04, 2.190888e+01, 4.933202e-03, 1.021218e+08, -5.017017e+04, 0, 6.278621e-03, -1.255189e+07, 1.903032e+04, 0, 4.484729e-03, 1.558282e+06, 2.417039e+03, 8.957179e+00, 8.969458e-03, -3.914997e+05, 1.370244e+04, 1.920907e+01, 2.287212e-02, -6.741212e+05, 3.455420e+04, 5.930749e+01, 8.520985e-02, -4.870917e+06, 1.084084e+05, 2.009074e+02, 3.735779e-01, -9.230984e+06, 2.505707e+05, 7.085224e+02, 1.758462e+00, -2.106645e+07, 5.356899e+05, 2.195612e+03, 7.431645e+00, -2.950385e+07, 8.461586e+05, 5.821344e+03, 2.723083e+01, -3.782577e+07, 1.119956e+06, 1.259572e+04, 8.251229e+01, -3.282215e+07, 1.127447e+06, 2.260996e+04, 2.090373e+02, -3.131878e+07, 1.051472e+06, 3.440400e+04, 4.481747e+02, -2.053329e+07, 7.431721e+05, 4.587941e+04, 8.398019e+02, -1.369182e+07, 4.785742e+05, 5.475855e+04, 1.400337e+03, -9.066544e+06, 2.627224e+05, 6.030965e+04, 2.128540e+03, -6.437927e+06, 1.088040e+05, 6.231489e+04, 3.004682e+03, -2.053492e+06, -4.777547e+04, 6.091525e+04, 3.993557e+03, -1.949825e+06, -6.605211e+04, 5.729296e+04, 5.045588e+03, -9.414086e+05, -9.996283e+04, 5.243186e+04, 6.132059e+03, -1.890967e+05, -1.121647e+05, 4.675167e+04, 7.214864e+03, -3.045963e+05, -9.180211e+04, 4.106393e+04, 8.265942e+03, -5.330101e+04, -8.608205e+04, 3.562988e+04, 9.272761e+03, -3.028050e+04, -7.119125e+04, 3.058189e+04, 1.021899e+04, 3.389382e+04, -6.002974e+04, 2.607403e+04, 1.109889e+04, 2.504837e+04, -4.749684e+04, 2.215132e+04, 1.190918e+04, 3.155848e+04, -3.811928e+04, 1.880026e+04, 1.265226e+04, -7.201400e+04, -2.586018e+04, 1.596321e+04, 1.333116e+04, 7.110271e+04, -2.854939e+04, 1.340926e+04, 1.395078e+04, 4.710820e+03, -1.819806e+04, 1.127146e+04, 1.450295e+04, -1.716947e+04, -1.351549e+04, 9.553127e+03, 1.500363e+04, 1.705228e+04, -1.317062e+04, 8.030335e+03, 1.545596e+04, -7.296253e+03, -8.740504e+03, 6.744056e+03, 1.585811e+04, 1.124590e+04, -8.382692e+03, 5.655728e+03, 1.621866e+04, -6.404979e+03, -5.276710e+03, 4.751552e+03, 1.653766e+04, -4.078801e+03, -4.618901e+03, 3.982096e+03, 1.682316e+04, 5.784536e+03, -4.519947e+03, 3.287528e+03, 1.707427e+04, -1.229816e+04, -2.021194e+03, 2.721875e+03, 1.729168e+04, 1.842108e+03, -3.109246e+03, 2.195199e+03, 1.748291e+04, 1.022085e+03, -2.237389e+03, 1.729408e+03, 1.764076e+04, -1.355747e+04, -3.814936e+02, 1.371889e+03, 1.777199e+04, -4.135917e+03, -1.405750e+03, 9.812738e+02, 1.788158e+04, -1.176006e+04, -1.122970e+02, 6.103796e+02, 1.795760e+04, -7.664940e+03, -2.255428e+01, 2.505438e+02, 1.800524e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.756796e+04, 3.410796e+02, 0, 0, -1.318358e+05, 2.755397e+03, 1.097018e+00, 1.345419e-03, -5.608807e+05, 1.562207e+04, 1.379447e+01, 2.466601e-02, -2.514261e+06, 6.918882e+04, 1.071228e+02, 2.654960e-01, -6.065589e+06, 1.944641e+05, 5.889450e+02, 2.019474e+00, -1.283506e+07, 4.191455e+05, 2.215660e+03, 1.058396e+01, -1.846805e+07, 6.414717e+05, 6.149145e+03, 4.126265e+01, -1.742585e+07, 7.178521e+05, 1.289995e+04, 1.231435e+02, -1.832815e+07, 7.396414e+05, 2.178945e+04, 2.939924e+02, -1.255612e+07, 5.674151e+05, 3.137447e+04, 5.949191e+02, -9.863656e+06, 4.196776e+05, 3.966016e+04, 1.048397e+03, -6.077376e+06, 2.402884e+05, 4.561200e+04, 1.662630e+03, -3.971539e+06, 1.160875e+05, 4.864964e+04, 2.421336e+03, -1.807408e+06, 1.308620e+04, 4.902579e+04, 3.296939e+03, -1.659778e+06, -1.565950e+04, 4.744301e+04, 4.252506e+03, -6.733442e+05, -5.969285e+04, 4.440953e+04, 5.259324e+03, -2.473511e+05, -7.140758e+04, 4.040044e+04, 6.277780e+03, -2.042537e+05, -6.499188e+04, 3.615217e+04, 7.282236e+03, -1.170966e+05, -6.002899e+04, 3.193951e+04, 8.257070e+03, -2.352214e+04, -5.459684e+04, 2.787370e+04, 9.187282e+03, 4.937715e+04, -4.785421e+04, 2.412159e+04, 1.006206e+04, -1.156724e+05, -3.191696e+04, 2.084086e+04, 1.087739e+04, 1.297973e+05, -3.849662e+04, 1.781328e+04, 1.163679e+04, -9.774888e+04, -1.844295e+04, 1.526608e+04, 1.232678e+04, 5.200490e+04, -2.438844e+04, 1.301188e+04, 1.296761e+04, -8.135849e+03, -1.543929e+04, 1.102631e+04, 1.354296e+04, 1.028947e+04, -1.379101e+04, 9.377438e+03, 1.406704e+04, -8.156883e+03, -9.874940e+03, 7.962838e+03, 1.453982e+04, -9.036508e+01, -8.750479e+03, 6.734128e+03, 1.496712e+04, 1.570054e+03, -7.174620e+03, 5.655807e+03, 1.534847e+04, -1.278293e+03, -5.539760e+03, 4.740587e+03, 1.568705e+04, -2.566299e+03, -4.405104e+03, 3.959008e+03, 1.598696e+04, -1.910568e+03, -3.654087e+03, 3.277553e+03, 1.625060e+04, -8.951905e+03, -2.385243e+03, 2.683652e+03, 1.647951e+04, -2.863973e+03, -2.620958e+03, 2.123866e+03, 1.667582e+04, -5.366473e+03, -1.785690e+03, 1.617383e+03, 1.683538e+04, -4.998538e+03, -1.403221e+03, 1.171570e+03, 1.696147e+04, -1.930573e+04, 4.416717e+02, 7.785677e+02, 1.705459e+04, -9.332163e+03, -8.178539e+01, 3.103724e+02, 1.711692e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8.909025e+02, 3.538429e+01, 0, 0, -6.422168e+04, 1.628264e+03, 2.273205e-01, 4.484729e-04, -1.684485e+05, 8.745175e+03, 1.123560e+01, 3.049616e-02, -1.396076e+06, 4.954183e+04, 9.457898e+01, 3.480150e-01, -3.153636e+06, 1.315038e+05, 5.765050e+02, 2.867984e+00, -5.753237e+06, 2.566029e+05, 2.084437e+03, 1.445742e+01, -8.015029e+06, 3.742078e+05, 5.388979e+03, 5.210269e+01, -8.074433e+06, 4.135002e+05, 1.068476e+04, 1.446774e+02, -6.661386e+06, 3.790568e+05, 1.722141e+04, 3.258434e+02, -6.077928e+06, 3.260624e+05, 2.393450e+04, 6.249524e+02, -3.712201e+06, 2.107243e+05, 2.968932e+04, 1.061776e+03, -2.467015e+06, 1.292915e+05, 3.366006e+04, 1.632819e+03, -1.882443e+06, 7.221017e+04, 3.588291e+04, 2.326102e+03, -1.086002e+06, 1.703520e+04, 3.635384e+04, 3.120870e+03, -4.605255e+05, -1.927992e+04, 3.530604e+04, 3.984944e+03, -4.341743e+05, -2.590209e+04, 3.334915e+04, 4.887920e+03, -1.327876e+05, -3.966641e+04, 3.080680e+04, 5.809224e+03, -1.434539e+05, -3.617659e+04, 2.795994e+04, 6.723427e+03, -3.317195e+04, -3.750287e+04, 2.503988e+04, 7.617373e+03, -7.415801e+04, -3.064914e+04, 2.218438e+04, 8.475763e+03, 5.703238e+04, -3.265980e+04, 1.944651e+04, 9.292128e+03, -6.193252e+04, -2.057404e+04, 1.700446e+04, 1.005564e+04, 1.215735e+04, -2.212679e+04, 1.477610e+04, 1.077365e+04, 1.341243e+04, -1.799234e+04, 1.273145e+04, 1.143468e+04, -3.132178e+04, -1.206636e+04, 1.099078e+04, 1.204245e+04, 3.848496e+04, -1.481817e+04, 9.392096e+03, 1.260173e+04, -3.404114e+04, -6.555128e+03, 8.060933e+03, 1.310445e+04, 4.790791e+03, -8.972117e+03, 6.866951e+03, 1.356787e+04, 2.423192e+03, -6.922553e+03, 5.758467e+03, 1.397865e+04, 1.399033e+03, -5.445455e+03, 4.839055e+03, 1.434333e+04, -1.893961e+04, -2.804734e+03, 4.069198e+03, 1.466700e+04, 1.877066e+03, -4.505274e+03, 3.305315e+03, 1.495392e+04, -2.115025e+03, -3.042529e+03, 2.614916e+03, 1.519227e+04, -1.104184e+04, -1.582042e+03, 2.053080e+03, 1.539091e+04, -1.188713e+04, -1.306613e+03, 1.508474e+03, 1.555342e+04, -2.215601e+04, 1.527387e+02, 9.531955e+02, 1.567324e+04, -9.598320e+03, -2.176024e+02, 3.465646e+02, 1.574722e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.644955e+03, 6.448869e+01, 0, 0, -1.029582e+04, 6.950336e+02, 5.752530e-01, 1.793892e-03, -1.273869e+05, 6.122692e+03, 8.641528e+00, 3.498089e-02, -4.160031e+05, 2.380720e+04, 8.266186e+01, 4.377096e-01, -1.255311e+06, 6.800200e+04, 4.206646e+02, 2.985036e+00, -2.081254e+06, 1.244833e+05, 1.454439e+03, 1.399056e+01, -2.900617e+06, 1.789184e+05, 3.584258e+03, 4.729999e+01, -2.756955e+06, 1.947111e+05, 6.897862e+03, 1.251625e+02, -2.672126e+06, 1.929093e+05, 1.099130e+04, 2.723388e+02, -2.086269e+06, 1.602556e+05, 1.530917e+04, 5.125534e+02, -1.573510e+06, 1.215890e+05, 1.919192e+04, 8.597800e+02, -1.355439e+06, 8.820952e+04, 2.224744e+04, 1.318242e+03, -5.451509e+05, 3.738095e+04, 2.414097e+04, 1.882051e+03, -6.036619e+05, 2.573667e+04, 2.497727e+04, 2.530007e+03, -3.048824e+05, 1.354461e+03, 2.497001e+04, 3.250364e+03, -2.405107e+05, -7.845169e+03, 2.417257e+04, 4.017749e+03, -7.981406e+04, -1.839566e+04, 2.282880e+04, 4.812674e+03, -5.359818e+04, -1.914615e+04, 2.117668e+04, 5.613727e+03, -9.539372e+04, -1.631387e+04, 1.943298e+04, 6.409506e+03, -4.737571e+03, -2.057378e+04, 1.755731e+04, 7.189996e+03, -1.608912e+04, -1.712993e+04, 1.567655e+04, 7.938106e+03, -2.088100e+03, -1.571847e+04, 1.391656e+04, 8.650875e+03, -3.661972e+04, -1.147036e+04, 1.228681e+04, 9.323355e+03, 1.657977e+04, -1.377689e+04, 1.070581e+04, 9.954345e+03, -3.463596e+03, -9.698335e+03, 9.274149e+03, 1.053254e+04, -5.891139e+03, -8.043333e+03, 8.040790e+03, 1.106587e+04, -1.191734e+04, -6.450980e+03, 6.917247e+03, 1.155414e+04, 3.491650e+02, -6.574146e+03, 5.858587e+03, 1.199621e+04, -7.578241e+03, -4.689544e+03, 4.907900e+03, 1.238765e+04, -1.092448e+04, -3.741680e+03, 4.055337e+03, 1.273290e+04, 4.106714e+03, -4.518819e+03, 3.238118e+03, 1.303002e+04, -2.102369e+04, -1.074664e+03, 2.560131e+03, 1.327469e+04, -1.056000e+04, -2.204585e+03, 1.868347e+03, 1.347934e+04, -2.377808e+04, -1.032248e+02, 1.180047e+03, 1.362602e+04, -1.508705e+04, -9.908849e+00, 4.767186e+02, 1.371823e+04, }; static float solarDataset720[] = { 2.525918e+14, -2.554558e+09, -1.370972e+05, 5.293898e+03, -9.815726e+12, 2.361968e+09, 0, 5.292070e+03, -2.161284e+10, 3.681165e+06, 1.412622e+05, 5.309215e+03, 5.368037e+09, -9.739389e+06, 1.367183e+05, 5.355116e+03, 1.822593e+09, -3.920899e+06, 1.308458e+05, 5.439746e+03, 7.141674e+07, -1.791913e+05, 1.286456e+05, 5.575115e+03, -2.827977e+08, 6.550345e+05, 1.286106e+05, 5.776749e+03, -4.278581e+07, -3.471843e+05, 1.274126e+05, 6.058476e+03, -4.678445e+07, -3.154022e+05, 1.243004e+05, 6.425649e+03, -1.705526e+06, -5.419689e+05, 1.199770e+05, 6.883746e+03, -4.511176e+07, -2.088734e+05, 1.148018e+05, 7.432212e+03, -9.899075e+06, -5.263774e+05, 1.080124e+05, 8.072059e+03, -1.136389e+07, -4.495800e+05, 9.941715e+04, 8.783408e+03, -4.432855e+06, -4.699310e+05, 8.991963e+04, 9.551761e+03, -6.678983e+06, -3.711487e+05, 7.987525e+04, 1.035412e+04, -1.048795e+06, -3.923684e+05, 6.943065e+04, 1.117043e+04, -1.487792e+06, -3.054383e+05, 5.919156e+04, 1.197072e+04, -5.138917e+05, -2.592954e+05, 4.970314e+04, 1.273960e+04, 4.638959e+05, -2.185755e+05, 4.110096e+04, 1.345986e+04, -3.133674e+05, -1.488658e+05, 3.379813e+04, 1.412155e+04, 7.701003e+02, -1.222341e+05, 2.757857e+04, 1.472633e+04, 1.443326e+05, -9.575337e+04, 2.226568e+04, 1.526806e+04, 1.586498e+05, -7.156428e+04, 1.793449e+04, 1.574764e+04, 1.756484e+04, -4.896879e+04, 1.451310e+04, 1.617102e+04, 8.828851e+04, -3.944113e+04, 1.175869e+04, 1.654602e+04, -6.323419e+04, -2.418904e+04, 9.565046e+03, 1.687570e+04, 9.171615e+04, -2.493151e+04, 7.723482e+03, 1.716762e+04, -1.428085e+04, -1.376363e+04, 6.275414e+03, 1.741964e+04, 2.437380e+04, -1.256407e+04, 5.133211e+03, 1.764318e+04, 1.709855e+03, -8.360511e+03, 4.206652e+03, 1.783845e+04, -1.602339e+03, -6.380326e+03, 3.464464e+03, 1.801101e+04, 1.086892e+04, -5.672266e+03, 2.839413e+03, 1.816274e+04, 1.947834e+03, -3.743557e+03, 2.343114e+03, 1.829498e+04, -4.914126e+03, -2.541311e+03, 1.951555e+03, 1.841212e+04, 7.500891e+03, -2.900219e+03, 1.606900e+03, 1.851587e+04, -6.683859e+03, -1.171479e+03, 1.335113e+03, 1.860554e+04, 2.524698e+03, -1.755106e+03, 1.097230e+03, 1.868573e+04, 1.413303e+02, -1.123324e+03, 8.913331e+02, 1.875383e+04, -5.972485e+02, -8.258019e+02, 7.301851e+02, 1.881276e+04, -1.374811e+03, -6.044738e+02, 5.930501e+02, 1.886362e+04, -2.464199e+02, -6.001397e+02, 4.686460e+02, 1.890681e+04, -3.386839e+03, -1.749768e+02, 3.615101e+02, 1.894210e+04, 1.115795e+03, -5.876697e+02, 2.497363e+02, 1.897051e+04, -5.909912e+03, 3.198230e+02, 1.691543e+02, 1.898962e+04, -1.580136e+03, -5.978889e+01, 6.196234e+01, 1.900370e+04, 2.989518e+13, -1.289421e+08, 1.099829e+05, 2.834177e+03, -3.090365e+12, 6.856653e+08, 1.321869e+05, 2.836187e+03, 9.682967e+10, -5.904165e+07, 1.626712e+05, 2.856692e+03, -5.436058e+09, 6.318661e+06, 1.551570e+05, 2.907038e+03, 6.591801e+08, -1.130499e+06, 1.565831e+05, 3.007157e+03, -7.138774e+08, 1.316135e+06, 1.563922e+05, 3.171322e+03, 3.237601e+07, -7.953836e+05, 1.552515e+05, 3.417128e+03, -4.655197e+07, -3.938954e+05, 1.522345e+05, 3.753533e+03, -2.305480e+07, -4.616706e+05, 1.487543e+05, 4.192527e+03, -8.350406e+07, -1.385543e+05, 1.443327e+05, 4.741292e+03, -2.273311e+07, -6.254407e+05, 1.375714e+05, 5.403999e+03, -2.274408e+07, -5.692192e+05, 1.282140e+05, 6.164358e+03, -6.189259e+06, -6.624563e+05, 1.172277e+05, 7.007832e+03, -1.040898e+07, -5.161737e+05, 1.053028e+05, 7.908995e+03, -2.699482e+06, -5.346775e+05, 9.279238e+04, 8.847287e+03, -2.235491e+06, -4.383825e+05, 8.020280e+04, 9.789863e+03, -1.374288e+06, -3.645659e+05, 6.827003e+04, 1.071465e+04, -1.221563e+04, -3.098323e+05, 5.718372e+04, 1.159997e+04, -3.432144e+05, -2.317054e+05, 4.735807e+04, 1.242805e+04, 1.796722e+05, -1.889060e+05, 3.883150e+04, 1.319192e+04, 5.940359e+04, -1.395754e+05, 3.160908e+04, 1.388396e+04, 1.898772e+05, -1.085417e+05, 2.562541e+04, 1.450571e+04, 6.259607e+04, -7.758476e+04, 2.076082e+04, 1.505893e+04, 9.493680e+03, -5.706448e+04, 1.682657e+04, 1.555047e+04, 1.154325e+05, -4.666948e+04, 1.358994e+04, 1.598475e+04, -6.600032e+03, -3.033826e+04, 1.102596e+04, 1.636513e+04, 5.150180e+04, -2.556832e+04, 8.962958e+03, 1.670138e+04, -5.043216e+03, -1.683693e+04, 7.309487e+03, 1.699565e+04, 4.630010e+04, -1.531867e+04, 5.969269e+03, 1.725549e+04, -3.176222e+04, -7.688050e+03, 4.927359e+03, 1.748265e+04, 1.990387e+04, -9.109929e+03, 4.042288e+03, 1.768595e+04, 1.136736e+04, -6.270534e+03, 3.303928e+03, 1.786155e+04, -1.921046e+03, -4.000413e+03, 2.750164e+03, 1.801613e+04, -8.295624e+03, -2.881436e+03, 2.295908e+03, 1.815411e+04, 1.158890e+04, -3.694378e+03, 1.877598e+03, 1.827603e+04, -7.985865e+03, -1.327338e+03, 1.554511e+03, 1.838032e+04, 6.287924e+03, -2.268548e+03, 1.279719e+03, 1.847378e+04, -5.841113e+03, -7.169778e+02, 1.056665e+03, 1.855324e+04, 2.331521e+03, -1.372167e+03, 8.596951e+02, 1.862405e+04, -6.715950e+02, -7.448262e+02, 6.904255e+02, 1.868294e+04, -2.277589e+03, -4.673925e+02, 5.571070e+02, 1.873345e+04, -2.143745e+03, -4.255135e+02, 4.286454e+02, 1.877595e+04, -2.342452e+03, -3.095573e+02, 3.018268e+02, 1.880924e+04, -2.141651e+03, -1.996398e+02, 1.826752e+02, 1.883282e+04, -1.800736e+03, -5.698464e+01, 8.207416e+01, 1.884678e+04, 1.447401e+13, -8.993067e+07, 7.803754e+04, 1.013116e+03, -8.727215e+11, 2.292335e+08, 8.783964e+04, 1.014508e+03, -2.637424e+10, 1.849076e+07, 1.050400e+05, 1.026912e+03, 2.501031e+09, -8.153203e+05, 1.086648e+05, 1.062371e+03, 6.350316e+08, 1.081054e+06, 1.106769e+05, 1.131995e+03, -5.067515e+08, 2.734648e+06, 1.150568e+05, 1.250306e+03, 8.471154e+07, 7.604123e+05, 1.198954e+05, 1.435562e+03, -5.169626e+07, 1.125922e+06, 1.244427e+05, 1.702570e+03, -1.420182e+08, 1.257137e+06, 1.296866e+05, 2.073373e+03, -6.016236e+07, 4.507910e+05, 1.331301e+05, 2.568637e+03, -6.181395e+07, 2.560844e+05, 1.334031e+05, 3.194251e+03, -2.944661e+07, -1.809190e+05, 1.302883e+05, 3.952267e+03, -1.974673e+07, -3.302753e+05, 1.236749e+05, 4.825974e+03, -1.831211e+07, -3.630744e+05, 1.144628e+05, 5.793807e+03, -1.063314e+05, -5.671483e+05, 1.027316e+05, 6.825455e+03, -7.428135e+06, -3.646082e+05, 9.035604e+04, 7.875637e+03, -4.224498e+05, -4.226070e+05, 7.785079e+04, 8.928044e+03, -5.225200e+05, -3.292931e+05, 6.569603e+04, 9.939440e+03, 1.351084e+05, -2.692418e+05, 5.486961e+04, 1.089545e+04, -6.986607e+05, -1.900635e+05, 4.546374e+04, 1.178319e+04, 8.151561e+05, -1.826275e+05, 3.717645e+04, 1.259855e+04, -2.097157e+05, -1.087743e+05, 3.039241e+04, 1.332873e+04, 8.873651e+04, -9.305999e+04, 2.483143e+04, 1.399033e+04, 8.394321e+04, -7.004892e+04, 2.014053e+04, 1.457831e+04, 2.568894e+04, -5.092930e+04, 1.634436e+04, 1.509840e+04, 1.280322e+05, -4.220220e+04, 1.325641e+04, 1.555749e+04, -3.361001e+04, -2.513248e+04, 1.085224e+04, 1.596046e+04, 2.979468e+04, -2.253703e+04, 8.893598e+03, 1.631985e+04, 3.723816e+04, -1.735501e+04, 7.267372e+03, 1.663501e+04, -1.726087e+04, -1.053326e+04, 6.006399e+03, 1.691243e+04, 1.578262e+04, -1.021949e+04, 4.953342e+03, 1.715986e+04, 1.743296e+03, -6.992042e+03, 4.079600e+03, 1.737627e+04, 1.170557e+03, -5.467831e+03, 3.375752e+03, 1.756744e+04, 7.317985e+03, -4.658490e+03, 2.788852e+03, 1.773572e+04, -2.944508e+03, -2.890565e+03, 2.322051e+03, 1.788333e+04, -1.384627e+03, -2.499429e+03, 1.932715e+03, 1.801462e+04, 3.870094e+03, -2.380198e+03, 1.589263e+03, 1.812959e+04, -7.589419e+03, -9.387526e+02, 1.316390e+03, 1.822906e+04, 6.765004e+03, -2.055863e+03, 1.059421e+03, 1.831691e+04, -7.908487e+03, -1.944332e+02, 8.634886e+02, 1.838909e+04, 2.402999e+03, -1.255047e+03, 6.776365e+02, 1.845334e+04, -3.022120e+03, -3.713633e+02, 5.165854e+02, 1.850326e+04, -2.480041e+03, -3.839458e+02, 3.785083e+02, 1.854419e+04, -7.542281e+03, 2.431373e+02, 2.418575e+02, 1.857417e+04, -1.557329e+03, -1.160108e+02, 7.276011e+01, 1.859310e+04, -4.132444e+13, 4.983149e+08, 6.380020e+04, 1.851747e+02, 1.098450e+12, -2.448093e+08, 4.414219e+04, 1.862109e+02, -3.624187e+10, 2.421969e+07, 3.304274e+04, 1.899028e+02, 3.813707e+09, -2.123873e+06, 3.724471e+04, 2.020496e+02, -9.762495e+07, 2.271395e+06, 3.918961e+04, 2.259298e+02, 3.247350e+08, 1.259102e+06, 4.364256e+04, 2.695358e+02, -7.726482e+07, 2.316327e+06, 4.998989e+04, 3.423470e+02, -1.019017e+08, 2.228401e+06, 5.902081e+04, 4.620756e+02, -5.107875e+07, 1.805353e+06, 6.940990e+04, 6.504069e+02, -9.891926e+07, 1.883571e+06, 8.077203e+04, 9.326294e+02, -6.594961e+07, 1.309945e+06, 9.189406e+04, 1.340972e+03, -5.421313e+07, 8.991718e+05, 1.004014e+05, 1.895689e+03, -3.766459e+07, 4.481471e+05, 1.050914e+05, 2.607513e+03, -2.032421e+07, 5.007750e+04, 1.049523e+05, 3.466517e+03, -1.278947e+07, -1.455609e+05, 1.004758e+05, 4.443536e+03, -6.566446e+06, -2.703383e+05, 9.276981e+04, 5.502737e+03, -2.497008e+06, -3.170135e+05, 8.300714e+04, 6.601359e+03, -2.210423e+06, -2.754951e+05, 7.259218e+04, 7.700522e+03, -8.795482e+05, -2.564902e+05, 6.219949e+04, 8.772571e+03, 4.875594e+05, -2.333622e+05, 5.229111e+04, 9.788438e+03, -3.924964e+05, -1.589745e+05, 4.367724e+04, 1.073035e+04, 2.878946e+05, -1.428811e+05, 3.620966e+04, 1.160062e+04, -8.617935e+04, -9.818419e+04, 2.987112e+04, 1.238861e+04, 1.563730e+05, -8.375478e+04, 2.455211e+04, 1.310190e+04, 3.157587e+04, -5.922817e+04, 2.015025e+04, 1.373849e+04, 1.956095e+04, -4.524892e+04, 1.656404e+04, 1.430792e+04, 4.832654e+04, -3.595669e+04, 1.358688e+04, 1.481455e+04, 4.014487e+04, -2.701491e+04, 1.116623e+04, 1.526291e+04, -8.957043e+03, -1.852113e+04, 9.237221e+03, 1.566073e+04, 1.813805e+04, -1.597159e+04, 7.633708e+03, 1.601542e+04, 7.265770e+03, -1.171307e+04, 6.306238e+03, 1.632830e+04, 5.845122e+03, -9.056395e+03, 5.229642e+03, 1.660539e+04, 1.705465e+03, -6.842519e+03, 4.346327e+03, 1.685070e+04, -3.099670e+03, -5.132762e+03, 3.614027e+03, 1.706799e+04, 9.091824e+03, -4.904382e+03, 2.986894e+03, 1.725985e+04, -3.097208e+03, -2.861985e+03, 2.486454e+03, 1.742725e+04, -5.115305e+03, -2.254430e+03, 2.073917e+03, 1.757629e+04, 3.305222e+03, -2.536090e+03, 1.690410e+03, 1.770681e+04, 8.613358e+02, -1.693291e+03, 1.373974e+03, 1.781760e+04, -5.270481e+03, -8.177981e+02, 1.129554e+03, 1.791337e+04, 7.202933e+01, -1.244067e+03, 8.946304e+02, 1.799642e+04, -3.932364e+03, -5.617175e+02, 6.851235e+02, 1.806340e+04, -2.555341e+03, -5.981541e+02, 4.914744e+02, 1.811718e+04, -7.312382e+03, 8.261489e+01, 3.128333e+02, 1.815579e+04, -3.444405e+03, -5.151392e+01, 1.189236e+02, 1.818034e+04, 8.583418e+11, -5.864616e+06, 5.801889e+03, 1.923411e+01, -6.597669e+10, 1.477868e+07, 6.364852e+03, 1.933677e+01, 2.967102e+09, -1.520837e+06, 7.049525e+03, 2.020405e+01, 1.724924e+09, -8.185196e+05, 7.008149e+03, 2.245400e+01, -3.378314e+08, 1.650445e+06, 8.069082e+03, 2.703836e+01, 1.552037e+08, 6.585714e+05, 1.041940e+04, 3.695513e+01, -3.403201e+07, 1.345522e+06, 1.363123e+04, 5.551902e+01, -1.703697e+07, 1.439665e+06, 1.903317e+04, 9.145205e+01, -9.003897e+07, 1.961474e+06, 2.698744e+04, 1.586961e+02, -6.267348e+07, 1.801412e+06, 3.788213e+04, 2.823781e+02, -7.470787e+07, 1.811829e+06, 5.060948e+04, 4.922647e+02, -5.781055e+07, 1.427287e+06, 6.398865e+04, 8.261355e+02, -4.006817e+07, 9.697074e+05, 7.540147e+04, 1.312352e+03, -3.092562e+07, 6.019593e+05, 8.322421e+04, 1.964145e+03, -1.617086e+07, 1.930166e+05, 8.632748e+04, 2.776467e+03, -7.153255e+06, -5.054112e+04, 8.478684e+04, 3.717483e+03, -8.315402e+06, -7.881484e+04, 8.021572e+04, 4.749714e+03, -1.434409e+06, -2.349591e+05, 7.304797e+04, 5.840556e+03, -1.429239e+06, -2.030418e+05, 6.452381e+04, 6.933083e+03, -6.545407e+05, -1.903916e+05, 5.599103e+04, 8.003800e+03, -3.793090e+04, -1.703670e+05, 4.774203e+04, 9.026419e+03, -9.296898e+04, -1.335883e+05, 4.028177e+04, 9.983296e+03, 5.681627e+04, -1.098699e+05, 3.373445e+04, 1.086875e+04, 7.934290e+04, -8.617558e+04, 2.809759e+04, 1.167776e+04, -1.118900e+05, -6.075673e+04, 2.336891e+04, 1.241185e+04, 2.127956e+05, -5.972293e+04, 1.927296e+04, 1.307544e+04, -1.157300e+04, -3.572063e+04, 1.597792e+04, 1.366415e+04, -1.006642e+04, -2.856674e+04, 1.333737e+04, 1.419680e+04, 2.851548e+04, -2.432571e+04, 1.105653e+04, 1.467415e+04, 1.366951e+04, -1.801951e+04, 9.163722e+03, 1.509781e+04, 2.547955e+03, -1.350032e+04, 7.624751e+03, 1.547499e+04, 1.201292e+04, -1.116877e+04, 6.343424e+03, 1.581086e+04, -7.993522e+03, -7.540323e+03, 5.292034e+03, 1.610860e+04, 1.389183e+04, -7.477679e+03, 4.396669e+03, 1.637388e+04, -4.384238e+03, -4.479632e+03, 3.669053e+03, 1.660659e+04, -3.138125e+03, -3.810639e+03, 3.067716e+03, 1.681444e+04, 2.205661e+03, -3.486730e+03, 2.530998e+03, 1.699733e+04, 3.541657e+03, -2.789475e+03, 2.081942e+03, 1.715588e+04, -6.419750e+03, -1.349094e+03, 1.732402e+03, 1.729391e+04, -3.412184e+03, -1.520739e+03, 1.412396e+03, 1.741589e+04, -1.601511e+03, -1.397792e+03, 1.100329e+03, 1.751816e+04, 1.155029e+03, -1.304754e+03, 8.286155e+02, 1.760046e+04, -1.103308e+04, 2.218581e+02, 6.236810e+02, 1.766473e+04, -2.654581e+03, -6.688353e+02, 3.763136e+02, 1.771593e+04, -3.364310e+03, -1.387471e+02, 1.691463e+02, 1.774386e+04, -3.366371e+12, 4.551509e+07, 2.521199e+03, 1.176103e+00, 4.269705e+10, -9.375992e+06, 1.089486e+03, 1.215845e+00, -2.678077e+09, 1.632330e+06, 6.917876e+02, 1.285806e+00, 5.646428e+08, -4.307335e+05, 8.992048e+02, 1.593390e+00, -6.281455e+07, 4.035231e+05, 1.038831e+03, 2.138181e+00, 3.725795e+07, 2.678653e+05, 1.679090e+03, 3.603652e+00, -1.868599e+07, 6.078925e+05, 2.794495e+03, 7.040473e+00, -2.585413e+07, 8.892713e+05, 5.187431e+03, 1.587553e+01, -6.872034e+07, 1.419539e+06, 9.710418e+03, 3.789527e+01, -5.812931e+07, 1.579306e+06, 1.744566e+04, 9.048376e+01, -7.327242e+07, 1.818701e+06, 2.839538e+04, 2.005187e+02, -6.016819e+07, 1.612661e+06, 4.199317e+04, 4.081326e+02, -4.581463e+07, 1.252723e+06, 5.561195e+04, 7.517504e+02, -3.153234e+07, 8.265349e+05, 6.688402e+04, 1.259016e+03, -1.853079e+07, 4.259439e+05, 7.406056e+04, 1.936723e+03, -1.281312e+07, 1.802667e+05, 7.674943e+04, 2.768831e+03, -5.976285e+06, -3.734133e+04, 7.529271e+04, 3.725956e+03, -3.885336e+06, -1.139315e+05, 7.068494e+04, 4.762226e+03, -1.400809e+06, -1.718468e+05, 6.415010e+04, 5.837947e+03, -8.976969e+05, -1.633241e+05, 5.674855e+04, 6.911982e+03, -2.378758e+05, -1.548497e+05, 4.928211e+04, 7.958122e+03, -4.067629e+05, -1.224513e+05, 4.221302e+04, 8.953753e+03, 3.647054e+05, -1.214788e+05, 3.566013e+04, 9.887462e+03, -3.019450e+05, -7.317725e+04, 3.004861e+04, 1.074445e+04, 2.857755e+05, -7.965496e+04, 2.512925e+04, 1.153600e+04, -1.459626e+05, -4.460431e+04, 2.100972e+04, 1.224792e+04, 1.068546e+05, -4.654852e+04, 1.751428e+04, 1.289850e+04, 1.656740e+04, -3.151584e+04, 1.455586e+04, 1.347833e+04, 3.276173e+04, -2.545561e+04, 1.216656e+04, 1.400043e+04, -2.466748e+04, -1.712349e+04, 1.020130e+04, 1.446904e+04, 1.127833e+04, -1.587340e+04, 8.510004e+03, 1.489124e+04, 1.967525e+04, -1.277787e+04, 7.060958e+03, 1.526518e+04, -5.566324e+03, -8.375268e+03, 5.904955e+03, 1.559653e+04, 6.832170e+03, -7.582035e+03, 4.940098e+03, 1.589320e+04, -1.505137e+03, -5.380298e+03, 4.129024e+03, 1.615572e+04, -4.851997e+03, -4.146360e+03, 3.449533e+03, 1.638915e+04, 6.220823e+03, -4.200678e+03, 2.847212e+03, 1.659502e+04, -2.257540e+03, -2.529572e+03, 2.356955e+03, 1.677328e+04, -6.506661e+03, -1.772864e+03, 1.953201e+03, 1.693045e+04, 1.966362e+03, -2.261074e+03, 1.566694e+03, 1.706682e+04, -2.160232e+03, -1.314709e+03, 1.240209e+03, 1.717955e+04, -6.509197e+03, -6.756691e+02, 9.705296e+02, 1.727398e+04, -3.335667e+03, -8.945697e+02, 6.952550e+02, 1.735046e+04, -1.024257e+04, 1.096345e+02, 4.408097e+02, 1.740488e+04, -4.884337e+03, -6.995646e+01, 1.680061e+02, 1.743947e+04, 5.051346e+10, -3.482968e+05, -3.302132e+01, 1.117732e-02, -6.399594e+09, 1.170259e+06, 0, 1.076335e-02, 2.378197e+07, -1.273564e+04, 2.884079e+00, 1.655900e-02, -4.193101e+07, 6.299121e+04, 2.194923e+00, 1.697297e-02, 2.186069e+06, 9.422620e+03, 3.137534e+01, 3.311800e-02, 3.955651e+06, 1.710432e+04, 5.844243e+01, 7.906922e-02, -5.048300e+06, 8.807915e+04, 1.413038e+02, 2.281002e-01, -5.834264e+06, 1.808251e+05, 4.543665e+02, 9.066052e-01, -1.717877e+07, 4.260059e+05, 1.359382e+03, 3.620625e+00, -3.208799e+07, 7.976457e+05, 3.825320e+03, 1.376715e+01, -4.503408e+07, 1.172645e+06, 9.176929e+03, 4.577239e+01, -4.518399e+07, 1.327171e+06, 1.816020e+04, 1.279439e+02, -4.202028e+07, 1.290199e+06, 2.997675e+04, 2.998951e+02, -3.158344e+07, 1.021061e+06, 4.259877e+04, 6.043667e+02, -2.250542e+07, 7.018793e+05, 5.343008e+04, 1.070337e+03, -1.237124e+07, 3.643660e+05, 6.071096e+04, 1.705578e+03, -9.254795e+06, 1.838508e+05, 6.403515e+04, 2.492654e+03, -4.016937e+06, -5.014300e+03, 6.370683e+04, 3.405094e+03, -3.183145e+06, -5.838735e+04, 6.052375e+04, 4.397082e+03, -6.326153e+05, -1.310928e+05, 5.546362e+04, 5.432589e+03, -8.980466e+05, -1.100814e+05, 4.957269e+04, 6.467941e+03, -1.845464e+05, -1.171335e+05, 4.351408e+04, 7.484261e+03, -7.330240e+04, -1.000436e+05, 3.759655e+04, 8.455153e+03, -8.536306e+04, -8.124805e+04, 3.220664e+04, 9.369683e+03, 6.271460e+04, -7.084973e+04, 2.735632e+04, 1.022133e+04, -6.549462e+04, -5.149641e+04, 2.313856e+04, 1.100420e+04, 1.042378e+05, -4.819678e+04, 1.945257e+04, 1.172164e+04, -6.586040e+03, -3.243944e+04, 1.636407e+04, 1.236958e+04, 1.937888e+04, -2.723890e+04, 1.379626e+04, 1.295960e+04, -2.094192e+04, -1.965536e+04, 1.161032e+04, 1.349253e+04, 2.879330e+04, -1.852871e+04, 9.713757e+03, 1.397336e+04, 1.432240e+04, -1.343548e+04, 8.130835e+03, 1.440101e+04, -1.821063e+04, -8.725253e+03, 6.865050e+03, 1.478482e+04, 1.419588e+04, -9.358718e+03, 5.748762e+03, 1.513083e+04, 1.055273e+03, -6.305478e+03, 4.805868e+03, 1.543573e+04, -5.662820e+03, -4.626779e+03, 4.041581e+03, 1.570792e+04, 3.620958e+02, -4.298662e+03, 3.366303e+03, 1.595011e+04, 1.279925e+03, -3.472943e+03, 2.779108e+03, 1.616176e+04, -8.119412e+03, -1.999793e+03, 2.294268e+03, 1.634600e+04, 2.703808e+03, -2.683207e+03, 1.844539e+03, 1.650646e+04, -5.608882e+03, -1.263187e+03, 1.464334e+03, 1.663925e+04, -2.539837e+03, -1.379024e+03, 1.128950e+03, 1.675095e+04, -6.360200e+03, -6.734980e+02, 8.228503e+02, 1.683877e+04, -1.233536e+04, 1.203160e+02, 5.305324e+02, 1.690457e+04, -5.730992e+03, -9.461582e+01, 1.996954e+02, 1.694608e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.824802e+05, 5.662913e+02, 0, 0, -2.089360e+05, 7.956041e+02, 5.856313e-01, 4.139750e-04, 2.204465e+05, -3.219661e+02, 1.539320e+00, 2.483850e-03, -2.076559e+05, 5.716207e+03, 3.299164e+00, 6.623600e-03, -1.630833e+06, 3.651570e+04, 3.131705e+01, 5.961240e-02, -4.750601e+06, 1.270860e+05, 2.360423e+02, 6.023336e-01, -1.059805e+07, 3.175159e+05, 1.112384e+03, 3.994031e+00, -1.908619e+07, 5.949891e+05, 3.700632e+03, 1.870919e+01, -2.366093e+07, 8.041978e+05, 9.162593e+03, 6.578187e+01, -2.229039e+07, 8.434683e+05, 1.752631e+04, 1.799168e+02, -1.954097e+07, 7.599747e+05, 2.748722e+04, 4.014783e+02, -1.339870e+07, 5.499302e+05, 3.708410e+04, 7.652249e+02, -1.029819e+07, 3.727003e+05, 4.454472e+04, 1.285347e+03, -4.368519e+06, 1.495000e+05, 4.891481e+04, 1.957839e+03, -4.419116e+06, 8.860581e+04, 5.036253e+04, 2.752876e+03, -1.481145e+06, -3.114013e+04, 4.934483e+04, 3.647707e+03, -1.131953e+06, -5.304541e+04, 4.640097e+04, 4.594923e+03, -4.087520e+05, -7.696885e+04, 4.249037e+04, 5.566846e+03, -4.277536e+05, -6.969004e+04, 3.810892e+04, 6.533158e+03, -3.981790e+04, -7.471184e+04, 3.357954e+04, 7.475552e+03, -5.532513e+04, -6.146236e+04, 2.921408e+04, 8.372805e+03, 2.297742e+04, -5.372960e+04, 2.523788e+04, 9.218872e+03, -4.526357e+04, -4.095211e+04, 2.170188e+04, 1.000775e+04, 2.858501e+04, -3.694172e+04, 1.854799e+04, 1.073977e+04, -3.310096e+04, -2.679609e+04, 1.578940e+04, 1.141043e+04, 8.050741e+04, -2.739862e+04, 1.336283e+04, 1.202398e+04, -6.328003e+04, -1.355651e+04, 1.138577e+04, 1.257725e+04, 3.556582e+04, -1.753080e+04, 9.641932e+03, 1.308660e+04, -1.740585e+03, -1.121468e+04, 8.123657e+03, 1.354004e+04, 4.908269e+03, -9.544626e+03, 6.882834e+03, 1.395006e+04, -1.374891e+04, -6.463029e+03, 5.824501e+03, 1.431834e+04, 1.616534e+04, -7.552350e+03, 4.872531e+03, 1.464918e+04, -1.772732e+04, -3.244296e+03, 4.094072e+03, 1.493915e+04, 9.689841e+03, -5.153985e+03, 3.394548e+03, 1.520003e+04, -9.718081e+03, -2.277143e+03, 2.798639e+03, 1.542337e+04, -6.633543e+02, -2.845618e+03, 2.278206e+03, 1.562014e+04, -4.278643e+03, -1.892766e+03, 1.806022e+03, 1.578510e+04, -5.433639e+03, -1.433992e+03, 1.392542e+03, 1.592207e+04, -7.648617e+03, -9.150271e+02, 1.007781e+03, 1.603088e+04, -8.612245e+03, -4.992492e+02, 6.366121e+02, 1.611080e+04, -6.343749e+03, -2.056231e+02, 2.914770e+02, 1.616025e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.135457e+04, 2.791630e+02, 0, 0, -7.955274e+04, 2.985927e+03, 1.611854e+00, 3.311800e-03, -6.493155e+05, 2.185150e+04, 2.430096e+01, 6.789190e-02, -2.078383e+06, 8.094823e+04, 2.102422e+02, 7.973158e-01, -6.000804e+06, 2.164166e+05, 1.026160e+03, 5.360976e+00, -7.509681e+06, 3.346173e+05, 3.348784e+03, 2.463110e+01, -9.709505e+06, 4.476003e+05, 7.656050e+03, 7.966162e+01, -9.777442e+06, 4.686826e+05, 1.394700e+04, 2.033979e+02, -7.272808e+06, 3.875450e+05, 2.106614e+04, 4.303630e+02, -6.067236e+06, 3.045882e+05, 2.765451e+04, 7.835942e+02, -3.743681e+06, 1.836085e+05, 3.273701e+04, 1.274002e+03, -2.204422e+06, 9.353882e+04, 3.571808e+04, 1.890326e+03, -1.657859e+06, 4.246821e+04, 3.683928e+04, 2.612254e+03, -8.290594e+05, -6.996218e+03, 3.633556e+04, 3.416065e+03, -4.247261e+05, -3.007731e+04, 3.457926e+04, 4.269476e+03, -4.641352e+05, -3.218306e+04, 3.213056e+04, 5.146662e+03, 3.361520e+04, -5.076883e+04, 2.915608e+04, 6.027337e+03, -1.771637e+05, -3.534656e+04, 2.610100e+04, 6.884571e+03, -4.187517e+04, -3.789010e+04, 2.312238e+04, 7.715656e+03, 8.157849e+04, -3.709787e+04, 2.020432e+04, 8.503474e+03, -1.077364e+05, -2.122007e+04, 1.767673e+04, 9.241847e+03, 3.794355e+04, -2.646253e+04, 1.532351e+04, 9.938986e+03, -2.130421e+03, -1.891377e+04, 1.317205e+04, 1.057852e+04, 2.458205e+03, -1.585926e+04, 1.133734e+04, 1.116822e+04, -1.024932e+04, -1.227472e+04, 9.729063e+03, 1.170859e+04, 1.302318e+04, -1.167431e+04, 8.296256e+03, 1.220175e+04, -2.645825e+03, -8.200160e+03, 7.072718e+03, 1.264649e+04, -1.946731e+04, -5.712138e+03, 6.033100e+03, 1.305017e+04, 1.908928e+04, -7.856404e+03, 5.040421e+03, 1.341373e+04, -1.921842e+04, -2.904171e+03, 4.229674e+03, 1.372996e+04, 7.815975e+03, -5.041356e+03, 3.502309e+03, 1.401481e+04, -1.222105e+04, -2.090158e+03, 2.867188e+03, 1.425719e+04, -1.443808e+03, -2.926865e+03, 2.291167e+03, 1.446851e+04, -8.489031e+03, -1.591866e+03, 1.763443e+03, 1.464092e+04, -6.705956e+03, -1.467380e+03, 1.277843e+03, 1.477936e+04, -2.081073e+04, 4.070825e+02, 8.281583e+02, 1.488046e+04, -8.711751e+03, -1.750566e+02, 3.099560e+02, 1.494590e+04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.563361e+03, 1.163545e+02, 0, 0, -4.016111e+04, 1.858785e+03, 1.077420e+00, 3.311800e-03, -2.538882e+05, 1.204296e+04, 2.087577e+01, 8.486487e-02, -8.568045e+05, 4.291307e+04, 1.658171e+02, 9.066052e-01, -1.848280e+06, 9.915324e+04, 7.465497e+02, 5.567136e+00, -2.940953e+06, 1.660291e+05, 2.247529e+03, 2.303978e+01, -3.370234e+06, 2.089797e+05, 5.011666e+03, 7.097312e+01, -3.259946e+06, 2.186080e+05, 8.892565e+03, 1.735888e+02, -3.097047e+06, 2.032584e+05, 1.336445e+04, 3.563617e+02, -1.821542e+06, 1.437017e+05, 1.764923e+04, 6.394746e+02, -1.802035e+06, 1.171823e+05, 2.118802e+04, 1.028337e+03, -1.000732e+06, 6.321832e+04, 2.372803e+04, 1.525758e+03, -7.690809e+05, 3.504376e+04, 2.503483e+04, 2.115529e+03, -3.914894e+05, 6.298728e+03, 2.528814e+04, 2.781267e+03, -3.035803e+05, -5.220347e+03, 2.468978e+04, 3.499590e+03, -1.135560e+05, -1.761802e+04, 2.348786e+04, 4.251977e+03, -1.801992e+05, -1.570171e+04, 2.191753e+04, 5.017650e+03, 1.706318e+04, -2.545515e+04, 2.006382e+04, 5.784350e+03, -6.797234e+04, -1.795386e+04, 1.815090e+04, 6.531178e+03, -1.793578e+04, -1.930896e+04, 1.628261e+04, 7.256949e+03, -2.326593e+04, -1.656161e+04, 1.443550e+04, 7.949046e+03, 2.835627e+04, -1.719413e+04, 1.268036e+04, 8.602624e+03, -3.200616e+04, -1.034425e+04, 1.113968e+04, 9.211894e+03, -1.865985e+04, -1.040495e+04, 9.723009e+03, 9.784332e+03, 3.642018e+04, -1.251177e+04, 8.326634e+03, 1.030995e+04, -3.566772e+04, -4.462584e+03, 7.200285e+03, 1.078360e+04, 1.006844e+04, -8.044621e+03, 6.164034e+03, 1.122405e+04, -1.216649e+04, -4.566143e+03, 5.198882e+03, 1.161386e+04, 2.635189e+03, -5.240412e+03, 4.341674e+03, 1.196312e+04, -9.610371e+03, -3.091591e+03, 3.584704e+03, 1.226633e+04, -5.856573e+03, -3.064976e+03, 2.898065e+03, 1.253040e+04, -1.080053e+04, -2.040908e+03, 2.251652e+03, 1.275061e+04, -1.117498e+04, -1.629984e+03, 1.631049e+03, 1.292734e+04, -1.961133e+04, -2.300963e+02, 1.034000e+03, 1.305636e+04, -1.288515e+04, -4.832654e+01, 4.255474e+02, 1.313697e+04, }; static float *solarDatasets[] = {solarDataset320, solarDataset360, solarDataset400, solarDataset440, solarDataset480, solarDataset520, solarDataset560, solarDataset600, solarDataset640, solarDataset680, solarDataset720}; static float limbDarkeningDataset320[] = { 0.087657, 0.767174, 0.658123, -1.02953, 0.703297, -0.186735}; static float limbDarkeningDataset360[] = { 0.122953, 1.01278, 0.238687, -1.12208, 1.17087, -0.424947}; static float limbDarkeningDataset400[] = { 0.123511, 1.08444, -0.405598, 0.370629, -0.240567, 0.0674778}; static float limbDarkeningDataset440[] = { 0.158489, 1.23346, -0.875754, 0.857812, -0.484919, 0.110895}; static float limbDarkeningDataset480[] = { 0.198587, 1.30507, -1.25998, 1.49727, -1.04047, 0.299516}; static float limbDarkeningDataset520[] = { 0.23695, 1.29927, -1.28034, 1.37760, -0.85054, 0.21706}; static float limbDarkeningDataset560[] = { 0.26892, 1.34319, -1.58427, 1.91271, -1.31350, 0.37295}; static float limbDarkeningDataset600[] = { 0.299804, 1.36718, -1.80884, 2.29294, -1.60595, 0.454874}; static float limbDarkeningDataset640[] = { 0.33551, 1.30791, -1.79382, 2.44646, -1.89082, 0.594769}; static float limbDarkeningDataset680[] = { 0.364007, 1.27316, -1.73824, 2.28535, -1.70203, 0.517758}; static float limbDarkeningDataset720[] = { 0.389704, 1.2448, -1.69708, 2.14061, -1.51803, 0.440004}; static float *limbDarkeningDatasets[] = {limbDarkeningDataset320, limbDarkeningDataset360, limbDarkeningDataset400, limbDarkeningDataset440, limbDarkeningDataset480, limbDarkeningDataset520, limbDarkeningDataset560, limbDarkeningDataset600, limbDarkeningDataset640, limbDarkeningDataset680, limbDarkeningDataset720}; RenderKit-ospray-85af292/modules/cpu/math/000077500000000000000000000000001464752671100204635ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/math/Distribution1D.ih000066400000000000000000000030531464752671100236520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // input: importance in 'cdf' // output: cdf of importance in 'cdf' // return sum SYCL_EXTERNAL export uniform float Distribution1D_create( const uniform int size, uniform float *uniform cdf); struct Sample1D { int idx; // relative sample index to start float frac; // relative prosition of the random sample inside // the selected bin (useful for random sample re-using) float pdf; // the pdf of sampling the position idx+frac // when frac is sampled uniformly inside the idx^th bin float prob; // the probability of sampling the idx^th bin }; inline Sample1D Distribution1D_sample(const uniform int size, const uniform float *uniform cdf, // we may sample different rows within one gang: use a varying offset // 'start' instead of a varying pointer 'cdf' const int start, const float s) { // find minimum index where cdf[i-1] <= s < cdf[i] int first = start; int len = size; while (len > 0) { const int half = len >> 1; const int mid = first + half; if (s < cdf[mid]) { len = half; } else { first = mid + 1; len -= half + 1; } } Sample1D ret; ret.idx = first - start; const float bef = first == start ? 0.0f : cdf[first - 1]; const float dpdf = cdf[first] - bef; ret.prob = dpdf; ret.pdf = dpdf * size; ret.frac = (s - bef) * rcp(dpdf); // rescale return ret; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/Distribution1D.ispc000066400000000000000000000020661464752671100242130ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Distribution1D.ih" #ifdef OSPRAY_TARGET_SYCL #include #endif // Pre-condition: size > 0 OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL export uniform float Distribution1D_create( const uniform int size, uniform float *uniform cdf) { // accumulate the function // using varying float and exclusive_scan_add(float v) is much slower uniform float sum = cdf[0]; for (uniform int i = 1; i < size; i++) cdf[i] = sum += cdf[i]; // compute reciprocal sum const uniform float rcpSum = 1.0f / sum; // next representable number in float greater than 1.0f const uniform float nextAfter1 = 0x1.000002p+0f; // normalize #ifdef OSPRAY_TARGET_SYCL for (int i = 0; i < size; ++i) { #else foreach (i = 0 ... size) { #endif const float c = cdf[i]; // handle cornercases (sum=0 -> rcpSum=inf; correct termination of sampling // with s=1.0f) const float q = c >= sum ? nextAfter1 : c * rcpSum; cdf[i] = q; } return sum; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/Distribution2D.cpp000066400000000000000000000011541464752671100240350ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Distribution2D.h" namespace ospray { Distribution2D::Distribution2D(const vec2i &size, api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { getSh()->size = size; getSh()->rcpSize = vec2f(1.f / size.x, 1.f / size.y); cdf_x = devicert::make_buffer_shared_unique( device.getDRTDevice(), size.x * size.y); cdf_y = devicert::make_buffer_shared_unique(device.getDRTDevice(), size.y); getSh()->cdf_x = cdf_x->data(); getSh()->cdf_y = cdf_y->data(); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/math/Distribution2D.h000066400000000000000000000010561464752671100235030ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "ISPCDevice.h" #include "ISPCDeviceObject.h" #include "common/OSPCommon.h" #include "common/StructShared.h" // ispc shared #include "Distribution2DShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Distribution2D : public AddStructShared { Distribution2D(const vec2i &size, api::ISPCDevice &device); BufferSharedUq cdf_x; BufferSharedUq cdf_y; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/math/Distribution2D.ih000066400000000000000000000012751464752671100236570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" // c++ shared #include "Distribution2DShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // Initialize the 2D distribution after populating the input cdf_x array // and writing f_y into cdf_y. The distribution will then compute cdf_y from f_y SYCL_EXTERNAL void Distribution2D_init(Distribution2D *uniform self); struct Sample2D { vec2f uv; float pdf; }; // inline? SYCL_EXTERNAL Sample2D Distribution2D_sample( const Distribution2D *uniform, const vec2f &s); SYCL_EXTERNAL float Distribution2D_pdf( const Distribution2D *uniform, const vec2f &uv); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/Distribution2D.ispc000066400000000000000000000027121464752671100242120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Distribution1D.ih" #include "Distribution2D.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL Sample2D Distribution2D_sample( const uniform Distribution2D *uniform self, const vec2f &s) { // use u.y to sample a row const Sample1D sy = Distribution1D_sample(self->size.y, self->cdf_y, 0, s.y); // use u.x to sample inside the row const int x0 = sy.idx * self->size.x; const Sample1D sx = Distribution1D_sample(self->size.x, self->cdf_x, x0, s.x); Sample2D ret; ret.uv = make_vec2f((sx.idx + sx.frac) * self->rcpSize.x, (sy.idx + sy.frac) * self->rcpSize.y); ret.pdf = sx.pdf * sy.pdf; return ret; } SYCL_EXTERNAL float Distribution2D_pdf( const uniform Distribution2D *uniform self, const vec2f &uv) { const int idy = clamp((int)(uv.y * self->size.y), 0, self->size.y - 1); const float befy = idy == 0 ? 0.0f : self->cdf_y[idy - 1]; const float pdf_y = (self->cdf_y[idy] - befy) * self->size.y; const int idx = clamp((int)(uv.x * self->size.x), 0, self->size.x - 1); const int x0 = idy * self->size.x; const float befx = idx == 0 ? 0.0f : self->cdf_x[x0 + idx - 1]; const float pdf_x = (self->cdf_x[x0 + idx] - befx) * self->size.x; return pdf_x * pdf_y; } SYCL_EXTERNAL void Distribution2D_init(Distribution2D *uniform self) { // initialize the y distribution Distribution1D_create(self->size.y, self->cdf_y); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/Distribution2DShared.h000066400000000000000000000007011464752671100246260ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Distribution2D { vec2i size; // 1/size vec2f rcpSize; // size.x*size.y elements float *cdf_x; // size.y elements float *cdf_y; #ifdef __cplusplus Distribution2D() : size(0), rcpSize(0.f), cdf_x(nullptr), cdf_y(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/math/halton.c000066400000000000000000000001421464752671100221110ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "halton.inl" RenderKit-ospray-85af292/modules/cpu/math/halton.ih000066400000000000000000000063431464752671100223000ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL #include "halton.inl" #else extern const uniform unsigned int halton_perm3[243]; extern const uniform unsigned int halton_perm5[125]; extern const uniform unsigned int halton_perm7[343]; #endif inline uint32 reverseBits(uint32 index) { index = (index << 16) | (index >> 16); index = ((index & 0x00ff00ff) << 8) | ((index & 0xff00ff00) >> 8); index = ((index & 0x0f0f0f0f) << 4) | ((index & 0xf0f0f0f0) >> 4); index = ((index & 0x33333333) << 2) | ((index & 0xcccccccc) >> 2); index = ((index & 0x55555555) << 1) | ((index & 0xaaaaaaaa) >> 1); return index; } inline float Halton_sample2(uint32 index) { return to_float_unorm(reverseBits(index)); } inline float Halton_sample3(const unsigned int index) { // Mirek note: // with normalization using 1.f instead of original 0x1.fffffcp-1 // it generates results closer to the plain iterative implementation, // (before results were usually smaller by 1-2 ULPs) // but on the other hand results may be equal to 1.f, so the range // [0-1) is not guaranteed return (halton_perm3[index % 243u] * 14348907u + halton_perm3[(index / 243u) % 243u] * 59049u + halton_perm3[(index / 59049u) % 243u] * 243u + halton_perm3[(index / 14348907u) % 243u]) * (float)(1.0 / 3486784401u); } // Permuted Halton sequence base-5 inline float PermHalton_sample5(const unsigned int index) { return (halton_perm5[index % 125u] * 1953125u + halton_perm5[(index / 125u) % 125u] * 15625u + halton_perm5[(index / 15625u) % 125u] * 125u + halton_perm5[(index / 1953125u) % 125u]) * (float)(1.0 / 244140625u); } // Permuted Halton sequence base-7 inline float PermHalton_sample7(const unsigned int index) { return (halton_perm7[index % 343u] * 117649u + halton_perm7[(index / 343u) % 343u] * 343u + halton_perm7[(index / 117649u) % 343u]) * (float)(1.0 / 40353607u); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/halton.inl000066400000000000000000000164551464752671100224670ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. OSPRAY_GLOBAL const unsigned int halton_perm3[243] = { 0, 81, 162, 27, 108, 189, 54, 135, 216, 9, 90, 171, 36, 117, 198, 63, 144, 225, 18, 99, 180, 45, 126, 207, 72, 153, 234, 3, 84, 165, 30, 111, 192, 57, 138, 219, 12, 93, 174, 39, 120, 201, 66, 147, 228, 21, 102, 183, 48, 129, 210, 75, 156, 237, 6, 87, 168, 33, 114, 195, 60, 141, 222, 15, 96, 177, 42, 123, 204, 69, 150, 231, 24, 105, 186, 51, 132, 213, 78, 159, 240, 1, 82, 163, 28, 109, 190, 55, 136, 217, 10, 91, 172, 37, 118, 199, 64, 145, 226, 19, 100, 181, 46, 127, 208, 73, 154, 235, 4, 85, 166, 31, 112, 193, 58, 139, 220, 13, 94, 175, 40, 121, 202, 67, 148, 229, 22, 103, 184, 49, 130, 211, 76, 157, 238, 7, 88, 169, 34, 115, 196, 61, 142, 223, 16, 97, 178, 43, 124, 205, 70, 151, 232, 25, 106, 187, 52, 133, 214, 79, 160, 241, 2, 83, 164, 29, 110, 191, 56, 137, 218, 11, 92, 173, 38, 119, 200, 65, 146, 227, 20, 101, 182, 47, 128, 209, 74, 155, 236, 5, 86, 167, 32, 113, 194, 59, 140, 221, 14, 95, 176, 41, 122, 203, 68, 149, 230, 23, 104, 185, 50, 131, 212, 77, 158, 239, 8, 89, 170, 35, 116, 197, 62, 143, 224, 17, 98, 179, 44, 125, 206, 71, 152, 233, 26, 107, 188, 53, 134, 215, 80, 161, 242, }; OSPRAY_GLOBAL const unsigned int halton_perm5[125] = { 0, 75, 50, 25, 100, 15, 90, 65, 40, 115, 10, 85, 60, 35, 110, 5, 80, 55, 30, 105, 20, 95, 70, 45, 120, 3, 78, 53, 28, 103, 18, 93, 68, 43, 118, 13, 88, 63, 38, 113, 8, 83, 58, 33, 108, 23, 98, 73, 48, 123, 2, 77, 52, 27, 102, 17, 92, 67, 42, 117, 12, 87, 62, 37, 112, 7, 82, 57, 32, 107, 22, 97, 72, 47, 122, 1, 76, 51, 26, 101, 16, 91, 66, 41, 116, 11, 86, 61, 36, 111, 6, 81, 56, 31, 106, 21, 96, 71, 46, 121, 4, 79, 54, 29, 104, 19, 94, 69, 44, 119, 14, 89, 64, 39, 114, 9, 84, 59, 34, 109, 24, 99, 74, 49, 124, }; OSPRAY_GLOBAL const unsigned int halton_perm7[343] = { 0, 98, 245, 147, 49, 196, 294, 14, 112, 259, 161, 63, 210, 308, 35, 133, 280, 182, 84, 231, 329, 21, 119, 266, 168, 70, 217, 315, 7, 105, 252, 154, 56, 203, 301, 28, 126, 273, 175, 77, 224, 322, 42, 140, 287, 189, 91, 238, 336, 2, 100, 247, 149, 51, 198, 296, 16, 114, 261, 163, 65, 212, 310, 37, 135, 282, 184, 86, 233, 331, 23, 121, 268, 170, 72, 219, 317, 9, 107, 254, 156, 58, 205, 303, 30, 128, 275, 177, 79, 226, 324, 44, 142, 289, 191, 93, 240, 338, 5, 103, 250, 152, 54, 201, 299, 19, 117, 264, 166, 68, 215, 313, 40, 138, 285, 187, 89, 236, 334, 26, 124, 271, 173, 75, 222, 320, 12, 110, 257, 159, 61, 208, 306, 33, 131, 278, 180, 82, 229, 327, 47, 145, 292, 194, 96, 243, 341, 3, 101, 248, 150, 52, 199, 297, 17, 115, 262, 164, 66, 213, 311, 38, 136, 283, 185, 87, 234, 332, 24, 122, 269, 171, 73, 220, 318, 10, 108, 255, 157, 59, 206, 304, 31, 129, 276, 178, 80, 227, 325, 45, 143, 290, 192, 94, 241, 339, 1, 99, 246, 148, 50, 197, 295, 15, 113, 260, 162, 64, 211, 309, 36, 134, 281, 183, 85, 232, 330, 22, 120, 267, 169, 71, 218, 316, 8, 106, 253, 155, 57, 204, 302, 29, 127, 274, 176, 78, 225, 323, 43, 141, 288, 190, 92, 239, 337, 4, 102, 249, 151, 53, 200, 298, 18, 116, 263, 165, 67, 214, 312, 39, 137, 284, 186, 88, 235, 333, 25, 123, 270, 172, 74, 221, 319, 11, 109, 256, 158, 60, 207, 305, 32, 130, 277, 179, 81, 228, 326, 46, 144, 291, 193, 95, 242, 340, 6, 104, 251, 153, 55, 202, 300, 20, 118, 265, 167, 69, 216, 314, 41, 139, 286, 188, 90, 237, 335, 27, 125, 272, 174, 76, 223, 321, 13, 111, 258, 160, 62, 209, 307, 34, 132, 279, 181, 83, 230, 328, 48, 146, 293, 195, 97, 244, 342, }; RenderKit-ospray-85af292/modules/cpu/math/interpolation.ih000066400000000000000000000041441464752671100236770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // x should be between [0..size-1] inline float interp1DLinear( float x, const uniform float *uniform f, uniform int size) { float xc = clamp(x, 0.f, (float)(size - 1)); float s = xc - floor(xc); int x0 = min((int)xc, size - 1); int x1 = min(x0 + 1, size - 1); return lerp(s, f[x0], f[x1]); } // p should be between [0..size-1] inline float interp2DLinear( vec2f p, const uniform float *uniform f, uniform vec2i size) { float xc = clamp(p.x, 0.f, (float)(size.x - 1)); float yc = clamp(p.y, 0.f, (float)(size.y - 1)); float sx = xc - floor(xc); float sy = yc - floor(yc); int x0 = min((int)xc, size.x - 1); int x1 = min(x0 + 1, size.x - 1); int y0 = min((int)yc, size.y - 1); int y1 = min(y0 + 1, size.y - 1); int ny = size.x; float f0 = lerp(sx, f[x0 + y0 * ny], f[x1 + y0 * ny]); float f1 = lerp(sx, f[x0 + y1 * ny], f[x1 + y1 * ny]); return lerp(sy, f0, f1); } // p should be between [0..size-1] inline float interp3DLinear( vec3f p, const uniform float *uniform f, uniform vec3i size) { float xc = clamp(p.x, 0.f, (float)(size.x - 1)); float yc = clamp(p.y, 0.f, (float)(size.y - 1)); float zc = clamp(p.z, 0.f, (float)(size.z - 1)); float sx = xc - floor(xc); float sy = yc - floor(yc); float sz = zc - floor(zc); int x0 = min((int)xc, size.x - 1); int x1 = min(x0 + 1, size.x - 1); int y0 = min((int)yc, size.y - 1); int y1 = min(y0 + 1, size.y - 1); int z0 = min((int)zc, size.z - 1); int z1 = min(z0 + 1, size.z - 1); int ny = size.x; int nz = size.x * size.y; float f00 = lerp(sx, f[x0 + y0 * ny + z0 * nz], f[x1 + y0 * ny + z0 * nz]); float f01 = lerp(sx, f[x0 + y1 * ny + z0 * nz], f[x1 + y1 * ny + z0 * nz]); float f10 = lerp(sx, f[x0 + y0 * ny + z1 * nz], f[x1 + y0 * ny + z1 * nz]); float f11 = lerp(sx, f[x0 + y1 * ny + z1 * nz], f[x1 + y1 * ny + z1 * nz]); float f0 = lerp(sy, f00, f01); float f1 = lerp(sy, f10, f11); return lerp(sz, f0, f1); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/random.ih000066400000000000000000000242171464752671100222730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "halton.ih" #include "rkcommon/math/vec.ih" #include "sobol.ih" OSPRAY_BEGIN_ISPC_NAMESPACE /////////////////////////////////////////////////////////////////////////////// // Hash functions inline uint32 MurmurHash3_mix(uint32 hash, uint32 k) { const uint32 c1 = 0xcc9e2d51; const uint32 c2 = 0x1b873593; const uint32 r1 = 15; const uint32 r2 = 13; const uint32 m = 5; const uint32 n = 0xe6546b64; k *= c1; k = (k << r1) | (k >> (32 - r1)); k *= c2; hash ^= k; hash = ((hash << r2) | (hash >> (32 - r2))) * m + n; return hash; } inline uint32 MurmurHash3_finalize(uint32 hash) { hash ^= hash >> 16; hash *= 0x85ebca6b; hash ^= hash >> 13; hash *= 0xc2b2ae35; hash ^= hash >> 16; return hash; } // https://github.com/skeeto/hash-prospector/ inline uint32 tripleHash(uint32 x) { x ^= x >> 17; x *= 0xed5ad4bb; x ^= x >> 11; x *= 0xac4c1b51; x ^= x >> 15; x *= 0x31848bab; x ^= x >> 14; return x; } // https://github.com/skeeto/hash-prospector/issues/12#issuecomment-1105792182 /* but https://github.com/skeeto/hash-prospector/issues/28 inline uint32 hash32(uint32 hash) { hash ^= hash >> 16; hash *= 0x21f0aaad; hash ^= hash >> 15; hash *= 0xf35a2d97; hash ^= hash >> 15; return hash; }*/ inline uint32 hashToRandom(uint32 value, uint32 scramble) { value = (value ^ 61) ^ scramble; value += value << 3; value ^= value >> 4; value *= 0x27d4eb2d; return value; } /////////////////////////////////////////////////////////////////////////////// // Utility functions inline float CranleyPattersonRotation(float x, float dx) { x += dx; if (x >= 1.f) x -= 1.f; return x; } inline vec2f CranleyPattersonRotation(vec2f v, vec2f dv) { const float x = CranleyPattersonRotation(v.x, dv.x); const float y = CranleyPattersonRotation(v.y, dv.y); return make_vec2f(x, y); } inline float radicalInverse(uint32 idx, const uint32 base) { float f = 0.f, g = 1.0f, inv = 1.0f / base; while (idx > 0) { g *= inv; f += (idx % base) * g; idx /= base; } return f; } ////////////////////V/////////////////////////////////////////////////////////// // PCG pseudo-random number generator http://www.pcg-random.org/ struct RandomSampler { uint64 state; uint32 stream; }; inline uint32 RandomSampler_pcg32(varying RandomSampler *uniform self) { uint64 oldstate = self->state; self->state = oldstate * 6364136223846793005ULL + (self->stream | 1u); uint32 xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; uint32 rot = oldstate >> 59u; return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); } inline float RandomSampler_getFloat(varying RandomSampler *uniform self) { return to_float_unorm(RandomSampler_pcg32(self)); } inline void RandomSampler_init( varying RandomSampler *uniform self, uint32 seed, uint32 stream) { self->state = 0; self->stream = (stream << 1u) | 1u; // hash seed to reduce correlation artefacts self->state = MurmurHash3_mix(self->state, seed); self->state = MurmurHash3_finalize(self->state); RandomSampler_pcg32(self); self->state += seed; RandomSampler_pcg32(self); } inline void RandomSampler_init(varying RandomSampler *uniform self, uint32 seed) { RandomSampler_init(self, seed, 0); } /////////////////////////////////////////////////////////////////////////////// // TEA - Random numbers based on Tiny Encryption Algorithm inline void tea8(uint32 &_v0, uint32 &_v1) { uint32 v0 = _v0; // operate on registers to avoid slowdown uint32 v1 = _v1; uint32 sum = 0; for (uniform int i = 0; i < 8; i++) { // just 8 instead of 32 rounds sum += 0x9e3779b9; v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + sum) ^ ((v1 >> 5) + 0xc8013ea4); v1 += ((v0 << 4) + 0xad90777d) ^ (v0 + sum) ^ ((v0 >> 5) + 0x7e95761e); } _v0 = v0; _v1 = v1; } struct RandomTEA { vec2ui state; }; inline void RandomTEA_Constructor( varying RandomTEA *uniform self, const uint32 idx, const uint32 seed) { self->state.x = idx; self->state.y = seed; } inline varying vec2f RandomTEA_getFloats(varying RandomTEA *uniform self) { tea8(self->state.x, self->state.y); return to_float_unorm(self->state); } /////////////////////////////////////////////////////////////////////////////// // LCG - Linear Congruential Generator inline uint32 LCG_init(uint32 pixelID, uint32 sampleIndex) { uint32 state = 0; state = MurmurHash3_mix(state, pixelID); state = MurmurHash3_mix(state, sampleIndex); state = MurmurHash3_finalize(state); return state; } inline uint32 LCG_next(uint32 value) { const uint32 m = 1664525; const uint32 n = 1013904223; return value * m + n; } inline float LCG_getFloat(uint32 &state) { state = LCG_next(state); return to_float_unorm(state); } inline vec2f LCG_getFloat2(uint32 &state) { const float x = LCG_getFloat(state); const float y = LCG_getFloat(state); return make_vec2f(x, y); } inline vec3f LCG_getFloat3(uint32 &state) { const float x = LCG_getFloat(state); const float y = LCG_getFloat(state); const float z = LCG_getFloat(state); return make_vec3f(x, y, z); } // https://psychopath.io/post/2021_01_30_building_a_better_lk_hash inline uint32 OwenHash2(uint32 x, uint32 seed) { x ^= x * 0x3d20adea; x += seed; x *= (seed >> 16) | 1; x ^= x * 0x05526c56; x ^= x * 0x53a22864; return x; } inline uint32 OwenScramble2(uint32 x, uint32 seed) { x = reverseBits(x); x = OwenHash2(x, seed); return reverseBits(x); } inline uint32 OwenScramble4(uint32 x, uint32 seed) { x = reverseBits(x); // https://psychopath.io/post/2022_08_14_a_fast_hash_for_base_4_owen_scrambling x ^= x * 0x3d20adea; x ^= (x >> 1) & (x << 1) & 0x55555555; x += seed; x *= (seed >> 16) | 1; x ^= (x >> 1) & (x << 1) & 0x55555555; x ^= x * 0x05526c56; x ^= x * 0x53a22864; return reverseBits(x); } #define SCRAMBLE0 0x9374b0d3 #define SCRAMBLE1 0x1ec38426 #define SCRAMBLE2 0xdb81c29c #define SCRAMBLE3 0x5628372b #define SCRAMBLE4 0xbcb745bd #ifdef OSPRAY_PATHTRACER_DEBUG // alternative drop-in implementations with same interface for debugging #include "random_debug.inl" #else //////////////////////////////////////////////////////////////////////////////// // Low-discrepancy sampler: shuffled (padding 5 dimensions), scrambled Sobol // Burley, "Practical Hash-based Owen Scrambling", 2020 struct LDSampler { uint32 revIndex; // bit-reversed sample index uint32 scramble; // seed for scrambling the samples uint32 baseIndexLight; // when sequence is split (blue noise) // valid bits TODO should move to global PT Context uniform uint32 idxMask; uniform uint32 idxMaskLight; }; inline void LDSampler_init(varying LDSampler &self, const uint32 seed, const uint32 sampleIndex, const uint32 sampleOffsetLight = 0, const uniform uint32 bits = 16, const uniform uint32 bitsLight = 16) { self.revIndex = reverseBits(sampleIndex); self.scramble = seed; // avoid zero! self.baseIndexLight = sampleOffsetLight; self.idxMask = bits > 31 ? -1u : ~(-1u >> bits); self.idxMaskLight = bitsLight > 31 ? -1u : ~(-1u >> bitsLight); } inline void LDSampler_nextGroup(LDSampler &self) { // padding: new decorrelated group self.scramble = tripleHash(self.scramble); } inline float LDSamplerScramble(const uint32 sample, const uint32 scramble) { return to_float_unorm(reverseBits(OwenHash2(sample, scramble))); } inline vec2f LDSampler_get3LightSamples(const LDSampler &self, const uniform uint32 idx, const bool split, float &ss) { uint32 revIndex = split ? reverseBits(self.baseIndexLight + idx) : self.revIndex; revIndex = OwenHash2(revIndex, self.scramble); // shuffle revIndex &= split ? self.idxMaskLight : self.idxMask; // sample const uint32 r0 = reverseBits(revIndex); const vec2ui r12 = Sobol_revSample2(revIndex); vec2f res; res.x = LDSamplerScramble(r0, self.scramble ^ SCRAMBLE0); res.y = LDSamplerScramble(r12.x, self.scramble ^ SCRAMBLE1); ss = LDSamplerScramble(r12.y, self.scramble ^ SCRAMBLE2); return res; } // the first 3 dims are already returned // the remaining 4th dim needs finalization (scrambling) inline vec2f LDSampler_getNext4Samples(LDSampler &self, float &ss, uint32 &u) { LDSampler_nextGroup(self); // shuffle const uint32 revIndex = OwenHash2(self.revIndex, self.scramble) & self.idxMask; // sample const uint32 r0 = reverseBits(revIndex); const vec3ui r123 = Sobol_revSample3(revIndex); vec2f res; res.x = LDSamplerScramble(r0, self.scramble ^ SCRAMBLE0); res.y = LDSamplerScramble(r123.x, self.scramble ^ SCRAMBLE1); ss = LDSamplerScramble(r123.y, self.scramble ^ SCRAMBLE2); u = r123.z; return res; } inline float LDSampler_finalizeDim3(const LDSampler &self, const uint32 revRes) { return LDSamplerScramble(revRes, self.scramble ^ SCRAMBLE3); } // the first 2 dims are already returned (the best ones) // the next remaining 3 dims need finalization (scrambling) inline vec2f LDSampler_getNext5Samples(LDSampler &self, vec3ui &ss) { LDSampler_nextGroup(self); // shuffle const uint32 revIndex = OwenHash2(self.revIndex, self.scramble) & self.idxMask; // sample const uint32 r0 = reverseBits(revIndex); const vec4ui r1234 = Sobol_revSample4(revIndex); vec2f res; res.x = LDSamplerScramble(r0, self.scramble ^ SCRAMBLE0); res.y = LDSamplerScramble(r1234.x, self.scramble ^ SCRAMBLE1); ss = make_vec3ui(r1234.y, r1234.z, r1234.w); return res; } inline vec2f LDSampler_finalizeDim23( const LDSampler &self, const vec3ui &revRes) { vec2f res; res.x = LDSamplerScramble(revRes.x, self.scramble ^ SCRAMBLE2); res.y = LDSamplerScramble(revRes.y, self.scramble ^ SCRAMBLE3); return res; } inline float LDSampler_finalizeDim4(const LDSampler &self, const vec3ui &revRes) { return LDSamplerScramble(revRes.z, self.scramble ^ SCRAMBLE4); } #undef SCRAMBLE0 #undef SCRAMBLE1 #undef SCRAMBLE2 #undef SCRAMBLE3 #undef SCRAMBLE4 #endif /////////////////////////////////////////////////////////////////////////////// // Halton - low discrepancy halton sequence; first two dimensions; no state inline varying vec2f HaltonSequence_get2D(varying uint32 idx) { return make_vec2f(Halton_sample2(idx), Halton_sample3(idx)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/random_debug.inl000066400000000000000000000114471464752671100236240ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #if 0 //////////////////////////////////////////////////////////////////////////////// // pure pseudo random sampler as debugging baseline struct LDSampler { RandomSampler rng; }; inline void LDSampler_init(varying LDSampler &self, const uint32 seed, const uint32 sampleIndex, const uint32 sampleOffsetLight = 0, const uniform uint32 bits = 16, const uniform uint32 bitsLight = 16) { RandomSampler_init(&self.rng, seed, sampleIndex); } inline uint32 LDSampler_getIndex(LDSampler &self) { return self.rng.stream; // dummy } inline void LDSampler_nextGroup(LDSampler &) {} inline vec2f RandomSampler_getFloat2(LDSampler &self) { vec2f res; res.x = RandomSampler_getFloat(&self.rng); res.y = RandomSampler_getFloat(&self.rng); return res; } inline vec2f LDSampler_get3LightSamples(LDSampler &self, const uint32, const bool, float &ss) { ss = RandomSampler_getFloat(&self.rng); return RandomSampler_getFloat2(self); } inline vec2f LDSampler_getNext4Samples(LDSampler &self, float &ss, uint32 &) { return LDSampler_get3LightSamples(self, 0, true, ss); } inline float LDSampler_finalizeDim3(LDSampler &self, const uint32) { return RandomSampler_getFloat(&self.rng); } inline vec2f LDSampler_getNext5Samples(LDSampler &self, vec3ui &) { return RandomSampler_getFloat2(self); } inline vec2f LDSampler_finalizeDim23(LDSampler &self, const vec3ui &) { return RandomSampler_getFloat2(self); } inline float LDSampler_finalizeDim4(LDSampler &self, const vec3ui &) { return RandomSampler_getFloat(&self.rng); } #else //////////////////////////////////////////////////////////////////////////////// // plain Burley implementation to verify optimized version struct LDSampler { uint32 index; // sample index uint32 scramble; // seed for scrambling the samples uint32 baseIndexLight; // when sequence is split (blue noise) float s0; float s1; float s2; float s3; float s4; // valid bits TODO should move to global PT Context uniform uint32 idxMask; uniform uint32 idxMaskLight; }; inline void LDSampler_init(varying LDSampler &self, const uint32 seed, const uint32 sampleIndex, const uint32 sampleOffsetLight = 0, const uniform uint32 bits = 16, const uniform uint32 bitsLight = 16) { self.index = sampleIndex; self.scramble = seed; // avoid zero! self.baseIndexLight = sampleOffsetLight; self.idxMask = bits > 31 ? -1u : (1u << bits) - 1; self.idxMaskLight = bitsLight > 31 ? -1u : (1u << bitsLight) - 1; } inline void LDSampler_nextGroup(LDSampler &self) { // padding: new decorrelated group self.scramble = tripleHash(self.scramble); } inline uint32 LDSampler_shuffleIndex( const uint32 index, const uint32 scramble, const uint32 mask) { return OwenScramble2(index, scramble) & mask; } inline uint32 LDSampler_shuffleIndex(const LDSampler &self) { return LDSampler_shuffleIndex(self.index, self.scramble, self.idxMask); } inline void LDSampler_sampleGroup(LDSampler &self, const uint32 index) { // sample const uint32 r0 = Sobol_sample(index, 0); const uint32 r1 = Sobol_sample(index, 1); const uint32 r2 = Sobol_sample(index, 2); const uint32 r3 = Sobol_sample(index, 3); const uint32 r4 = Sobol_sample(index, 4); // scramble self.s0 = to_float_unorm(OwenScramble2(r0, self.scramble ^ SCRAMBLE0)); self.s1 = to_float_unorm(OwenScramble2(r1, self.scramble ^ SCRAMBLE1)); self.s2 = to_float_unorm(OwenScramble2(r2, self.scramble ^ SCRAMBLE2)); self.s3 = to_float_unorm(OwenScramble2(r3, self.scramble ^ SCRAMBLE3)); self.s4 = to_float_unorm(OwenScramble2(r4, self.scramble ^ SCRAMBLE4)); } inline vec2f LDSampler_get3LightSamples(const LDSampler &self, const uniform uint32 idx, const bool split, float &ss) { LDSampler lds; lds.scramble = self.scramble; const uint32 index = split ? LDSampler_shuffleIndex( self.baseIndexLight + idx, self.scramble, self.idxMaskLight) : LDSampler_shuffleIndex(self); LDSampler_sampleGroup(lds, index); ss = lds.s2; return make_vec2f(lds.s0, lds.s1); } inline vec2f LDSampler_getNext4Samples(LDSampler &self, float &ss, uint32 &) { LDSampler_nextGroup(self); LDSampler_sampleGroup(self, LDSampler_shuffleIndex(self)); ss = self.s2; return make_vec2f(self.s0, self.s1); } inline float LDSampler_finalizeDim3(const LDSampler &self, const uint32) { return self.s3; } inline vec2f LDSampler_getNext5Samples(LDSampler &self, vec3ui &) { LDSampler_nextGroup(self); LDSampler_sampleGroup(self, LDSampler_shuffleIndex(self)); return make_vec2f(self.s0, self.s1); } inline vec2f LDSampler_finalizeDim23(const LDSampler &self, const vec3ui &) { return make_vec2f(self.s2, self.s3); } inline float LDSampler_finalizeDim4(const LDSampler &self, const vec3ui &) { return self.s4; } #endif RenderKit-ospray-85af292/modules/cpu/math/sampling.h000066400000000000000000000014101464752671100224420ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // utility library containing sampling functions // convention is to return the sample (vec3f) generated from given vec2f // 's'ample as last parameter sampling functions often come in pairs: sample and // pdf (needed later for MIS) good reference is "Total Compendium" by Philip // Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/ #include "rkcommon/math/rkmath.h" namespace ospray { inline float uniformSampleConePDF(const float cosAngle) { return rcp(float(two_pi) * (1.0f - cosAngle)); } inline float uniformSampleRingPDF(const float radius, const float innerRadius) { return rcp(float(pi) * ((radius * radius) - (innerRadius * innerRadius))); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/math/sampling.ih000066400000000000000000000135031464752671100226210ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once /*! \brief utility library containing sampling functions */ // convention is to return the sample (vec3f) generated from given vec2f // 's'ample as last parameter sampling functions often come in pairs: sample and // pdf (needed later for MIS) good reference is "Total Compendium" by Philip // Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/ #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline vec3f cartesian( const float phi, const float sinTheta, const float cosTheta) { float sinPhi, cosPhi; sincos(phi, &sinPhi, &cosPhi); return make_vec3f(cosPhi * sinTheta, sinPhi * sinTheta, cosTheta); } inline vec3f cartesian(const float phi, const float cosTheta) { return cartesian(phi, cos2sin(cosTheta), cosTheta); } /// uniform sampling of hemisphere oriented along the +z-axis //////////////////////////////////////////////////////////////////////////////// inline vec3f uniformSampleHemisphere(const vec2f s) { const float phi = (float)two_pi * s.x; const float cosTheta = s.y; const float sinTheta = cos2sin(s.y); return cartesian(phi, sinTheta, cosTheta); } inline float uniformSampleHemispherePDF() { return one_over_two_pi; } /// cosine-weighted sampling of hemisphere oriented along the +z-axis //////////////////////////////////////////////////////////////////////////////// inline vec3f cosineSampleHemisphere(const vec2f s) { const float phi = (float)two_pi * s.x; const float cosTheta = sqrt(s.y); const float sinTheta = sqrt(1.0f - s.y); return cartesian(phi, sinTheta, cosTheta); } inline float cosineSampleHemispherePDF(const vec3f &dir) { return dir.z * (float)one_over_pi; } inline float cosineSampleHemispherePDF(float cosTheta) { return cosTheta * (float)one_over_pi; } /// power cosine-weighted sampling of hemisphere oriented along the +z-axis //////////////////////////////////////////////////////////////////////////////// inline vec3f powerCosineSampleHemisphere(const float n, const vec2f &s) { const float phi = (float)two_pi * s.x; const float cosTheta = pow(s.y, 1.0f / (n + 1.0f)); return cartesian(phi, cosTheta); } inline float powerCosineSampleHemispherePDF( const float cosTheta, const float n) // TODO: order of arguments { return (n + 1.0f) * (float)one_over_two_pi * pow(cosTheta, n); } inline float powerCosineSampleHemispherePDF( const vec3f &dir, const float n) // TODO: order of arguments { return (n + 1.0f) * (float)one_over_two_pi * pow(dir.z, n); } /// uniform sampling of cone of directions oriented along the +z-axis //////////////////////////////////////////////////////////////////////////////// inline vec3f uniformSampleCone(const float cosAngle, const vec2f &s) { const float phi = (float)two_pi * s.x; const float cosTheta = 1.0f - s.y * (1.0f - cosAngle); return cartesian(phi, cosTheta); } inline float uniformSampleConePDF(const float cosAngle) { return rcp((float)two_pi * (1.0f - cosAngle)); } #ifndef OSPRAY_TARGET_SYCL inline uniform float uniformSampleConePDF(const uniform float cosAngle) { return rcp((float)two_pi * (1.0f - cosAngle)); } #endif /// uniform sampling of ring //////////////////////////////////////////////////////////////////////////////// inline vec3f uniformSampleRing( const float radius, const float innerRadius, const vec2f &s) { const float r = sqrtf(lerp(s.x, sqr(innerRadius), sqr(radius))); const float phi = (float)two_pi * s.y; float sinPhi, cosPhi; sincos(phi, &sinPhi, &cosPhi); return make_vec3f(r * cosPhi, r * sinPhi, 0.f); } inline float uniformSampleRingPDF(const float radius, const float innerRadius) { return rcp((float)pi * (sqr(radius) - sqr(innerRadius))); } #ifndef OSPRAY_TARGET_SYCL inline uniform float uniformSampleRingPDF( const uniform float radius, const uniform float innerRadius) { return rcp((float)pi * (sqr(radius) - sqr(innerRadius))); } #endif /// uniform sampling of disk //////////////////////////////////////////////////////////////////////////////// // TODO: just use uniformSampleRing with innerRadius = 0? inline vec3f uniformSampleDisk(const float radius, const vec2f &s) { const float r = sqrtf(s.x) * radius; const float phi = (float)two_pi * s.y; float sinPhi, cosPhi; sincos(phi, &sinPhi, &cosPhi); return make_vec3f(r * cosPhi, r * sinPhi, 0.f); } inline float uniformSampleDiskPDF(const float radius) { return rcp((float)pi * sqr(radius)); } #ifndef OSPRAY_TARGET_SYCL inline uniform float uniformSampleDiskPDF(const uniform float radius) { return rcp((float)pi * sqr(radius)); } #endif /// uniform sampling of triangle abc //////////////////////////////////////////////////////////////////////////////// inline vec2f uniformSampleTriangleUV(const vec2f &s) { const float su = sqrtf(s.x); vec2f uv; uv.x = s.y * su; uv.y = (1.0f - s.y) * su; return uv; } inline vec3f uniformSampleTriangle( const vec3f &a, const vec3f &b, const vec3f &c, const vec2f &s) { const vec2f uv = uniformSampleTriangleUV(s); return a + uv.x * (b - a) + uv.y * (c - a); } inline float uniformSampleTrianglePDF( const vec3f &a, const vec3f &b, const vec3f &c) { return 2.0f * rcp(length(cross(a - c, b - c))); } /// uniform sampling of sphere //////////////////////////////////////////////////////////////////////////////// inline vec3f uniformSampleSphere(const float radius, const vec2f s) { const float phi = (float)two_pi * s.x; const float cosTheta = radius * (1.f - 2.f * s.y); const float sinTheta = 2.f * radius * sqrt(s.y * (1.f - s.y)); return cartesian(phi, sinTheta, cosTheta); } inline float uniformSampleSpherePDF(const float radius) { return rcp((float)four_pi * sqr(radius)); } #ifndef OSPRAY_TARGET_SYCL inline uniform float uniformSampleSpherePDF(const uniform float radius) { return rcp((float)four_pi * sqr(radius)); } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/sobol.c000066400000000000000000000001411464752671100217410ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "sobol.inl" RenderKit-ospray-85af292/modules/cpu/math/sobol.ih000066400000000000000000000056431464752671100221330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_TARGET_SYCL #include "sobol.inl" #else extern const uniform unsigned int Sobol_revMatrices[4 * 32]; extern const uniform unsigned int Sobol_matrices[5 * 52]; #endif // compute components 1 and 2 of the Sobol'-sequence (count starting from 0) inline vec2ui Sobol_revSample2(uint32 revIndex) { vec2ui result = make_vec2ui(0); for (uniform uint32 i = 0; revIndex; revIndex <<= 1, i += 4) { if (revIndex & 0x80000000u) { result.x ^= Sobol_revMatrices[i]; result.y ^= Sobol_revMatrices[i + 1]; } } return result; } // compute components 1 to 3 of the Sobol'-sequence (count starting from 0) inline vec3ui Sobol_revSample3(uint32 revIndex) { vec3ui result = make_vec3ui(0); for (uniform uint32 i = 0; revIndex; revIndex <<= 1, i += 4) { if (revIndex & 0x80000000u) { result.x ^= Sobol_revMatrices[i]; result.y ^= Sobol_revMatrices[i + 1]; result.z ^= Sobol_revMatrices[i + 2]; } } return result; } // compute components 1 to 4 of the Sobol'-sequence (count starting from 0) inline vec4ui Sobol_revSample4(uint32 revIndex) { vec4ui result = make_vec4ui(0); for (uniform uint32 i = 0; revIndex; revIndex <<= 1, i += 4) { if (revIndex & 0x80000000u) { result.x ^= Sobol_revMatrices[i]; result.y ^= Sobol_revMatrices[i + 1]; result.z ^= Sobol_revMatrices[i + 2]; result.w ^= Sobol_revMatrices[i + 3]; } } return result; } inline uint32 Sobol_sample(uint32 index, uniform uint32 dim) { uint32 res = 0; for (uniform uint32 i = dim * 52; index; index >>= 1, i++) { if (index & 1) res ^= Sobol_matrices[i]; } return res; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/sobol.inl000066400000000000000000000167301464752671100223140ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // These matrices are based on the following publication: // // S. Joe and F. Y. Kuo: "Constructing Sobol sequences with better // two-dimensional projections", SIAM J. Sci. Comput. 30, 2635-2654 (2008). // // The tabulated direction numbers are available here: // http://web.maths.unsw.edu.au/~fkuo/sobol/new-joe-kuo-6.21201 // bit-reversed and interleaved OSPRAY_GLOBAL const unsigned int Sobol_revMatrices[4 * 32] = { 0x1u, 0x1u, 0x1u, 0x1u, 0x3u, 0x3u, 0x3u, 0x2u, 0x5u, 0x6u, 0x4u, 0x4u, 0xfu, 0x9u, 0xau, 0xdu, 0x11u, 0x17u, 0x1fu, 0x1fu, 0x33u, 0x3au, 0x2eu, 0x3bu, 0x55u, 0x71u, 0x45u, 0x5eu, 0xffu, 0xa3u, 0xc9u, 0xb9u, 0x101u, 0x116u, 0x11bu, 0x15au, 0x303u, 0x339u, 0x2a4u, 0x3f4u, 0x505u, 0x677u, 0x79au, 0x685u, 0xf0fu, 0x9aau, 0xb67u, 0xd0fu, 0x1111u, 0x1601u, 0x101eu, 0x115bu, 0x3333u, 0x3903u, 0x302du, 0x23f6u, 0x5555u, 0x7706u, 0x4041u, 0x4681u, 0xffffu, 0xaa09u, 0xa0c3u, 0xdd02u, 0x10001u, 0x10117u, 0x1f104u, 0x1e144u, 0x30003u, 0x3033au, 0x2e28au, 0x393cdu, 0x50005u, 0x60671u, 0x457dfu, 0x5a6dfu, 0xf000fu, 0x909a3u, 0xc9baeu, 0xb4dbbu, 0x110011u, 0x171616u, 0x11a105u, 0x14401eu, 0x330033u, 0x3a3939u, 0x2a7289u, 0x3cd039u, 0x550055u, 0x717777u, 0x79e7dbu, 0x6df05au, 0xff00ffu, 0xa3aaaau, 0xb6dba4u, 0xdbb0b4u, 0x1010101u, 0x1170001u, 0x100011au, 0x101e145u, 0x3030303u, 0x33a0003u, 0x30002a7u, 0x20393cfu, 0x5050505u, 0x6710006u, 0x400079eu, 0x405a6dbu, 0xf0f0f0fu, 0x9a30009u, 0xa000b6du, 0xd0b4db6u, 0x11111111u, 0x16160017u, 0x1f001001u, 0x1f144001u, 0x33333333u, 0x3939003au, 0x2e003003u, 0x3b3cd002u, 0x55555555u, 0x77770071u, 0x45004004u, 0x5e6df004u, 0xffffffffu, 0xaaaa00a3u, 0xc900a00au, 0xb9dbb00du, }; OSPRAY_GLOBAL const unsigned int Sobol_matrices[5 * 52] = { 0x80000000U, 0x40000000U, 0x20000000U, 0x10000000U, 0x8000000U, 0x4000000U, 0x2000000U, 0x1000000U, 0x800000U, 0x400000U, 0x200000U, 0x100000U, 0x80000U, 0x40000U, 0x20000U, 0x10000U, 0x8000U, 0x4000U, 0x2000U, 0x1000U, 0x800U, 0x400U, 0x200U, 0x100U, 0x80U, 0x40U, 0x20U, 0x10U, 0x8U, 0x4U, 0x2U, 0x1U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x0U, 0x80000000U, 0xc0000000U, 0xa0000000U, 0xf0000000U, 0x88000000U, 0xcc000000U, 0xaa000000U, 0xff000000U, 0x80800000U, 0xc0c00000U, 0xa0a00000U, 0xf0f00000U, 0x88880000U, 0xcccc0000U, 0xaaaa0000U, 0xffff0000U, 0x80008000U, 0xc000c000U, 0xa000a000U, 0xf000f000U, 0x88008800U, 0xcc00cc00U, 0xaa00aa00U, 0xff00ff00U, 0x80808080U, 0xc0c0c0c0U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x88888888U, 0xccccccccU, 0xaaaaaaaaU, 0xffffffffU, 0x80000000U, 0xc0000000U, 0xa0000000U, 0xf0000000U, 0x88000000U, 0xcc000000U, 0xaa000000U, 0xff000000U, 0x80800000U, 0xc0c00000U, 0xa0a00000U, 0xf0f00000U, 0x88880000U, 0xcccc0000U, 0xaaaa0000U, 0xffff0000U, 0x80008000U, 0xc000c000U, 0xa000a000U, 0xf000f000U, 0x80000000U, 0xc0000000U, 0x60000000U, 0x90000000U, 0xe8000000U, 0x5c000000U, 0x8e000000U, 0xc5000000U, 0x68800000U, 0x9cc00000U, 0xee600000U, 0x55900000U, 0x80680000U, 0xc09c0000U, 0x60ee0000U, 0x90550000U, 0xe8808000U, 0x5cc0c000U, 0x8e606000U, 0xc5909000U, 0x6868e800U, 0x9c9c5c00U, 0xeeee8e00U, 0x5555c500U, 0x8000e880U, 0xc0005cc0U, 0x60008e60U, 0x9000c590U, 0xe8006868U, 0x5c009c9cU, 0x8e00eeeeU, 0xc5005555U, 0x68808000U, 0x9cc0c000U, 0xee606000U, 0x55909000U, 0x8068e800U, 0xc09c5c00U, 0x60ee8e00U, 0x9055c500U, 0xe880e880U, 0x5cc05cc0U, 0x8e608e60U, 0xc590c590U, 0x68686868U, 0x9c9c9c9cU, 0xeeeeeeeeU, 0x55555555U, 0x80000000U, 0xc0000000U, 0x60000000U, 0x90000000U, 0x80000000U, 0xc0000000U, 0x20000000U, 0x50000000U, 0xf8000000U, 0x74000000U, 0xa2000000U, 0x93000000U, 0xd8800000U, 0x25400000U, 0x59e00000U, 0xe6d00000U, 0x78080000U, 0xb40c0000U, 0x82020000U, 0xc3050000U, 0x208f8000U, 0x51474000U, 0xfbea2000U, 0x75d93000U, 0xa0858800U, 0x914e5400U, 0xdbe79e00U, 0x25db6d00U, 0x58800080U, 0xe54000c0U, 0x79e00020U, 0xb6d00050U, 0x800800f8U, 0xc00c0074U, 0x200200a2U, 0x50050093U, 0xf80f80d8U, 0x74074025U, 0xa20a2059U, 0x930930e6U, 0xd88d8878U, 0x254254b4U, 0x59e59e82U, 0xe6de6dc3U, 0x780f80a0U, 0xb4074091U, 0x820a20dbU, 0xc3093025U, 0x208d8858U, 0x514254e5U, 0xfbe59e79U, 0x75de6db6U, 0xa08f8000U, 0x91474000U, 0xdbea2000U, 0x25d93000U, 0x80000000U, 0x40000000U, 0x20000000U, 0xb0000000U, 0xf8000000U, 0xdc000000U, 0x7a000000U, 0x9d000000U, 0x5a800000U, 0x2fc00000U, 0xa1600000U, 0xf0b00000U, 0xda880000U, 0x6fc40000U, 0x81620000U, 0x40bb0000U, 0x22878000U, 0xb3c9c000U, 0xfb65a000U, 0xddb2d000U, 0x78022800U, 0x9c0b3c00U, 0x5a0fb600U, 0x2d0ddb00U, 0xa2878080U, 0xf3c9c040U, 0xdb65a020U, 0x6db2d0b0U, 0x800228f8U, 0x400b3cdcU, 0x200fb67aU, 0xb00ddb9dU, 0xf80780daU, 0xdc09c06fU, 0x7a05a081U, 0x9d02d040U, 0x5a8a2822U, 0x2fcf3cb3U, 0xa16db6fbU, 0xf0b6dbddU, 0xda8000f8U, 0x6fc000dcU, 0x8160007aU, 0x40b0009dU, 0x2288005aU, 0xb3c4002fU, 0xfb6200a1U, 0xddbb00f0U, 0x780780daU, 0x9c09c06fU, 0x5a05a081U, 0x2d02d040U, }; RenderKit-ospray-85af292/modules/cpu/math/spectrum.h000066400000000000000000000040451464752671100225010ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ==> 430..675 #define SPECTRUM_SAMPLES 8 #define SPECTRUM_FIRSTWL 430.f #define SPECTRUM_SPACING 35.f #ifdef __cplusplus #include #include struct alignas(SPECTRUM_SAMPLES * sizeof(float)) spectrum : public std::array { spectrum() = default; spectrum(const spectrum &) = default; ~spectrum() = default; spectrum &operator=(const spectrum &) = default; // The initializer_list constructor lets us construct the spectrum object // in C++ as if it's directly a std::array using the array init syntax spectrum(std::initializer_list l) { assert(l.size() == SPECTRUM_SAMPLES); std::copy(l.begin(), l.end(), begin()); } }; #endif // __cplusplus #define SPECTRUM_AL_ETA \ { \ 0.570, 0.686, 0.813, 0.952, 1.11, 1.29, 1.49, 1.73 \ } #define SPECTRUM_AL_K \ { \ 5.21, 5.64, 6.05, 6.45, 6.85, 7.24, 7.61, 7.94 \ } #define RGB_AL_ETA \ { \ 1.47f, 0.984f, 0.602f \ } #define RGB_AL_K \ { \ 7.64f, 6.55f, 5.36f \ } // = ((eta-1)^2+k^2)/((eta+1)^2+k^2) #define RGB_AL_COLOR \ { \ 0.909f, 0.916f, 0.923f \ } RenderKit-ospray-85af292/modules/cpu/math/spectrum.ih000066400000000000000000000025121464752671100226470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "math/spectrum.h" #include "rkcommon/math/vec.ih" #ifndef OSPRAY_TARGET_SYCL typedef uniform float spectrum; #endif OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef ISPC extern spectrum spectrum_sRGB_r; extern spectrum spectrum_sRGB_g; extern spectrum spectrum_sRGB_b; #endif inline uniform vec3f spectrum_sRGB(const uniform int l) { #ifdef OSPRAY_TARGET_SYCL const spectrum spectrum_sRGB_r = {0.0598548f, -0.0234574f, -0.220138f, -0.238902f, 0.316327f, 0.738315f, 0.323302f, 0.0446981f}; const spectrum spectrum_sRGB_g = {-0.0567346f, -0.0160361f, 0.223861f, 0.531185f, 0.337221f, 0.0149718f, -0.0296053f, -0.00486239f}; const spectrum spectrum_sRGB_b = {0.420693f, 0.616597f, 0.0796766f, -0.0496266f, -0.0473149f, -0.0167536f, -0.00295686f, -0.000314818f}; #endif return make_vec3f(spectrum_sRGB_r[l], spectrum_sRGB_g[l], spectrum_sRGB_b[l]); } // note: result can be <0 or >1 inline uniform vec3f spectrum2rgb(const spectrum &s) { uniform vec3f rgb = make_vec3f(0.f); for (uniform int l = 0; l < SPECTRUM_SAMPLES; l++) rgb = rgb + s[l] * spectrum_sRGB(l); return rgb; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/math/spectrum.ispc000066400000000000000000000013051464752671100232040ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "math/spectrum.ih" // convolutions of: normalization * D65 * CIE_XYZ * xyz2sRGB OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef ISPC spectrum spectrum_sRGB_r = {0.0598548f, -0.0234574f, -0.220138f, -0.238902f, 0.316327f, 0.738315f, 0.323302f, 0.0446981f}; spectrum spectrum_sRGB_g = {-0.0567346f, -0.0160361f, 0.223861f, 0.531185f, 0.337221f, 0.0149718f, -0.0296053f, -0.00486239f}; spectrum spectrum_sRGB_b = {0.420693f, 0.616597f, 0.0796766f, -0.0496266f, -0.0473149f, -0.0167536f, -0.00295686f, -0.000314818f}; #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/pf/000077500000000000000000000000001464752671100201375ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/pf/LUTPixelFilter.ih000066400000000000000000000005401464752671100232740ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "PixelFilter.ih" #include "math/Distribution2D.ih" // c++ shared #include "LUTPixelFilterShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec2f LUTPixelFilter_sample( const PixelFilter *uniform self, const vec2f &s); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/pf/LUTPixelFilter.ispc000066400000000000000000000105401464752671100236330ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "math/Distribution1D.ih" #include "pf/LUTPixelFilter.ih" OSPRAY_BEGIN_ISPC_NAMESPACE vec2f LUTPixelFilter_sample(const PixelFilter *uniform _self, const vec2f &s) { const LUTPixelFilter *uniform self = (const LUTPixelFilter *uniform)_self; Sample2D sample2d = Distribution2D_sample(self->distribution, s); return (sample2d.uv + make_vec2f(-0.5f)) * make_vec2f(self->super.width); } inline float Gaussian_eval(const PixelFilter *uniform self, const vec2f &x) { const float sigma = (0.5f * self->width) / 3.0f; const float sigmaSqr = sigma * sigma; const float distanceSqr = x.x * x.x + x.y * x.y; return exp(-0.5f * (distanceSqr / sigmaSqr)); } inline float MitchellNetravali_eval( const PixelFilter *uniform self, const vec2f &x) { const float oneOverSix = 1.0f / 6.0f; const float B = 1.0f / 3.0f; const float C = 1.0f / 3.0f; const vec2f tx = (x / make_vec2f(self->width)) * make_vec2f(4.0f); const float fx = sqrt(tx.x * tx.x + tx.y * tx.y); const float fx2 = fx * fx; const float fx3 = fx2 * fx; float value = 0.0f; if (fx < 1.0f) { value = oneOverSix * ((12.0f - 9.0f * B - 6.0f * C) * fx3 + (-18.0f + 12.0f * B + 6.0f * C) * fx2 + (6.0f - 2.0f * B)); } else if (fx < 2.0f) { value = oneOverSix * ((-B - 6.0f * C) * fx3 + (6.0f * B + 30.0f * C) * fx2 + (-12.0f * B - 48.0f * C) * fx + (8.0f * B + 24.0f * C)); } return value; } inline float BlackmanHarris_eval( const PixelFilter *uniform self, const vec2f &x) { const float a0 = 0.35875f; const float a1 = 0.48829f; const float a2 = 0.14128f; const float a3 = 0.01168f; const float fx = sqrt(x.x * x.x + x.y * x.y) + self->width / 2.0f; const float oneOverWMinusOne = 1.0f / (self->width); const float value = a0 - a1 * cos((2.0f * M_PI * fx) * oneOverWMinusOne) + a2 * cos((4.0f * M_PI * fx) * oneOverWMinusOne) - a3 * cos((6.0f * M_PI * fx) * oneOverWMinusOne); return value; } #ifndef OSPRAY_TARGET_SYCL task #endif unmasked void LUTPixelFilter_calcRowImportance(const LUTPixelFilter *uniform const self, int uniform const lut_width, float *uniform const importance, float *uniform const row_importance #ifdef OSPRAY_TARGET_SYCL , const int taskIndex #endif ) { const uniform float filter_width = self->super.width; const uniform int y = taskIndex; const uniform float fy = (y + 0.5f) * (1.0f / (float)lut_width); #ifdef OSPRAY_TARGET_SYCL for (int x = 0; x < lut_width; ++x) { #else foreach (x = 0 ... lut_width) { #endif const varying float fx = (x + 0.5f) * (1.0f / (float)lut_width); const vec2f coord = make_vec2f(fx, fy) - make_vec2f(0.5f); float filterEval = 0.f; switch (self->lutFilterType) { case LUT_PIXEL_FILTER_TYPE_GAUSSIAN: filterEval = Gaussian_eval(&self->super, coord * make_vec2f(filter_width)); break; case LUT_PIXEL_FILTER_TYPE_MITCHELL_NETRAVALI: filterEval = MitchellNetravali_eval( &self->super, coord * make_vec2f(filter_width)); break; case LUT_PIXEL_FILTER_TYPE_BLACKMANN_HARRIS: filterEval = BlackmanHarris_eval(&self->super, coord * make_vec2f(filter_width)); break; default: break; } // clamp the evaluation of the filter // to avoid negative values importance[y * lut_width + x] = max(0.0f, filterEval); } row_importance[y] = Distribution1D_create(lut_width, importance + y * lut_width); } export void LUTPixelFilter_buildLUT(void *uniform _self) { LUTPixelFilter *uniform self = (LUTPixelFilter * uniform) _self; const uniform int lut_width = self->distribution->size.x; float *uniform cdf_x = self->distribution->cdf_x; float *uniform row_importance = self->distribution->cdf_y; #ifdef OSPRAY_TARGET_SYCL // TODO: This could become a kernel launch via SYCL // This serial loop is just for testing an initial C++ migration of the ISPC // code for (int i = 0; i < lut_width; ++i) { LUTPixelFilter_calcRowImportance(self, lut_width, cdf_x, row_importance, i); } #else launch[lut_width] LUTPixelFilter_calcRowImportance( self, lut_width, cdf_x, row_importance); sync; #endif // Initialize the distribution with the computed cdf/f values Distribution2D_init(self->distribution); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/pf/LUTPixelFilterShared.h000066400000000000000000000013751464752671100242610ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "math/Distribution2DShared.h" #include "pf/PixelFilterShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus enum LUTPixelFilterType { LUT_PIXEL_FILTER_TYPE_GAUSSIAN, LUT_PIXEL_FILTER_TYPE_BLACKMANN_HARRIS, LUT_PIXEL_FILTER_TYPE_MITCHELL_NETRAVALI, }; #define LUTPIXELFILTER_PER_PIXEL_BINS 5 struct LUTPixelFilter { PixelFilter super; // The 2D distribution used to importance sample Distribution2D *distribution; LUTPixelFilterType lutFilterType; #ifdef __cplusplus LUTPixelFilter() : distribution(nullptr), lutFilterType{LUT_PIXEL_FILTER_TYPE_GAUSSIAN} { super.type = PIXEL_FILTER_TYPE_LUT; } }; } #else }; #endif RenderKit-ospray-85af292/modules/cpu/pf/PixelFilter.cpp000066400000000000000000000035511464752671100230760ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "PixelFilter.h" #include "ISPCDevice.h" #include "ISPCDeviceObject.h" #include "math/Distribution2D.h" #ifndef OSPRAY_TARGET_SYCL #include "pf/LUTPixelFilter_ispc.h" #else namespace ispc { void LUTPixelFilter_buildLUT(void *self); } #endif namespace ospray { PixelFilter::PixelFilter(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) {} LUTPixelFilter::LUTPixelFilter(const float size, ispc::LUTPixelFilterType lutFilterType, api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { getSh()->super.width = size; getSh()->super.type = ispc::PIXEL_FILTER_TYPE_LUT; const vec2i lutSize = vec2i(std::ceil(size)) * LUTPIXELFILTER_PER_PIXEL_BINS; distribution = new Distribution2D(lutSize, device); // Remove local ref distribution->refDec(); getSh()->distribution = distribution->getSh(); getSh()->lutFilterType = lutFilterType; ispc::LUTPixelFilter_buildLUT(getSh()); } PointPixelFilter::PointPixelFilter(api::ISPCDevice &device) : PixelFilter(device) { getSh()->type = ispc::PIXEL_FILTER_TYPE_POINT; getSh()->width = 0.f; } BoxPixelFilter::BoxPixelFilter(api::ISPCDevice &device) : PixelFilter(device) { getSh()->type = ispc::PIXEL_FILTER_TYPE_BOX; getSh()->width = 1.f; } GaussianLUTPixelFilter::GaussianLUTPixelFilter(api::ISPCDevice &device) : LUTPixelFilter(3.f, ispc::LUT_PIXEL_FILTER_TYPE_GAUSSIAN, device) {} BlackmanHarrisLUTPixelFilter::BlackmanHarrisLUTPixelFilter( api::ISPCDevice &device) : LUTPixelFilter(3.f, ispc::LUT_PIXEL_FILTER_TYPE_BLACKMANN_HARRIS, device) {} MitchellNetravaliLUTPixelFilter::MitchellNetravaliLUTPixelFilter( api::ISPCDevice &device) : LUTPixelFilter( 4.f, ispc::LUT_PIXEL_FILTER_TYPE_MITCHELL_NETRAVALI, device) {} } // namespace ospray RenderKit-ospray-85af292/modules/cpu/pf/PixelFilter.h000066400000000000000000000026421464752671100225430ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDevice.h" #include "ISPCDeviceObject.h" #include "common/Managed.h" #include "common/StructShared.h" #include "math/Distribution2D.h" // ispc shared #include "pf/LUTPixelFilterShared.h" #include "pf/PixelFilterShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE PixelFilter : public AddStructShared { PixelFilter(api::ISPCDevice &device); }; struct OSPRAY_SDK_INTERFACE LUTPixelFilter : public AddStructShared { LUTPixelFilter(const float size, ispc::LUTPixelFilterType lutFilterType, api::ISPCDevice &device); Ref distribution; }; struct OSPRAY_SDK_INTERFACE PointPixelFilter : public PixelFilter { PointPixelFilter(api::ISPCDevice &device); }; struct OSPRAY_SDK_INTERFACE BoxPixelFilter : public PixelFilter { BoxPixelFilter(api::ISPCDevice &device); }; struct OSPRAY_SDK_INTERFACE GaussianLUTPixelFilter : public LUTPixelFilter { GaussianLUTPixelFilter(api::ISPCDevice &device); }; struct OSPRAY_SDK_INTERFACE BlackmanHarrisLUTPixelFilter : public LUTPixelFilter { BlackmanHarrisLUTPixelFilter(api::ISPCDevice &device); }; struct OSPRAY_SDK_INTERFACE MitchellNetravaliLUTPixelFilter : public LUTPixelFilter { MitchellNetravaliLUTPixelFilter(api::ISPCDevice &device); }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/pf/PixelFilter.ih000066400000000000000000000012111464752671100227030ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" // c++ shared #include "pf/PixelFilterShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void PixelFilter_Constructor(PixelFilter *uniform self, uniform float width, uniform PixelFilter_SampleFunc sample) { self->width = width; self->sample = sample; } inline vec2f Point_sample(const PixelFilter *uniform, const vec2f &) { return make_vec2f(0.0f); } inline vec2f Box_sample(const PixelFilter *uniform self, const vec2f &s) { return (s + make_vec2f(-0.5f)) * make_vec2f(self->width); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/pf/PixelFilterDispatch.ih000066400000000000000000000015041464752671100243700ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/OSPCommon.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PixelFilter; /* Samples a relative pixel position proportional to the kernel of a pixel filter. The sampled position is relative to the center of a pixel. It converts a uniform 2D random variable s with values of the range [0..1) into a non-uniform 2D position in the range of [-w/2 .. w/2], where w = self->width. The center of the pixel filter kernel is [0,0], which represents a position at the center of the pixel. Returns a 2D position in the domain [-w/2 .. w/2] distributed proportionally to the filter kernel. */ SYCL_EXTERNAL vec2f PixelFilter_dispatch_sample( const PixelFilter *uniform self, const vec2f &x); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/pf/PixelFilterDispatch.ispc000066400000000000000000000011351464752671100247260ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "pf/LUTPixelFilter.ih" #include "pf/PixelFilter.ih" #include "pf/PixelFilterDispatch.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec2f PixelFilter_dispatch_sample( const PixelFilter *uniform self, const vec2f &x) { switch (self->type) { case PIXEL_FILTER_TYPE_POINT: return Point_sample(self, x); case PIXEL_FILTER_TYPE_BOX: return Box_sample(self, x); case PIXEL_FILTER_TYPE_LUT: return LUTPixelFilter_sample(self, x); default: return make_vec2f(0.f); } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/pf/PixelFilterShared.h000066400000000000000000000024401464752671100236660ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *PixelFilter_SampleFunc; #else struct PixelFilter; /* Samples a relative pixel position proportional to the kernel of a pixel filter. The sampled position is relative to the center of a pixel. It converts a uniform 2D random variable s with values of the range [0..1) into a non-uniform 2D position in the range of [-w/2 .. w/2], where w = self->width. The center of the pixel filter kernel is [0,0], which represents a position at the center of the pixel, which should be sampled for input s = [0.5, 0.5]. Returns a 2D position in the domain [-w/2 .. w/2] distributed proportionally to the filter kernel. */ typedef vec2f (*PixelFilter_SampleFunc)( const PixelFilter *uniform self, const vec2f &s); #endif enum PixelFilterType { PIXEL_FILTER_TYPE_POINT, PIXEL_FILTER_TYPE_BOX, PIXEL_FILTER_TYPE_LUT, PIXEL_FILTER_TYPE_UNKNOWN, }; struct PixelFilter { PixelFilterType type; float width; PixelFilter_SampleFunc sample; #ifdef __cplusplus PixelFilter() : type(PIXEL_FILTER_TYPE_UNKNOWN), width(0.f), sample(nullptr) {} }; } #else }; #endif RenderKit-ospray-85af292/modules/cpu/render/000077500000000000000000000000001464752671100210115ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/LoadBalancer.cpp000066400000000000000000000020471464752671100240270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "LoadBalancer.h" #include "camera/Camera.h" #include "common/World.h" #include "fb/FrameBuffer.h" // ispc shared #include "fb/LocalFBShared.h" namespace ospray { std::pair LocalTiledLoadBalancer::renderFrame( FrameBuffer *fb, Renderer *renderer, Camera *camera, World *world) { fb->beginFrame(); void *perFrameData = renderer->beginFrame(fb, world); // Get render tasks and process them all utility::ArrayView taskIds = fb->getRenderTaskIDs(renderer->errorThreshold, renderer->spp); devicert::AsyncEvent rendererEvent; if (taskIds.size()) rendererEvent = renderer->renderTasks(fb, camera, world, perFrameData, taskIds); // Schedule post-processing kernels devicert::AsyncEvent fbEvent = fb->postProcess(); return std::make_pair(rendererEvent, fbEvent); } std::string LocalTiledLoadBalancer::toString() const { return "ospray::LocalTiledLoadBalancer"; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/LoadBalancer.h000066400000000000000000000025401464752671100234720ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/OSPCommon.h" #include "render/Renderer.h" namespace ospray { struct FrameBuffer; struct Camera; struct World; struct OSPRAY_SDK_INTERFACE TiledLoadBalancer { virtual ~TiledLoadBalancer() = default; virtual std::string toString() const = 0; /*! Render the entire framebuffer using the given renderer, camera and * world configuration using the load balancer to parallelize the work */ virtual std::pair renderFrame( FrameBuffer *fb, Renderer *renderer, Camera *camera, World *world) = 0; }; // Inlined definitions ////////////////////////////////////////////////////// //! tiled load balancer for local rendering on the given machine /*! a tiled load balancer that orchestrates (multi-threaded) rendering on a local machine, without any cross-node communication/load balancing at all (even if there are multiple application ranks each doing local rendering on their own) */ struct OSPRAY_SDK_INTERFACE LocalTiledLoadBalancer : public TiledLoadBalancer { std::pair renderFrame( FrameBuffer *fb, Renderer *renderer, Camera *camera, World *world) override; std::string toString() const override; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/Material.cpp000066400000000000000000000122631464752671100232570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Material.h" #include "render/bsdfs/MicrofacetAlbedoTables.h" #include "texture/Texture.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/Material_ispc.h" #endif namespace ospray { // Material definitions /////////////////////////////////////////////////////// Ref Material::microfacetAlbedoTables; Material::Material(api::ISPCDevice &device, const FeatureFlagsOther ffo) : AddStructShared(device.getDRTDevice(), device), featureFlags(ffo) { managedObjectType = OSP_MATERIAL; #ifndef OSPRAY_TARGET_SYCL getSh()->getTransparency = reinterpret_cast( ispc::Material_getTransparency_addr()); getSh()->selectNextMedium = reinterpret_cast( ispc::Material_selectNextMedium_addr()); getSh()->getEmission = reinterpret_cast( ispc::Material_getEmission_addr()); #endif if (!microfacetAlbedoTables) { microfacetAlbedoTables = new MicrofacetAlbedoTables(device); // Release the extra local ref microfacetAlbedoTables->refDec(); } else { microfacetAlbedoTables->refInc(); } getSh()->microfacetAlbedoTables = microfacetAlbedoTables->getSh(); } Material::~Material() { if (microfacetAlbedoTables) { const bool lastReference = microfacetAlbedoTables->useCount() == 1; // The last material referencing the albedo tables should null out the // pointer so we don't try to call refDec again and know to re-create it // when a new material is made if (lastReference) { microfacetAlbedoTables = nullptr; } else { microfacetAlbedoTables->refDec(); } } } std::string Material::toString() const { return "ospray::Material"; } void Material::commit() {} ispc::TextureParam Material::getTextureParam( const char *texture_name, const Ref &ref_tex) { if (ref_tex) featureFlags |= FFO_TEXTURE_IN_MATERIAL; // Get 2D transformation if exists int transformFlags = ispc::TRANSFORM_FLAG_NONE; affine2f xfm2f = affine2f(one); utility::Optional xform2f = getTextureTransform2f(texture_name); if (xform2f.has_value()) { xfm2f = xform2f.value(); transformFlags |= ispc::TRANSFORM_FLAG_2D; } // Get 3D transformation if exists affine3f xfm3f = affine3f(one); auto xform3f = getOptParam((std::string(texture_name) + ".transform").c_str()); if (xform3f.has_value()) { xfm3f = xform3f.value(); transformFlags |= ispc::TRANSFORM_FLAG_3D; } // Initialize ISPC structure ispc::TextureParam param; param.ptr = ref_tex ? ref_tex->getSh() : nullptr; param.transformFlags = (ispc::TransformFlags)transformFlags; param.xform2f = xfm2f; param.scale2f = sqrt(xfm2f.l.det()); param.xform3f = xfm3f; // Done return param; } MaterialParam1f Material::getMaterialParam1f( const char *name, float valIfNotFound) { const std::string mapName = "map_" + std::string(name); MaterialParam1f param; param.ref_tex = getParamObject(mapName.c_str()); param.tex = getTextureParam(mapName.c_str(), param.ref_tex); param.rot = ((linear2f *)(¶m.tex.xform2f.l))->orthogonal().transposed(); param.factor = getParam(name, param.tex.ptr ? 1.f : valIfNotFound); return param; } MaterialParam3f Material::getMaterialParam3f( const char *name, vec3f valIfNotFound) { const std::string mapName = "map_" + std::string(name); MaterialParam3f param; param.ref_tex = getParamObject(mapName.c_str()); param.tex = getTextureParam(mapName.c_str(), param.ref_tex); param.rot = ((linear2f *)(¶m.tex.xform2f.l))->orthogonal().transposed(); param.factor = getParam(name, param.tex.ptr ? vec3f(1.f) : valIfNotFound); return param; } utility::Optional Material::getTextureTransform2f( const char *_texname) { std::string texname(_texname); texname += "."; utility::Optional xform; // Apply translation const utility::Optional translation = getOptParam((texname + "translation").c_str()); if (translation.has_value()) xform = affine2f::translate(-translation.value()); // Apply scale const utility::Optional scale = getOptParam((texname + "scale").c_str()); if (scale.has_value()) { xform = xform.value_or(affine2f(one)) * affine2f::translate(vec2f(0.5f)); xform = *xform * affine2f::scale(rcp(scale.value())); xform = *xform * affine2f::translate(vec2f(-0.5f)); } // Apply rotation const utility::Optional rotation = getOptParam((texname + "rotation").c_str()); if (rotation.has_value()) { xform = xform.value_or(affine2f(one)) * affine2f::translate(vec2f(0.5f)); xform = *xform * affine2f::rotate(-deg2rad(rotation.value())); xform = *xform * affine2f::translate(vec2f(-0.5f)); } // Apply complete transformation const utility::Optional transf = getOptParam((texname + "transform").c_str()); if (transf.has_value()) xform = xform.value_or(affine2f(one)) * affine2f(transf.value()); return xform; } OSPTYPEFOR_DEFINITION(Material *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/Material.h000066400000000000000000000060661464752671100227300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDeviceObject.h" #include "common/FeatureFlagsEnum.h" #include "common/ObjectFactory.h" #include "common/StructShared.h" // ispc shared #include "MaterialShared.h" #include "bsdfs/MicrofacetAlbedoTables.h" #include "texture/Texture.h" #include "texture/TextureParamShared.h" namespace ospray { /*! helper structure to store a uniform or textured material parameter */ template struct MaterialParam { T factor; ispc::TextureParam tex; Ref ref_tex; linear2f rot; }; using MaterialParam1f = MaterialParam; using MaterialParam3f = MaterialParam; struct OSPRAY_SDK_INTERFACE Material : public AddStructShared, public ObjectFactory { Material(api::ISPCDevice &device, const FeatureFlagsOther ffo); virtual ~Material() override; virtual std::string toString() const override; virtual void commit() override; FeatureFlags getFeatureFlags() const; // helper function to get all texture related parameters ispc::TextureParam getTextureParam( const char *texture_name, const Ref &ref_tex); /*! \brief helper function to get a uniform or texture material parameter */ MaterialParam1f getMaterialParam1f(const char *name, float valIfNotFound); MaterialParam3f getMaterialParam3f(const char *name, vec3f valIfNotFound); virtual bool isEmissive() const; private: /*! \brief helper function to combine multiple texture transformation parameters The following parameters (prefixed with "texture_name.") are combined into one transformation matrix: name type description transform vec4f interpreted as 2x2 matrix (linear part), column-major rotation float angle in degree, counterclock-wise, around center (0.5, 0.5) scale vec2f enlarge texture, relative to center (0.5, 0.5) translation vec2f move texture in positive direction (right/up) The transformations are applied in the given order. Rotation, scale and translation are interpreted "texture centric", i.e. their effect seen by an user are relative to the texture (although the transformations are applied to the texture coordinates). */ utility::Optional getTextureTransform2f(const char *_texname); utility::Optional getTextureTransform3f(const char *_texname); FeatureFlagsOther featureFlags; // Microfacet albedo tables data, shared by all materials. New materials // increment the use count, and decrement it on destruction to ensure // the data will be released before the device static Ref microfacetAlbedoTables; }; OSPTYPEFOR_SPECIALIZATION(Material *, OSP_MATERIAL); // Inlined definitions ///////////////////////////////////////////////////////// inline FeatureFlags Material::getFeatureFlags() const { FeatureFlags ff; ff.other = featureFlags; return ff; } inline bool Material::isEmissive() const { return false; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/Material.ih000066400000000000000000000065051464752671100230770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/DifferentialGeometry.ih" #include "common/FeatureFlags.ih" #include "rkcommon/math/AffineSpace.ih" #include "texture/TextureParam.ih" // c++ shared #include "MaterialShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #define define_texture_get_ff(fn, map, dg, val, ffh) \ ((getFeatureFlagsOther(ffh) & FFO_TEXTURE_IN_MATERIAL) ? fn(map, dg, val) \ : val) #define get1f_ff(map, dg, val, ff) \ define_texture_get_ff(get1f, map, dg, val, ff) #define get3f_ff(map, dg, val, ff) \ define_texture_get_ff(get3f, map, dg, val, ff) #define get4f_ff(map, dg, val, ff) \ define_texture_get_ff(get4f, map, dg, val, ff) inline linear3f makeShadingFrame(const DifferentialGeometry &dg) { vec3f N = dg.Ns; vec3f U = normalize(dg.dPds); vec3f V = cross(N, U); if (dot(V, V) > 0.f) { V = normalize(V); U = cross(V, N); return make_LinearSpace3f(U, V, N); } else { return frame(N); } } inline linear3f makeShadingFrame(const linear3f &f, const vec3f &localN) { // in general f is not ortho-normal, thus need to re-normalize vec3f N = normalize(f * localN); // transform normal to world space vec3f U = f.vx; vec3f V = cross(N, U); if (dot(V, V) > 0.f) { V = normalize(V); U = cross(V, N); return make_LinearSpace3f(U, V, N); } else { return frame(N); } } inline linear3f makeShadingFrame( const DifferentialGeometry &dg, const vec3f &localN) { linear3f f = makeShadingFrame(dg); return makeShadingFrame(f, localN); } inline linear3f makeShadingFrame(const DifferentialGeometry &dg, const uniform TextureParam &normalMap, const uniform linear2f &normalRot, uniform float normalScale = 1.f) { if (valid(normalMap)) { linear3f f = make_LinearSpace3f(normalize(dg.dPds), normalize(dg.dPdt), dg.Ns); // get normal from texture vec3f localN = getNormal(normalMap, dg) * make_vec3f(normalScale, normalScale, 1.f); // rotate in 2D (tangent space) to account for tc transformations vec2f rotN = normalRot * make_vec2f(localN.x, localN.y); localN.x = rotN.x; localN.y = rotN.y; return makeShadingFrame(f, localN); } else { return makeShadingFrame(dg); } } inline linear3f makeShadingFrame_ff(const DifferentialGeometry &dg, const uniform TextureParam &normalMap, const uniform linear2f &normalRot, const uniform FeatureFlagsHandler &ffh) { return (getFeatureFlagsOther(ffh) & FFO_TEXTURE_IN_MATERIAL) ? makeShadingFrame(dg, normalMap, normalRot) : makeShadingFrame(dg); } SYCL_EXTERNAL vec3f Material_getTransparency( const uniform Material *uniform self, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL void Material_selectNextMedium( const uniform Material *uniform self, const DifferentialGeometry &dg, Medium ¤tMedium); SYCL_EXTERNAL vec3f Material_getEmission(const Material *uniform self, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/Material.ispc000066400000000000000000000021511464752671100234260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Material.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec3f Material_getTransparency(const uniform Material *uniform, const DifferentialGeometry &, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { return make_vec3f(0.0f); } SYCL_EXTERNAL void Material_selectNextMedium( const uniform Material *uniform, const DifferentialGeometry &, Medium &) { /* do nothing by default */ } SYCL_EXTERNAL vec3f Material_getEmission(const Material *uniform, const varying DifferentialGeometry &, const uniform FeatureFlagsHandler &) { return make_vec3f(0.0f); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Material_getTransparency_addr() { return (void *uniform)Material_getTransparency; } export void *uniform Material_selectNextMedium_addr() { return (void *uniform)Material_selectNextMedium; } export void *uniform Material_getEmission_addr() { return (void *uniform)Material_getEmission; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/MaterialDispatch.ih000066400000000000000000000026101464752671100245500ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL __noinline const varying BSDF *uniform Material_dispatch_getBSDF( const uniform Material *uniform self, uniform ShadingContext *uniform ctx, // The point to shade on a surface. const DifferentialGeometry &dg, // The ray arriving at the point to shade. const Ray &ray, // The medium this ray travels inside. const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL __noinline vec3f Material_dispatch_getTransparency( const uniform Material *uniform self, // The point to shade on a surface. const DifferentialGeometry &dg, // The ray arriving at the point to shade. const Ray &ray, // The medium this ray travels inside. const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL __noinline void Material_dispatch_selectNextMedium( const uniform Material *uniform self, const DifferentialGeometry &dg, Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL __noinline vec3f Material_dispatch_getEmission( const Material *uniform self, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/MaterialDispatch.ispc000066400000000000000000000137201464752671100251120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Material.ih" #include "MaterialDispatch.ih" #include "common/FeatureFlagsEnum.h" #include "render/materials/Alloy.ih" #include "render/materials/CarPaint.ih" #include "render/materials/Glass.ih" #include "render/materials/Luminous.ih" #include "render/materials/Metal.ih" #include "render/materials/MetallicPaint.ih" #include "render/materials/Mix.ih" #include "render/materials/OBJ.ih" #include "render/materials/Plastic.ih" #include "render/materials/Principled.ih" #include "render/materials/ThinGlass.ih" #include "render/materials/Velvet.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL __noinline const varying BSDF *uniform Material_dispatch_getBSDF( const uniform Material *uniform self, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->type == MATERIAL_TYPE_ALLOY) && (ffo & FFO_MATERIAL_ALLOY)) { return Alloy_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_CARPAINT) && (ffo & FFO_MATERIAL_CARPAINT)) { return CarPaint_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_GLASS) && (ffo & FFO_MATERIAL_GLASS)) { return Glass_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_LUMINOUS) && (ffo & FFO_MATERIAL_LUMINOUS)) { return Luminous_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_METAL) && (ffo & FFO_MATERIAL_METAL)) { return Metal_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_METALLICPAINT) && (ffo & FFO_MATERIAL_METALLICPAINT)) { return MetallicPaint_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_OBJ) && (ffo & FFO_MATERIAL_OBJ)) { return OBJ_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_PLASTIC) && (ffo & FFO_MATERIAL_PLASTIC)) { return Plastic_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_PRINCIPLED) && (ffo & FFO_MATERIAL_PRINCIPLED)) { return Principled_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_THINGLASS) && (ffo & FFO_MATERIAL_THINGLASS)) { return ThinGlass_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_VELVET) && (ffo & FFO_MATERIAL_VELVET)) { return Velvet_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } #ifndef OSPRAY_TARGET_SYCL else if ((self->type == MATERIAL_TYPE_MIX) && (ffo & FFO_MATERIAL_MIX)) { return Mix_getBSDF(self, ctx, dg, ray, currentMedium, ffh); } else { return self->getBSDF(self, ctx, dg, ray, currentMedium, ffh); } #endif return NULL; } SYCL_EXTERNAL __noinline vec3f Material_dispatch_getTransparency( const uniform Material *uniform self, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->type == MATERIAL_TYPE_GLASS) && (ffo & FFO_MATERIAL_GLASS)) { return Glass_getTransparency(self, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_LUMINOUS) && (ffo & FFO_MATERIAL_LUMINOUS)) { return Luminous_getTransparency(self, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_OBJ) && (ffo & FFO_MATERIAL_OBJ)) { return OBJ_getTransparency(self, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_PRINCIPLED) && (ffo & FFO_MATERIAL_PRINCIPLED)) { return Principled_getTransparency(self, dg, ray, currentMedium, ffh); } else if ((self->type == MATERIAL_TYPE_THINGLASS) && (ffo & FFO_MATERIAL_THINGLASS)) { return ThinGlass_getTransparency(self, dg, ray, currentMedium, ffh); } #ifndef OSPRAY_TARGET_SYCL else if ((self->type == MATERIAL_TYPE_MIX) && (ffo & FFO_MATERIAL_MIX)) { return Mix_getTransparency(self, dg, ray, currentMedium, ffh); } else { return self->getTransparency(self, dg, ray, currentMedium, ffh); } #else else { return Material_getTransparency(self, dg, ray, currentMedium, ffh); } #endif } SYCL_EXTERNAL __noinline void Material_dispatch_selectNextMedium( const uniform Material *uniform self, const DifferentialGeometry &dg, Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->type == MATERIAL_TYPE_GLASS) && (ffo & FFO_MATERIAL_GLASS)) { Glass_selectNextMedium(self, dg, currentMedium); } else if ((self->type == MATERIAL_TYPE_PRINCIPLED) && (ffo & FFO_MATERIAL_PRINCIPLED)) { Principled_selectNextMedium(self, dg, currentMedium); } else { #ifndef OSPRAY_TARGET_SYCL self->selectNextMedium(self, dg, currentMedium); #else Material_selectNextMedium(self, dg, currentMedium); #endif } } SYCL_EXTERNAL __noinline vec3f Material_dispatch_getEmission( const Material *uniform self, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->type == MATERIAL_TYPE_LUMINOUS) && (ffo & FFO_MATERIAL_LUMINOUS)) { return Luminous_getEmission(self, dg, ffh); } else if ((self->type == MATERIAL_TYPE_PRINCIPLED) && (ffo & FFO_MATERIAL_PRINCIPLED)) { return Principled_getEmission(self, dg, ffh); } #ifndef OSPRAY_TARGET_SYCL else if ((self->type == MATERIAL_TYPE_MIX) && (ffo & FFO_MATERIAL_MIX)) { return Mix_getEmission(self, dg, ffh); } else { return self->getEmission(self, dg, ffh); } #else else { return Material_getEmission(self, dg, ffh); } #endif } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/MaterialShared.h000066400000000000000000000055111464752671100240510ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "texture/TextureParamShared.h" #define EPS 1e-5f #include "bsdfs/MicrofacetAlbedoTablesShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *Material_GetBSDFFunc; typedef void *Material_GetTransparencyFunc; typedef void *Material_SelectNextMediumFunc; typedef void *Material_GetEmissionFunc; #else struct BSDF; struct ShadingContext; struct Medium; struct DifferentialGeometry; struct Ray; struct Material; struct FeatureFlagsHandler; typedef const varying BSDF *uniform (*Material_GetBSDFFunc)( const uniform Material *uniform self, uniform ShadingContext *uniform ctx, // The point to shade on a surface. const DifferentialGeometry &dg, // The ray arriving at the point to shade. const Ray &ray, // The medium this ray travels inside. const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); // shortcut: compute transmission of material, for transparent shadows, // neglecting refraction typedef vec3f (*Material_GetTransparencyFunc)( const uniform Material *uniform self, // The point to shade on a surface. const DifferentialGeometry &dg, // The ray arriving at the point to shade. const Ray &ray, // The medium this ray travels inside. const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); typedef void (*Material_SelectNextMediumFunc)( const uniform Material *uniform self, const DifferentialGeometry &dg, Medium ¤tMedium); typedef vec3f (*Material_GetEmissionFunc)(const Material *uniform self, // The point to shade on a surface. const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh); #endif enum MaterialType { MATERIAL_TYPE_ALLOY = 0, MATERIAL_TYPE_CARPAINT = 1, MATERIAL_TYPE_GLASS = 2, MATERIAL_TYPE_LUMINOUS = 3, MATERIAL_TYPE_METAL = 4, MATERIAL_TYPE_METALLICPAINT = 5, MATERIAL_TYPE_MIX = 6, MATERIAL_TYPE_OBJ = 7, MATERIAL_TYPE_PLASTIC = 8, MATERIAL_TYPE_PRINCIPLED = 9, MATERIAL_TYPE_THINGLASS = 10, MATERIAL_TYPE_VELVET = 11, MATERIAL_TYPE_UNKNOWN = 12 }; // ISPC-side abstraction for a material. struct Material { MaterialType type; Material_GetBSDFFunc getBSDF; Material_GetTransparencyFunc getTransparency; Material_SelectNextMediumFunc selectNextMedium; Material_GetEmissionFunc getEmission; bool isEmissive; MicrofacetAlbedoTables *microfacetAlbedoTables; #ifdef __cplusplus Material() : type(MATERIAL_TYPE_UNKNOWN), getBSDF(nullptr), getTransparency(nullptr), selectNextMedium(nullptr), getEmission(nullptr), isEmissive(false), microfacetAlbedoTables(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/Renderer.cpp000066400000000000000000000120601464752671100232620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Renderer.h" #include "LoadBalancer.h" #include "Material.h" #include "camera/Camera.h" #include "common/Instance.h" #include "common/World.h" #include "fb/FrameBuffer.h" #include "geometry/GeometricModel.h" #include "ospray/OSPEnums.h" #include "pf/PixelFilter.h" #ifndef OSPRAY_TARGET_SYCL #include "render/Renderer_ispc.h" #include "render/util_ispc.h" #endif namespace ospray { // Renderer definitions /////////////////////////////////////////////////////// Renderer::Renderer(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device), device(device), drtDevice(device.getDRTDevice()) { managedObjectType = OSP_RENDERER; pixelFilter = nullptr; } std::string Renderer::toString() const { return "ospray::Renderer"; } void Renderer::commit() { spp = std::max(1, getParam("pixelSamples", 1)); const float mipBias = getParam("mipMapBias", 0.f); const uint32_t maxDepth = std::max(0, getParam("maxPathLength", 20)); const float minContribution = getParam("minContribution", 0.001f); errorThreshold = getParam("varianceThreshold", 0.f); maxDepthTexture = getParamObject("map_maxDepth"); backplate = getParamObject("map_backplate"); featureFlags.reset(); if (maxDepthTexture || backplate) featureFlags.other |= FFO_TEXTURE_IN_RENDERER; if (maxDepthTexture) { if (maxDepthTexture->format != OSP_TEXTURE_R32F || maxDepthTexture->filter != OSP_TEXTURE_FILTER_NEAREST) { static WarnOnce warning( "maxDepthTexture provided to the renderer " "needs to be of type OSP_TEXTURE_R32F and have " "the OSP_TEXTURE_FILTER_NEAREST flag"); } } vec3f bgColor3 = getParam( "backgroundColor", vec3f(getParam("backgroundColor", 0.f))); bgColor = getParam("backgroundColor", vec4f(bgColor3, 0.f)); // Handle materials assigned to renderer materialArray = nullptr; getSh()->material = nullptr; materialData = getParamDataT("material"); if (materialData) { for (auto &&mat : *materialData) featureFlags |= mat->getFeatureFlags(); materialArray = devicert::make_buffer_shared_unique( getISPCDevice().getDRTDevice(), createArrayOfSh(*materialData)); getSh()->numMaterials = materialArray->size(); getSh()->material = materialArray->sharedPtr(); } getSh()->spp = spp; getSh()->maxDepth = maxDepth; getSh()->minContribution = minContribution; getSh()->bgColor = bgColor; getSh()->backplate = backplate ? backplate->getSh() : nullptr; getSh()->maxDepthTexture = maxDepthTexture ? maxDepthTexture->getSh() : nullptr; setupPixelFilter(); getSh()->pixelFilter = pixelFilter ? pixelFilter->getSh() : nullptr; getSh()->mipBiasFactor = powf(2, mipBias); } OSPPickResult Renderer::pick( FrameBuffer *fb, Camera *camera, World *world, const vec2f &screenPos) { OSPPickResult res; res.instance = nullptr; res.model = nullptr; res.primID = RTC_INVALID_GEOMETRY_ID; #ifndef OSPRAY_TARGET_SYCL int instID = RTC_INVALID_GEOMETRY_ID; int geomID = RTC_INVALID_GEOMETRY_ID; int primID = RTC_INVALID_GEOMETRY_ID; ispc::Renderer_pick(getSh(), fb->getSh(), camera->getSh(), world->getSh(), (const ispc::vec2f &)screenPos, (ispc::vec3f &)res.worldPosition[0], instID, geomID, primID, res.hasHit); if (res.hasHit) { auto *instance = (*world->instances)[instID]; auto *group = instance->group.ptr; if (!group->geometricModels) { res.hasHit = false; return res; } auto *model = (*group->geometricModels)[geomID]; instance->refInc(); model->refInc(); res.instance = (OSPInstance)instance; res.model = (OSPGeometricModel)model; res.primID = static_cast(primID); } #else // Silence unused parameter warning (void)fb; (void)camera; (void)world; (void)screenPos; #endif return res; } void Renderer::setupPixelFilter() { const auto pixelFilterType = (OSPPixelFilterType)getParam( "pixelFilter", OSPPixelFilterType::OSP_PIXELFILTER_GAUSS); pixelFilter = nullptr; switch (pixelFilterType) { case OSPPixelFilterType::OSP_PIXELFILTER_BOX: { pixelFilter = new BoxPixelFilter(getISPCDevice()); break; } case OSPPixelFilterType::OSP_PIXELFILTER_POINT: { pixelFilter = new PointPixelFilter(getISPCDevice()); break; } case OSPPixelFilterType::OSP_PIXELFILTER_BLACKMAN_HARRIS: { pixelFilter = new BlackmanHarrisLUTPixelFilter(getISPCDevice()); break; } case OSPPixelFilterType::OSP_PIXELFILTER_MITCHELL: { pixelFilter = new MitchellNetravaliLUTPixelFilter(getISPCDevice()); break; } case OSPPixelFilterType::OSP_PIXELFILTER_GAUSS: default: { pixelFilter = new GaussianLUTPixelFilter(getISPCDevice()); break; } } if (pixelFilter) { // Need to remove extra local ref pixelFilter->refDec(); } } OSPTYPEFOR_DEFINITION(Renderer *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/Renderer.h000066400000000000000000000046311464752671100227340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDeviceObject.h" #include "common/FeatureFlagsEnum.h" #include "pf/PixelFilter.h" #include "rkcommon/utility/ArrayView.h" #include "texture/Texture2D.h" // ispc shared #include "RendererShared.h" namespace ospray { struct Camera; struct World; struct Material; struct FrameBuffer; // abstract base class for all ospray renderers. // // This base renderer abstraction only knows about // 'rendering a frame'; most actual renderers will be derived from a // tile renderer, but this abstraction level also allows for frame // compositing or even projection/splatting based approaches struct OSPRAY_SDK_INTERFACE Renderer : public AddStructShared, public ObjectFactory { Renderer(api::ISPCDevice &device); virtual ~Renderer() override = default; virtual void commit() override; virtual std::string toString() const override; // called to initialize a new frame // // this function gets called exactly once (on each node) at the // beginning of each frame, and allows the renderer to do whatever // is required to initialize a new frame. In particular, this // function _can_ return a pointer to some "per-frame-data"; this // pointer (can be NULL) is then passed to 'renderFrame' to do with as they // please // // returns pointer to per-frame data, or NULL if this does not apply virtual void *beginFrame(FrameBuffer *fb, World *world); // called by the load balancer to render one "sample" for each task virtual devicert::AsyncEvent renderTasks(FrameBuffer *, Camera *, World *, void *, const utility::ArrayView &) const = 0; virtual OSPPickResult pick( FrameBuffer *fb, Camera *camera, World *world, const vec2f &screenPos); // Data // int32 spp{1}; float errorThreshold{0.f}; vec4f bgColor{0.f}; Ref maxDepthTexture; Ref backplate; Ref pixelFilter; Ref> materialData; BufferSharedUq materialArray; protected: FeatureFlags featureFlags; api::ISPCDevice &device; devicert::Device &drtDevice; private: void setupPixelFilter(); }; OSPTYPEFOR_SPECIALIZATION(Renderer *, OSP_RENDERER); inline void *Renderer::beginFrame(FrameBuffer *, World *) { return nullptr; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/Renderer.ih000066400000000000000000000010011464752671100230710ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" // c++ shared #include "RendererShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f Renderer_getBackground(const Renderer *uniform self, const vec2f &screenPos, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL float Renderer_getMaxDepth(const Renderer *uniform self, const vec2f &screenPos, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/Renderer.ispc000066400000000000000000000057731464752671100234530ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // TODO: Seems like ISPC bug: if Renderer.ih included before // Texture2D.ih I get an error that the Texture2D type is declared but not // defined #include "common/FeatureFlagsEnum.h" #include "texture/Texture2D.ih" #include "Renderer.ih" #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/World.ih" #include "fb/FrameBuffer.ih" #include "fb/FrameBufferDispatch.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f Renderer_getBackground(const Renderer *uniform self, const vec2f &screenPos, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); if (!self->backplate || !(ff.other & FFO_TEXTURE_IN_RENDERER)) return self->bgColor; // TODO: Now for GPU making a whole DifferentialGeometry object // just to set up the texture coords we want to sample for the background // seems very wasteful DifferentialGeometry lookup; initDgFromTexCoord(lookup, clamp2edge(self->backplate, screenPos)); return get4f(self->backplate, lookup); } SYCL_EXTERNAL float Renderer_getMaxDepth(const Renderer *uniform self, const vec2f &screenPos, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); if (!self->maxDepthTexture || !(ff.other & FFO_TEXTURE_IN_RENDERER)) return inf; DifferentialGeometry lookup; initDgFromTexCoord(lookup, screenPos); return max(0.f, get1f(self->maxDepthTexture, lookup)); } // Exports (called from C++) ////////////////////////////////////////////////// export void Renderer_pick(const void *uniform _self, const void *uniform, const void *uniform _camera, const void *uniform _world, const uniform vec2f &screenPos, uniform vec3f &pos, uniform int32 &instID, uniform int32 &geomID, uniform int32 &primID, uniform int32 &hit) { #ifndef OSPRAY_TARGET_SYCL const Renderer *uniform self = (const Renderer *uniform)_self; const Camera *uniform camera = (const Camera *uniform)_camera; const World *uniform world = (const World *uniform)_world; CameraSample cameraSample; cameraSample.screen.x = screenPos.x; cameraSample.screen.y = screenPos.y; // use center of lens and shutter time cameraSample.lens.x = 0.0f; cameraSample.lens.y = 0.0f; cameraSample.time = 0.5f; uniform FeatureFlagsHandler ffh; Ray ray; RayCone rayCone; Camera_dispatch_initRay(camera, ray, rayCone, cameraSample, ffh); ray.t = min(ray.t, Renderer_getMaxDepth(self, cameraSample.screen, ffh)); traceRay(world, ray, ffh); vec3f p = ray.org + ray.dir * ray.t; pos.x = extract(p.x, 0); pos.y = extract(p.y, 0); pos.z = extract(p.z, 0); hit = extract((int)(hadHit(ray)), 0); instID = extract(ray.instID, 0); geomID = extract(ray.geomID, 0); primID = extract(ray.primID, 0); #else (void)_self; (void)_camera; (void)_world; (void)screenPos; (void)pos; (void)instID; (void)geomID; (void)primID; (void)hit; #endif } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/RendererData.h000066400000000000000000000003451464752671100235240ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "OSPCommon.h" namespace ospray { struct RendererData { virtual ~RendererData() = default; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/RendererRenderTaskFn.inl000066400000000000000000000076071464752671100255440ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // Renderer common infrastructure shared among other renderers static void Renderer_default_renderTask(const uniform vec3ui itemIndex, Renderer *uniform self, FrameBuffer *uniform fb, Camera *uniform camera, World *uniform world, const uint32 *uniform taskIDs, const uniform FeatureFlagsHandler &ffh) { const uniform int32 spp = self->spp; ScreenSample screenSample; screenSample.z = inf; screenSample.alpha = 0.f; CameraSample cameraSample; uniform RenderTaskDesc taskDesc = FrameBuffer_dispatch_getRenderTaskDesc(fb, taskIDs[itemIndex.z], ffh); const uniform int startSampleID = fb->frameID * spp + 1; // Halton Sequence starts with 1 if (fb->cancelRender || isEmpty(taskDesc.region)) { return; } #ifndef ISPC { int32 y = taskDesc.region.lower.y + itemIndex.y; int32 x = taskDesc.region.lower.x + itemIndex.x; #else foreach_tiled (y = taskDesc.region.lower.y... taskDesc.region.upper.y, x = taskDesc.region.lower.x... taskDesc.region.upper.x) { #endif screenSample.sampleID.x = x; screenSample.sampleID.y = y; // set ray t value for early ray termination (from maximum depth texture) vec2f center = make_vec2f(screenSample.sampleID.x, screenSample.sampleID.y) + 0.5f; const float tMax = Renderer_getMaxDepth(self, center * fb->rcpSize, ffh); screenSample.z = tMax; vec3f col = make_vec3f(0.f); float alpha = 0.f; float depth = inf; vec3f normal = make_vec3f(0.f); vec3f albedo = make_vec3f(0.f); for (uniform int32 s = 0; s < spp; s++) { const float pixel_du = Halton_sample2(startSampleID + s); const float pixel_dv = CranleyPattersonRotation( Halton_sample3(startSampleID + s), 1.f / 6.f); // rotate to sample center (0.5) of pixel for sampleID=0 const vec2f pixelSample = make_vec2f(pixel_du, pixel_dv); const PixelFilter *uniform pf = self->pixelFilter; const vec2f pfSample = pf ? PixelFilter_dispatch_sample(pf, pixelSample) : pixelSample - make_vec2f(0.5f); screenSample.sampleID.z = startSampleID + s; cameraSample.pixel_center = (make_vec2f(x, y) + 0.5f) * fb->rcpSize; screenSample.pos = cameraSample.pixel_center; cameraSample.screen = cameraSample.pixel_center + pfSample * fb->rcpSize; // no DoF or MB per default cameraSample.lens.x = 0.0f; cameraSample.lens.y = 0.0f; cameraSample.time = 0.5f; Camera_dispatch_initRay( camera, screenSample.ray, screenSample.rayCone, cameraSample, ffh); // take screen resolution (unnormalized coordinates), i.e., pixel size // into account screenSample.rayCone.dwdt *= fb->rcpSize.y; screenSample.rayCone.width *= fb->rcpSize.y; screenSample.ray.t = min(screenSample.ray.t, tMax); screenSample.z = inf; screenSample.primID = RTC_INVALID_GEOMETRY_ID; screenSample.geomID = RTC_INVALID_GEOMETRY_ID; screenSample.instID = RTC_INVALID_GEOMETRY_ID; screenSample.albedo = make_vec3f(Renderer_getBackground(self, screenSample.pos, ffh)); screenSample.normal = make_vec3f(0.f); // The proper sample rendering function name is substituted here via macro renderSampleFn(self, fb, world, screenSample, ffh); col = col + screenSample.rgb; alpha += screenSample.alpha; depth = min(depth, screenSample.z); normal = normal + screenSample.normal; albedo = albedo + screenSample.albedo; } const float rspp = rcpf(spp); screenSample.rgb = col * rspp; screenSample.alpha = alpha * rspp; screenSample.z = depth; screenSample.normal = normal * rspp; screenSample.albedo = albedo * rspp; FrameBuffer_dispatch_accumulateSample(fb, screenSample, taskDesc, ffh); } FrameBuffer_dispatch_completeTask(fb, taskDesc, ffh); } RenderKit-ospray-85af292/modules/cpu/render/RendererShared.h000066400000000000000000000016461464752671100240660ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Texture2D; struct Material; struct PixelFilter; struct Renderer { int32 spp; vec4f bgColor; // background color and alpha Texture2D *backplate; Texture2D *maxDepthTexture; // optional maximum depth texture used for early // ray termination uint32 maxDepth; float minContribution; int32 numMaterials; Material **material; PixelFilter *pixelFilter; float mipBiasFactor; #ifdef __cplusplus Renderer() : spp(1), bgColor(0.f), backplate(nullptr), maxDepthTexture(nullptr), maxDepth(20), minContribution(0.001f), numMaterials(0), material(nullptr), pixelFilter(nullptr), mipBiasFactor(1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/RenderingFuture.h000066400000000000000000000047021464752671100242750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "common/DeviceRT.h" #include "common/Future.h" #include "fb/FrameBuffer.h" namespace ospray { struct RenderingFuture : public Future { RenderingFuture(FrameBuffer *fb, devicert::AsyncEvent rendererEvent, devicert::AsyncEvent frameBufferEvent, devicert::AsyncEvent finalHostEvent); ~RenderingFuture() override; bool isFinished(OSPSyncEvent event = OSP_TASK_FINISHED) override; void wait(OSPSyncEvent event = OSP_TASK_FINISHED) override; void cancel() override; float getProgress() override; float getTaskDuration() override; private: Ref fb; devicert::AsyncEvent rendererEvent; devicert::AsyncEvent frameBufferEvent; devicert::AsyncEvent finalHostEvent; }; // Inlined definitions ////////////////////////////////////////////////////// inline RenderingFuture::RenderingFuture(FrameBuffer *fb, devicert::AsyncEvent rendererEvent, devicert::AsyncEvent frameBufferEvent, devicert::AsyncEvent finalHostEvent) : fb(fb), rendererEvent(rendererEvent), frameBufferEvent(frameBufferEvent), finalHostEvent(finalHostEvent) {} inline RenderingFuture::~RenderingFuture() { // Wait for all work to be done when OSPRay future is released. This behavior // is mainly for OSPRay backwards compatibility, rendererEvent.wait(); frameBufferEvent.wait(); finalHostEvent.wait(); } inline bool RenderingFuture::isFinished(OSPSyncEvent event) { switch (event) { case OSP_TASK_FINISHED: return finalHostEvent.finished(); case OSP_FRAME_FINISHED: return frameBufferEvent.finished(); case OSP_WORLD_RENDERED: return rendererEvent.finished(); default: return true; } } inline void RenderingFuture::wait(OSPSyncEvent event) { switch (event) { case OSP_TASK_FINISHED: rendererEvent.wait(); frameBufferEvent.wait(); finalHostEvent.wait(); return; case OSP_FRAME_FINISHED: rendererEvent.wait(); frameBufferEvent.wait(); return; case OSP_WORLD_RENDERED: rendererEvent.wait(); return; default: return; } } inline void RenderingFuture::cancel() { fb->cancelFrame(); } inline float RenderingFuture::getProgress() { return fb->getCurrentProgress(); } inline float RenderingFuture::getTaskDuration() { return rendererEvent.getDuration() + frameBufferEvent.getDuration() + finalHostEvent.getDuration(); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/ScreenSample.ih000066400000000000000000000013721464752671100237170ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/Ray.ih" #include "common/RayCone.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct ScreenSample { // input values to 'renderSample' vec3i sampleID; // x/y=pixelID, z=accumID/sampleID vec2f pos; // normalized screen coord, center of pixel, for backplate sampling Ray ray; // the primary ray generated by the camera RayCone rayCone; // return values from 'renderSample' vec3f rgb; float alpha; float z; vec3f normal; vec3f albedo; // IDs of primary ray hits. Invalid: unsigned RTC_INVALID_GEOMETRY_ID, 0xffff unsigned int primID; unsigned int geomID; unsigned int instID; }; OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/ao/000077500000000000000000000000001464752671100214105ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/ao/AORenderer.cpp000066400000000000000000000036061464752671100241070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "AORenderer.h" #include "camera/Camera.h" #include "common/DeviceRT.h" #include "common/FeatureFlagsEnum.h" #include "common/World.h" #include "fb/FrameBuffer.h" // Kernel launcher is defined in another compilation unit DECLARE_RENDERER_KERNEL_LAUNCHER(AORenderer_renderTaskLauncher); namespace ospray { AORenderer::AORenderer(api::ISPCDevice &device, int defaultNumSamples) : AddStructShared(device.getDRTDevice(), device), aoSamples(defaultNumSamples) {} std::string AORenderer::toString() const { return "ospray::render::AO"; } void AORenderer::commit() { Renderer::commit(); getSh()->aoSamples = getParam("aoSamples", aoSamples); getSh()->aoRadius = getParam("aoDistance", getParam("aoRadius", 1e20f)); getSh()->aoIntensity = getParam("aoIntensity", 1.f); getSh()->volumeSamplingRate = getParam("volumeSamplingRate", 1.f); } devicert::AsyncEvent AORenderer::renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *, const utility::ArrayView &taskIDs) const { // Gather feature flags from all components FeatureFlags ff = world->getFeatureFlags(); ff |= featureFlags; ff |= fb->getFeatureFlags(); ff |= camera->getFeatureFlags(); // Prepare parameters for kernel launch auto *rendererSh = &getSh()->super; auto *fbSh = fb->getSh(); auto *cameraSh = camera->getSh(); auto *worldSh = world->getSh(); const size_t numTasks = taskIDs.size(); const vec2i taskSize = fb->getRenderTaskSize(); const vec3ui itemDims = vec3ui(taskSize.x, taskSize.y, numTasks); // Launch rendering kernel on the device return drtDevice.launchRendererKernel(itemDims, ispc::AORenderer_renderTaskLauncher, rendererSh, fbSh, cameraSh, worldSh, taskIDs.data(), ff); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/ao/AORenderer.h000066400000000000000000000012071464752671100235470ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "render/Renderer.h" // ispc shared #include "AORendererShared.h" namespace ospray { struct AORenderer : public AddStructShared { AORenderer(api::ISPCDevice &device, int defaultAORendererSamples = 1); std::string toString() const override; void commit() override; virtual devicert::AsyncEvent renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *perFrameData, const utility::ArrayView &taskIDs) const override; private: int aoSamples{1}; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/ao/AORenderer.ispc000066400000000000000000000116301464752671100242570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/DeviceRT.ih" #include "common/FeatureFlagsEnum.h" #include "fb/FrameBuffer.ih" #include "fb/FrameBufferDispatch.ih" #include "fb/RenderTaskDesc.ih" #include "math/random.ih" #include "pf/PixelFilterDispatch.ih" #include "render/Renderer.ih" #include "render/ScreenSample.ih" // AO renderer #include "surfaces.ih" #include "volumes.ih" // c++ shared #include "AORendererShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE static void AORenderer_renderSample(Renderer *uniform _self, FrameBuffer *uniform fb, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { uniform AORenderer *uniform self = (uniform AORenderer * uniform) _self; const uniform FeatureFlags ff = getFeatureFlags(ffh); RandomSampler randomSampler; RandomSampler_init(&randomSampler, sample.sampleID.x + fb->size.x * sample.sampleID.y, sample.sampleID.z); uniform bool firstHit = true; const float originalRayTFar = sample.ray.t; #ifdef OSPRAY_ENABLE_VOLUMES #ifdef OSPRAY_TARGET_SYCL // We only support a single volume interval on the GPU VolumeInterval vInterval; VolumeIntervals volumeIntervals; volumeIntervals.numVolumeIntervals = 0; volumeIntervals.numAllocated = 1; volumeIntervals.intervals = &vInterval; #else // Allocate memory for volume intervals VolumeIntervals volumeIntervals; allocVolumeIntervals(volumeIntervals); #endif #endif // This is our main ray Ray &ray = sample.ray; RayCone &rayCone = sample.rayCone; // First trace the ray across clipping scene to calculate ray intervals, // this step should keep ray structure unchanged RayIntervals rayIntervals; traceClippingRay(world, ray, rayIntervals, ffh); // Iterate over all translucent geometry till we are fully opaque vec4f outputColor = make_vec4f(0.f); while (outputColor.w < 0.99f) { // Then trace normal geometry using calculated ray intervals, // if hit ray.t will be updated if (ff.geometry) { traceGeometryRayIntervals(world, ray, rayIntervals, ffh); } #ifdef OSPRAY_ENABLE_VOLUMES if (ff.other & FFO_VOLUME_IN_SCENE) { // Determine volume intervals by tracing ray in the volume scene Ray volumeRay = ray; traceVolumeRay(world, volumeRay, volumeIntervals); // Sample volumes across volume intervals (in front of geometry hit) if (volumeIntervals.numVolumeIntervals > 0) { vec4f volumeColor = integrateVolumeIntervals(volumeIntervals, rayIntervals, volumeRay, randomSampler, self->volumeSamplingRate, ffh); outputColor = outputColor + (1.f - outputColor.w) * volumeColor; } } #endif // If any geometry has been hit vec4f blendedColor; const bool rayHadHit = hadHit(ray); if (rayHadHit && ff.geometry) { // Prepare differential geometry structure DifferentialGeometry dg; computeDG(world, self, ray, rayCone, dg, ffh); // Shade geometry SSI surfaceShading; surfaceShading = AORenderer_computeShading(self, world, dg, sample, ffh); // Use shaded color for blending blendedColor = surfaceShading.shadedColor; // Initialize other per sample data with first hit values if (firstHit) { sample.z = ray.t; sample.albedo = surfaceShading.albedo; sample.normal = dg.Ns; sample.instID = dg.instID; sample.geomID = dg.objID; sample.primID = ray.primID; } // Prepare ray for next loop iteration, // start from the last geometry hit all over to initial Tfar setRay(ray, ray.t + dg.epsilon, originalRayTFar); } else { blendedColor = Renderer_getBackground(&self->super, sample.pos, ffh); // Initialize other per sample data with first hit values if (firstHit) { sample.z = ray.t; sample.albedo = make_vec3f(blendedColor); sample.normal = sample.ray.dir; } } // Blend with output final color outputColor = outputColor + (1.f - outputColor.w) * blendedColor; firstHit = false; if (!rayHadHit) { break; } } #if defined(OSPRAY_ENABLE_VOLUMES) && !defined(OSPRAY_TARGET_SYCL) freeVolumeIntervals(volumeIntervals); #endif sample.rgb = make_vec3f(outputColor); sample.alpha = outputColor.w; } #define renderSampleFn AORenderer_renderSample #include "render/RendererRenderTaskFn.inl" #undef renderSampleFn inline void AORenderer_renderTask(const uniform vec3ui itemIndex, Renderer *uniform self, FrameBuffer *uniform fb, Camera *uniform camera, World *uniform world, const uint32 *uniform taskIDs, const uniform FeatureFlagsHandler &ffh) { Renderer_default_renderTask(itemIndex, self, fb, camera, world, taskIDs, ffh); } DEFINE_RENDERER_KERNEL_LAUNCHER(AORenderer_renderTask); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/ao/AORendererShared.h000066400000000000000000000007421464752671100247010ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/RendererShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct AORenderer { Renderer super; int aoSamples; float aoRadius; float aoIntensity; float volumeSamplingRate; #ifdef __cplusplus AORenderer() : aoSamples(1), aoRadius(1e20f), aoIntensity(1.f), volumeSamplingRate(1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/ao/surfaces.ih000066400000000000000000000020701464752671100235440ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlagsEnum.h" #include "common/World.ih" // c++ shared #include "AORendererShared.h" #include "common/RayCone.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct DifferentialGeometry; struct FrameBuffer; struct ScreenSample; struct SurfaceShadingInfo { vec4f shadedColor; vec3f albedo; }; typedef SurfaceShadingInfo SSI; inline void computeDG(const World *uniform world, const AORenderer *uniform renderer, const Ray &ray, RayCone &rayCone, DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { postIntersect(world, &renderer->super, dg, ray, rayCone, DG_NG | DG_NS | DG_NORMALIZE | DG_FACEFORWARD | DG_COLOR | DG_TEXCOORD | DG_TANGENTS, ffh); } SYCL_EXTERNAL SSI AORenderer_computeShading(const AORenderer *uniform self, const World *uniform world, const DifferentialGeometry &dg, ScreenSample &sample, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/ao/surfaces.ispc000066400000000000000000000041401464752671100241020ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #include "math/random.ih" #include "math/sampling.ih" #include "render/ScreenSample.ih" #include "render/materials/OBJ.ih" #include "render/util.ih" #include "texture/TextureParam.ih" // AO Renderer #include "surfaces.ih" // c++ shared #include "render/materials/OBJShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline vec4f getSurfaceColor( const DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { const OBJ *mat = (const OBJ *)dg.material; vec3f surfaceColor = make_vec3f(1.f); float opacity = 1.f; const uniform FeatureFlags ff = getFeatureFlags(ffh); const uniform bool fft = ff.other & FFO_TEXTURE_IN_MATERIAL; foreach_unique (m in mat) { if (m != NULL && m->super.type == MATERIAL_TYPE_OBJ) { surfaceColor = m->Kd; if (valid(m->KdMap) && fft) { vec4f Kd_from_map = get4f(m->KdMap, dg); surfaceColor = surfaceColor * make_vec3f(Kd_from_map); opacity *= Kd_from_map.w; } opacity *= m->d * (fft ? get1f(m->dMap, dg, 1.f) : 1.f); } } return make_vec4f(surfaceColor * make_vec3f(dg.color), opacity * dg.color.w); } SYCL_EXTERNAL SSI AORenderer_computeShading(const AORenderer *uniform self, const World *uniform world, const DifferentialGeometry &dg, ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { SSI retval; const vec4f surfaceColor = getSurfaceColor(dg, ffh); const vec3f color = make_vec3f(surfaceColor); const float opacity = surfaceColor.w; const float eyeLightIntensity = absf(dot(dg.Ns, sample.ray.dir)) * opacity; float intensity = eyeLightIntensity; if (self->aoSamples > 0 && self->aoIntensity > 0.01f) { const float ao = computeAO(&self->super, world, dg, self->aoSamples, self->aoRadius, sample.sampleID, ffh); intensity *= (1.0f - self->aoIntensity) + (ao * self->aoIntensity); } retval.shadedColor = make_vec4f(color * intensity, opacity); retval.albedo = color; return retval; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/ao/volumes.ih000066400000000000000000000011101464752671100234150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "common/Clipping.ih" #include "common/FeatureFlagsEnum.h" #include "common/Ray.ih" #include "common/VolumeIntervals.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct RandomSampler; SYCL_EXTERNAL vec4f integrateVolumeIntervals(const VolumeIntervals &intervals, const RayIntervals &rayIntervals, Ray &ray, RandomSampler &randomSampler, const uniform float samplingRate, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/ao/volumes.ispc000066400000000000000000000260531464752671100237700ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "math/random.ih" #include "math/sampling.ih" #include "render/util.ih" #include "volume/Volume.ih" #include "volume/VolumetricModel.ih" #include "volume/transferFunction/TransferFunctionDispatch.ih" #include "volumes.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #ifndef OSPRAY_TARGET_SYCL struct VolumeContext { uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; VKLIntervalIterator intervalIterator; VKLInterval interval; vec3f org; vec3f dir; float iuLength; // VKL interval length in sampling steps as an unit float iuDistance; // sampling distance within VKL interval in sampling steps // as an unit float distance; // last sampling distance from 'vc.org' vec4f sample; uint32 ready; // 1 if sample is ready to be used }; static void sampleVolume(VolumeContext &vc, const VolumetricModel *uniform m, const uniform float samplingRate) { // We have to iterate till we get a valid sample value float dt = 0.f; float sampleVal = nan; while (isnan(sampleVal)) { // Iterate till sampling position is within interval float emptySpace = 0.f; while (vc.iuDistance > vc.iuLength) { // Get next VKL interval const float prevUpper = vc.interval.tRange.upper; if (vklIterateIntervalV(vc.intervalIterator, &vc.interval)) { // Intervals may not be contiguous, accumulate empty space emptySpace += max(vc.interval.tRange.lower - prevUpper, 0.f); // Make it local for the next interval vc.iuDistance -= vc.iuLength; // Calculate how many steps can be made within this interval const float samplingStep = vc.interval.nominalDeltaT / samplingRate; vc.iuLength = (vc.interval.tRange.upper - vc.interval.tRange.lower) / samplingStep; // Initialize distance if necessary vc.distance = (vc.distance == inf) ? vc.interval.tRange.lower : vc.distance; } else { // The end of the volume has been reached vc.distance = inf; return; } } // Calculate sampling distance const float samplingStep = vc.interval.nominalDeltaT / samplingRate; const float newDistance = vc.interval.tRange.lower + vc.iuDistance * samplingStep; // Prepare sampling position const vec3f p = vc.org + newDistance * vc.dir; // Sample volume value in given point sampleVal = vklComputeSampleV( &m->volume->vklSampler, (const varying vkl_vec3f *uniform) & p); // Go to the next sub-interval vc.iuDistance += 1.f; dt = newDistance - vc.distance - emptySpace; vc.distance = newDistance; } // Apply transfer function to get color with alpha vc.sample = TransferFunction_dispatch_get(m->transferFunction, sampleVal); // Weight the opacity with deltaT using Beer law vc.sample.w = 1.f - exp(-vc.sample.w * dt * m->densityScale); } static float sampleAllVolumes(const VolumeIntervals &volumeIntervals, varying VolumeContext *uniform volumeContexts, const uniform float samplingRate, vec4f &sampledColor) { // Look for the closest sample across all volumes float minDist = inf; int usedSampleId = -1; for (uniform uint32 i = 0; i < reduce_max(volumeIntervals.numVolumeIntervals); i++) { if (i >= volumeIntervals.numVolumeIntervals) break; // If the sample has been used already regenerate a new one VolumeContext &vc = volumeContexts[i]; if (vc.ready == 0) { const VolumeInterval &vi = volumeIntervals.intervals[i]; foreach_unique (m in vi.volumetricModel) sampleVolume(vc, m, samplingRate); vc.ready = 1; } // Take the sample if closer if (vc.distance < minDist) { minDist = vc.distance; sampledColor = vc.sample; usedSampleId = i; } } // Mark used samples as not ready if (usedSampleId != -1) { volumeContexts[usedSampleId].ready = 0; } // Return distance for sampled color return minDist; } SYCL_EXTERNAL vec4f integrateVolumeIntervals( const VolumeIntervals &volumeIntervals, const RayIntervals &rayIntervals, Ray &ray, RandomSampler &randomSampler, const uniform float samplingRate, const uniform FeatureFlagsHandler &) { // Array of volume contexts varying VolumeContext *uniform volumeContexts = (varying VolumeContext * uniform) pushTLS(reduce_max(volumeIntervals.numVolumeIntervals) * sizeof(varying VolumeContext)); // Sampling position jitter const float jitter = RandomSampler_getFloat(&randomSampler); // Iterate through all volumes and initialize its contexts with data that // do not change across ray intervals for (uniform uint32 i = 0; i < reduce_max(volumeIntervals.numVolumeIntervals); i++) { if (i >= volumeIntervals.numVolumeIntervals) break; // Transform ray into the volume local space const VolumeInterval &vi = volumeIntervals.intervals[i]; Ray transformedRay = ray; AffineSpace3f instanceRcpXfm = vi.instance->rcp_xfm; transformRay(transformedRay, instanceRcpXfm); // Set volume context initial values VolumeContext &vc = volumeContexts[i]; vc.org = transformedRay.org; vc.dir = transformedRay.dir; } // Define initial color with alpha vec3f color = make_vec3f(0.f); float alpha = 0.f; // Iterate through all ray intervals for (uniform uint32 i = 0; i < reduce_max(rayIntervals.count) && (alpha < .99f); i++) { if (i >= rayIntervals.count) break; // Iterate through all volumes for (uniform uint32 j = 0; j < reduce_max(volumeIntervals.numVolumeIntervals); j++) { if (j >= volumeIntervals.numVolumeIntervals) break; // Calculate volume and ray intervals union const VolumeInterval &vi = volumeIntervals.intervals[j]; range1f rInterval = rayIntervals.intervals[i]; rInterval.lower = max(rInterval.lower, vi.interval.lower); rInterval.upper = min(rInterval.upper, vi.interval.upper); // Reset distance to sample VolumeContext &vc = volumeContexts[j]; vc.distance = inf; // Check if volume and ray intervals overlap if (rInterval.upper <= rInterval.lower) { // Skip this volume if not vc.ready = 1; continue; } // We will sample across this volume so initialize members used during // sampling vc.iuDistance = jitter; vc.iuLength = 0.f; vc.ready = 0; vc.interval.tRange.upper = inf; // There might be different volumetric models used across vector lanes // so we must iterate over them float time = 0.5f; VolumetricModel *varying model = vi.volumetricModel; // Create volume interval iterator foreach_unique (m in model) vc.intervalIterator = vklInitIntervalIteratorV(&m->vklIntervalContext, (varying vkl_vec3f *)&vc.org, (varying vkl_vec3f *)&vc.dir, (varying vkl_range1f *)&rInterval, &time, vc.intervalIteratorBuffer); } // Propagate ray across all volumes till opaque while (alpha < .99f) { // Sample across all volumes vec4f sampledColorOpacity; float dist = sampleAllVolumes( volumeIntervals, volumeContexts, samplingRate, sampledColorOpacity); // Exit loop if nothing sampled if (dist == inf) break; // Alpha blend sampled color color = color + ((1.f - alpha) * sampledColorOpacity.w * make_vec3f(sampledColorOpacity)); alpha = alpha + ((1.f - alpha) * sampledColorOpacity.w); } } popTLS(volumeContexts); // Return final color return make_vec4f(color, alpha); } #else // GPU version SYCL_EXTERNAL vec4f integrateVolumeIntervals( const VolumeIntervals &volumeIntervals, const RayIntervals &, Ray &ray, RandomSampler &randomSampler, const uniform float samplingRate, const uniform FeatureFlagsHandler &ffh) { const VolumeInterval &vi = volumeIntervals.intervals[0]; Ray tRay = ray; AffineSpace3f instanceRcpXfm = vi.instance->rcp_xfm; transformRay(tRay, instanceRcpXfm); // Define initial color with alpha vec3f color = make_vec3f(0.f); float alpha = 0.f; const uniform FeatureFlags ff = getFeatureFlags(ffh); uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; VolumetricModel *varying m = vi.volumetricModel; VKLIntervalIterator intervalIterator = vklInitIntervalIteratorV(&m->vklIntervalContext, (varying vkl_vec3f *)&tRay.org, (varying vkl_vec3f *)&tRay.dir, (varying vkl_range1f *)&vi.interval, .5f, intervalIteratorBuffer, ff.volume); // Sampling position jitter const float jitter = RandomSampler_getFloat(&randomSampler); // Propagate ray across all volumes till opaque float distance = inf; float iuDistance = jitter; float iuLength = 0.f; VKLInterval interval; interval.tRange.upper = inf; float samplingStep = 0.f; while (alpha < .99f) { // Iterate till sampling position is within interval float emptySpace = 0.f; while (iuDistance > iuLength) { // Get next VKL interval const float prevUpper = interval.tRange.upper; if (vklIterateIntervalV(intervalIterator, &interval, ff.volume)) { // Intervals may not be contiguous, accumulate empty space emptySpace += max(interval.tRange.lower - prevUpper, 0.f); // Make it local for the next interval iuDistance -= iuLength; // Calculate how many steps can be made within this interval samplingStep = interval.nominalDeltaT / samplingRate; iuLength = (interval.tRange.upper - interval.tRange.lower) / samplingStep; // Initialize distance if necessary distance = (distance == inf) ? interval.tRange.lower : distance; } else { // The end of the volume has been reached return make_vec4f(color, alpha); } } // Calculate sampling distance const float newDistance = interval.tRange.lower + iuDistance * samplingStep; // Prepare sampling position const vec3f p = tRay.org + newDistance * tRay.dir; // Sample volume value in given point float sampleVal = vklComputeSampleV(&m->volume->vklSampler, (const varying vkl_vec3f *uniform) & p, 0, .5f, ff.volume); if (!isnan(sampleVal)) { // Apply transfer function to get color with alpha vec4f sampledColor = TransferFunction_dispatch_get(m->transferFunction, sampleVal); // Weight the opacity with deltaT using Beer law float dt = newDistance - distance - emptySpace; sampledColor.w = 1.f - exp(-sampledColor.w * dt * m->densityScale); // Alpha blend sampled color color = color + ((1.f - alpha) * sampledColor.w * make_vec3f(sampledColor)); alpha = alpha + ((1.f - alpha) * sampledColor.w); } // Go to the next sub-interval iuDistance += 1.f; distance = newDistance; } // Return final color return make_vec4f(color, alpha); } #endif OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/bsdfs/000077500000000000000000000000001464752671100221125ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/bsdfs/BSDF.ih000066400000000000000000000064541464752671100231630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "common/OSPCommon.ih" #include "render/pathtracer/Scattering.ih" #include "rkcommon/math/LinearSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // keep interface of BSDFs the same typedef Scattering_EvalRes BSDF_EvalRes; typedef Scattering_SampleRes BSDF_SampleRes; typedef Scattering_Type BSDFScatteringType; #define BSDF_SPECULAR_REFLECTION SCATTERING_SPECULAR_REFLECTION #define BSDF_GLOSSY_REFLECTION SCATTERING_GLOSSY_REFLECTION #define BSDF_DIFFUSE_REFLECTION SCATTERING_DIFFUSE_REFLECTION #define BSDF_SPECULAR_TRANSMISSION SCATTERING_SPECULAR_TRANSMISSION #define BSDF_GLOSSY_TRANSMISSION SCATTERING_GLOSSY_TRANSMISSION #define BSDF_DIFFUSE_TRANSMISSION SCATTERING_DIFFUSE_TRANSMISSION #define BSDF_DIFFUSE SCATTERING_DIFFUSE #define BSDF_GLOSSY SCATTERING_GLOSSY #define BSDF_SPECULAR SCATTERING_SPECULAR #define BSDF_REFLECTION SCATTERING_REFLECTION #define BSDF_TRANSMISSION SCATTERING_TRANSMISSION #define BSDF_SMOOTH SCATTERING_SMOOTH #define BSDF_NONE SCATTERING_NONE #define BSDF_ALL SCATTERING_ALL enum BSDFType { BSDF_TYPE_UNKNOWN, BSDF_TYPE_OBJ, BSDF_TYPE_THINGLASS, BSDF_TYPE_GLASS, BSDF_TYPE_LUMINOUS, BSDF_TYPE_METAL, BSDF_TYPE_METAL_ROUGH, BSDF_TYPE_METALLICPAINT, BSDF_TYPE_MIX, BSDF_TYPE_CARPAINT, BSDF_TYPE_PRINCIPLED, BSDF_TYPE_ALLOY, BSDF_TYPE_ALLOY_ROUGH, BSDF_TYPE_PLASTIC, BSDF_TYPE_VELVET, BSDF_TYPE_CONDUCTOR, BSDF_TYPE_DIELECTRIC, BSDF_TYPE_DIELECTRIC_LAYER, BSDF_TYPE_LAMBERT, BSDF_TYPE_LAMBERT_TRANSMISSION, BSDF_TYPE_MICROFACET_CONDUCTOR, BSDF_TYPE_MICROFACET_DIELECTRIC, BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER, BSDF_TYPE_MICROFACET_SHEEN_LAYER, BSDF_TYPE_MINNEART, BSDF_TYPE_MULTI_BSDF, BSDF_TYPE_OREN_NAYAR, BSDF_TYPE_SPECULAR, BSDF_TYPE_SCALE, BSDF_TYPE_REFLECTION, BSDF_TYPE_ROBUST_DIELECTRIC, BSDF_TYPE_ROBUST_THIN_DIELECTRIC, BSDF_TYPE_THIN_DIELECTRIC, BSDF_TYPE_THIN_MICROFACET_DIELECTRIC, BSDF_TYPE_TRANSMISSION, BSDF_TYPE_VELVETY }; inline BSDF_EvalRes make_BSDF_EvalRes_zero() { BSDF_EvalRes res; res.value = make_vec3f(0.0f); res.pdf = 0.0f; return res; } inline BSDF_SampleRes make_BSDF_SampleRes_zero() { BSDF_SampleRes res; res.weight = make_vec3f(0.0f); return res; } struct BSDF { varying vec3f albedo; varying BSDFScatteringType scatteringType; uniform BSDFType bsdfType; const varying linear3f *uniform frame; }; inline void BSDF_Constructor(varying BSDF *uniform self, varying vec3f albedo, varying BSDFScatteringType scatteringType, uniform BSDFType bsdfType, const varying linear3f *uniform frame) { self->albedo = albedo; self->scatteringType = scatteringType; self->bsdfType = bsdfType; self->frame = frame; } inline vec3f getN(const varying BSDF *uniform bsdf) { return bsdf->frame->vz; } inline linear3f getFrame(const varying BSDF *uniform bsdf) { return *bsdf->frame; } SYCL_EXTERNAL BSDF_EvalRes BSDF_dispatch_eval(const varying BSDF *uniform self, const vec3f &wo, const vec3f &wi, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_SampleRes BSDF_dispatch_sample( const varying BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/BSDF.ispc000066400000000000000000000106161464752671100235140ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/bsdfs/BSDF.ih" #include "common/FeatureFlags.ih" #include "render/materials/Alloy.ih" #include "render/materials/CarPaint.ih" #include "render/materials/Glass.ih" #include "render/materials/Luminous.ih" #include "render/materials/Metal.ih" #include "render/materials/MetallicPaint.ih" #include "render/materials/Mix.ih" #include "render/materials/OBJ.ih" #include "render/materials/Plastic.ih" #include "render/materials/Principled.ih" #include "render/materials/ThinGlass.ih" #include "render/materials/Velvet.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL BSDF_EvalRes BSDF_dispatch_eval(const varying BSDF *uniform self, const vec3f &wo, const vec3f &wi, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->bsdfType == BSDF_TYPE_OBJ) && (ffo & FFO_MATERIAL_OBJ)) { return OBJ_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_ALLOY_ROUGH) && (ffo & FFO_MATERIAL_ALLOY)) { return AlloyRough_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_METAL_ROUGH) && (ffo & FFO_MATERIAL_METAL)) { return MetalRough_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_METALLICPAINT) && (ffo & FFO_MATERIAL_METALLICPAINT)) { return MetallicPaint_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_CARPAINT) && (ffo & FFO_MATERIAL_CARPAINT)) { return CarPaint_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_PRINCIPLED) && (ffo & FFO_MATERIAL_PRINCIPLED)) { return Principled_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_PLASTIC) && (ffo & FFO_MATERIAL_PLASTIC)) { return Plastic_BSDF_eval(self, wo, wi); } else if ((self->bsdfType == BSDF_TYPE_VELVET) && (ffo & FFO_MATERIAL_VELVET)) { return Velvet_BSDF_eval(self, wo, wi); } #ifndef OSPRAY_TARGET_SYCL else if ((self->bsdfType == BSDF_TYPE_MIX) && (ffo & FFO_MATERIAL_MIX)) { return Mix_BSDF_eval(self, wo, wi); } #endif return make_BSDF_EvalRes_zero(); } SYCL_EXTERNAL BSDF_SampleRes BSDF_dispatch_sample( const varying BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); if ((self->bsdfType == BSDF_TYPE_OBJ) && (ffo & FFO_MATERIAL_OBJ)) { return OBJ_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_THINGLASS) && (ffo & FFO_MATERIAL_THINGLASS)) { return ThinGlass_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_GLASS) && (ffo & FFO_MATERIAL_GLASS)) { return Glass_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_LUMINOUS) && (ffo & FFO_MATERIAL_LUMINOUS)) { return Luminous_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_ALLOY) && (ffo & FFO_MATERIAL_ALLOY)) { return Alloy_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_ALLOY_ROUGH) && (ffo & FFO_MATERIAL_ALLOY)) { return AlloyRough_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_METAL) && (ffo & FFO_MATERIAL_METAL)) { return Metal_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_METAL_ROUGH) && (ffo & FFO_MATERIAL_METAL)) { return MetalRough_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_METALLICPAINT) && (ffo & FFO_MATERIAL_METALLICPAINT)) { return MetallicPaint_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_CARPAINT) && (ffo & FFO_MATERIAL_CARPAINT)) { return CarPaint_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_PRINCIPLED) && (ffo & FFO_MATERIAL_PRINCIPLED)) { return Principled_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_PLASTIC) && (ffo & FFO_MATERIAL_PLASTIC)) { return Plastic_BSDF_sample(self, wo, s, ss); } else if ((self->bsdfType == BSDF_TYPE_VELVET) && (ffo & FFO_MATERIAL_VELVET)) { return Velvet_BSDF_sample(self, wo, s, ss); } #ifndef OSPRAY_TARGET_SYCL else if ((self->bsdfType == BSDF_TYPE_MIX) && (ffo & FFO_MATERIAL_MIX)) { return Mix_BSDF_sample(self, wo, s, ss); } #endif return make_BSDF_SampleRes_zero(); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/BeckmannDistribution.ih000066400000000000000000000016741464752671100265620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MicrofacetDistribution.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Beckmann distribution struct BeckmannDistribution { float alpha; }; inline BeckmannDistribution make_BeckmannDistribution(float alpha) { BeckmannDistribution m; m.alpha = alpha; return m; } inline vec3f sample( const BeckmannDistribution &self, float &pdf, const vec2f &s) { float alpha2 = sqr(self.alpha); float tanTheta2 = -alpha2 * log(1.f - s.x); float cosTheta = rsqrt(1.f + tanTheta2); float sinTheta = cos2sin(cosTheta); float phi = 2.f * (float)pi * s.y; float cosTheta3 = sqr(cosTheta) * cosTheta; pdf = (1.f - s.x) * rcp((float)pi * alpha2 * cosTheta3); float sinPhi, cosPhi; sincos(phi, &sinPhi, &cosPhi); float x = cosPhi * sinTheta; float y = sinPhi * sinTheta; float z = cosTheta; return make_vec3f(x, y, z); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Conductor.ih000066400000000000000000000024751464752671100244040ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "Fresnel.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Conductor { BSDF super; Fresnel *uniform fresnel; }; inline BSDF_SampleRes Conductor_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &, float) { const varying Conductor *uniform self = (const varying Conductor *uniform)super; BSDF_SampleRes res; res.wi = reflect(wo, getN(super)); res.pdf = inf; res.type = BSDF_SPECULAR_REFLECTION; res.weight = Fresnel_dispatch_eval(self->fresnel, dot(wo, getN(super))); return res; } inline void Conductor_Constructor(varying Conductor *uniform self, const varying linear3f *uniform frame, Fresnel *uniform fresnel) { BSDF_Constructor(&self->super, Fresnel_dispatch_evalAvg(fresnel), BSDF_SPECULAR_REFLECTION, BSDF_TYPE_CONDUCTOR, frame); self->fresnel = fresnel; } inline varying BSDF *uniform Conductor_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, Fresnel *uniform fresnel) { varying Conductor *uniform self = (varying Conductor * uniform) ShadingContext_alloc(ctx, sizeof(Conductor)); Conductor_Constructor(self, frame, fresnel); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Dielectric.ih000066400000000000000000000042431464752671100245060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "Fresnel.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // FIXME: improve robustness struct Dielectric { BSDF super; float eta; // etaO / etaI }; inline BSDF_EvalRes Dielectric_eval( const varying BSDF *uniform, const vec3f &, const vec3f &) { return make_BSDF_EvalRes_zero(); } inline BSDF_SampleRes Dielectric_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &, float ss) { const varying Dielectric *uniform self = (const varying Dielectric *uniform)super; BSDF_SampleRes res; float cosThetaO = max(dot(wo, getN(super)), 0.f); // Fresnel term float cosThetaT; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaT, self->eta); res.pdf = inf; // Sample the reflection or the transmission bool doReflection = (ss <= F); if (doReflection) { // Reflection res.wi = reflect(wo, getN(super), cosThetaO); res.type = BSDF_SPECULAR_REFLECTION; res.weight = make_vec3f(1.f); } else { // Transmission res.wi = refract(wo, getN(super), cosThetaO, cosThetaT, self->eta); res.type = BSDF_SPECULAR_TRANSMISSION; // res.weight = make_vec3f(sqr(self->eta)); // solid angle compression res.weight = make_vec3f(1.f); // ignore solid angle compression } return res; } inline void Dielectric_Constructor(varying Dielectric *uniform self, const varying linear3f *uniform frame, float eta) { BSDF_Constructor(&self->super, make_vec3f(1.0f), BSDF_SPECULAR, BSDF_TYPE_DIELECTRIC, frame); self->eta = eta; } inline varying BSDF *uniform Dielectric_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, float eta) { varying Dielectric *uniform self = (varying Dielectric * uniform) ShadingContext_alloc(ctx, sizeof(Dielectric)); Dielectric_Constructor(self, frame, eta); return &self->super; } // Helper function for transparent shadow rays inline vec3f Dielectric_getTransparency(float cosThetaO, float eta) { float T = 1.f - fresnelDielectric(cosThetaO, eta); return make_vec3f(T); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/DielectricLayer.ih000066400000000000000000000241571464752671100255110ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Dielectric.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Simplified, energy conserving Weidlich-Wilkie smooth coating BSDF. // Refraction is ignored, but absorption is computed from the refracted ray // lengths. [Weidlich and Wilkie, 2007, "Arbitrarily Layered Micro-Facet // Surfaces"] [Kulla and Conty, 2017, "Revisiting Physically Based Shading at // Imageworks"] [Kelemen and Szirmay-Kalos, 2001, "A Microfacet Based Coupled // Specular-Matte BRDF Model with Importance Sampling"] struct DielectricLayer { BSDF super; float weight; float eta; vec3f transmittance; float thickness; // Energy conservation [Kulla and Conty, 2017] float Favg; }; inline void DielectricLayer_Constructor(varying DielectricLayer *uniform self, const varying linear3f *uniform frame, varying BSDF *varying substrate, float eta, vec3f transmittance, float thickness, float weight) { self->Favg = fresnelDielectricAvg(eta) * weight; // XXX check const vec3f albedo = substrate->albedo * ((1.0f - weight) + pow(transmittance, thickness) * (1.f - self->Favg)); BSDF_Constructor(&self->super, albedo, BSDF_SPECULAR_REFLECTION | substrate->scatteringType, BSDF_TYPE_DIELECTRIC_LAYER, frame); self->eta = (eta <= 1.f) ? eta : rcp(eta); self->transmittance = transmittance; self->thickness = thickness; self->weight = weight; } // Helper function for transparent shadow rays inline vec3f DielectricLayer_getTransparency(float cosThetaO, float eta, vec3f transmittance, float thickness, float weight) { if (eta < 1.f) eta = rcp(eta); // Fresnel term float cosThetaO1; // positive float Fo = fresnelDielectricEx(cosThetaO, cosThetaO1, eta) * weight; // Apply the coating medium absorption // Use refracted angles for computing the absorption path length float lengthO1 = rcp(cosThetaO1); vec3f value = lerp(weight, make_vec3f(1.f), pow(transmittance, thickness * lengthO1)); // Energy conservation float T = 1.f - Fo; // for generic (non-diffuse) substrates [Kulla and Conty, 2017] value = value * T; return value; } OSPRAY_END_ISPC_NAMESPACE // Eval macros #define DIELECTRICLAYER_EVAL( \ dl_name, scatteringType, substrate_bsdf, substrate_fn) \ const varying DielectricLayer *uniform dl = \ (const varying DielectricLayer *uniform) & dl_name; \ \ float cosThetaO = dot(wo, getN(&dl->super)); \ if (cosThetaO <= 0.f) \ return make_BSDF_EvalRes_zero(); \ \ /* Evaluate the substrate */ \ /* Ignore refraction */ \ BSDF_EvalRes substrate = substrate_fn(substrate_bsdf, wo, wi); \ \ /* Fresnel term */ \ float cosThetaO1; /* positive */ \ float Fo = fresnelDielectricEx(cosThetaO, cosThetaO1, dl->eta) * dl->weight; \ \ float cosThetaI = dot(wi, getN(&dl->super)); \ float cosThetaI1; /* positive */ \ float Fi = \ fresnelDielectricEx(abs(cosThetaI), cosThetaI1, dl->eta) * dl->weight; \ \ /* Apply the coating medium absorption */ \ /* Use refracted angles for computing the absorption path length */ \ float lengthO1 = rcp(cosThetaO1); \ float lengthI1 = rcp(cosThetaI1); \ float length = lengthO1 + lengthI1; \ if (cosThetaI <= 0.f) \ length *= 0.5f; /* for transmission, use the average length */ \ substrate.value = lerp(dl->weight, \ substrate.value, \ substrate.value * pow(dl->transmittance, dl->thickness * length)); \ \ /* Energy conservation */ \ float T; \ if (scatteringType & ~BSDF_DIFFUSE) \ T = min(1.f - Fo, 1.f - Fi); /* for generic (non-diffuse) substrates \ [Kulla and Conty, 2017] */ \ else \ T = (1.f - Fo) * (1.f - Fi) \ * rcp(1.f - dl->Favg); /* for diffuse substrates [Kelemen and \ Szirmay-Kalos, 2001] */ \ substrate.value = substrate.value * T; \ substrate.pdf *= (1.f - Fo) #define DIELECTRICLAYER_EVAL_GET() substrate // Sample macros #define DIELECTRICLAYER_SAMPLE( \ dl_name, scatteringType, substrate_bsdf, substrate_fn) \ const varying DielectricLayer *uniform dl = \ (const varying DielectricLayer *uniform) & dl_name; \ BSDF_SampleRes res; \ \ float cosThetaO = dot(wo, getN(&dl->super)); \ if (cosThetaO <= 0.f) \ return make_BSDF_SampleRes_zero(); \ \ /* Fresnel term */ \ float cosThetaO1; /* positive */ \ float Fo = fresnelDielectricEx(cosThetaO, cosThetaO1, dl->eta) * dl->weight; \ \ if (ss < Fo) { \ /* Sample the coating */ \ res.type = BSDF_SPECULAR_REFLECTION; \ res.wi = reflect(wo, getN(&dl->super), cosThetaO); \ res.pdf = inf; \ res.weight = make_vec3f(1.f); \ } else { \ /* Sample the substrate */ \ /* Ignore refraction */ \ float ss1 = (ss - Fo) * rcp(1.f - Fo); /* reallocate sample */ \ res = substrate_fn(substrate_bsdf, wo, s, ss1); \ if (reduce_max(res.weight) <= 0.f) \ return res; \ float cosThetaI = dot(res.wi, getN(&dl->super)); \ \ float cosThetaI1; /* positive */ \ float Fi = \ fresnelDielectricEx(abs(cosThetaI), cosThetaI1, dl->eta) * dl->weight; \ \ /* Apply the coating medium absorption */ \ /* Use refracted angles for computing the absorption path length */ \ float lengthO1 = rcp(cosThetaO1); \ float lengthI1 = rcp(cosThetaI1); \ float length = lengthO1 + lengthI1; \ if (cosThetaI <= 0.f) \ length *= 0.5f; /* for transmission, use the average length */ \ res.weight = lerp(dl->weight, \ res.weight, \ res.weight * pow(dl->transmittance, dl->thickness * length)); \ \ /* Energy conservation */ \ float T; \ if (scatteringType & ~BSDF_DIFFUSE) \ T = min(1.f - Fo, 1.f - Fi); /* for generic (non-diffuse) substrates \ [Kulla and Conty, 2017] */ \ else \ T = (1.f - Fo) * (1.f - Fi) \ * rcp(1.f - dl->Favg); /* for diffuse substrates [Kelemen and \ Szirmay-Kalos, 2001] */ \ res.weight = res.weight * (T * rcp(1.f - Fo)); \ res.pdf *= (1.f - Fo); \ } #define DIELECTRICLAYER_SAMPLE_GET() res RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Fresnel.ih000066400000000000000000000224301464752671100240330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Optics.ih" #include "ShadingContext.ih" #include "math/sampling.ih" #include "math/spectrum.ih" #include "rkcommon/math/LinearSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE //! \brief Computes fresnel coefficient for dielectric medium /*! \detailed Computes fresnel coefficient for media interface with * relative refraction index eta. Eta is the outside refraction index * divided by the inside refraction index. Both cosines have to be * positive. */ inline float fresnelDielectric(float cosI, float cosT, float eta) { const float Rper = (eta * cosI - cosT) * rcpf(eta * cosI + cosT); const float Rpar = (cosI - eta * cosT) * rcpf(cosI + eta * cosT); return 0.5f * (sqr(Rpar) + sqr(Rper)); } /*! Computes fresnel coefficient for media interface with relative * refraction index eta. Eta is the outside refraction index * divided by the inside refraction index. The cosine has to be * positive. */ inline float fresnelDielectric(float cosI, float eta) { const float sqrcost = sqrCosT(cosI, eta); if (sqrcost < 0.0f) return 1.0f; return fresnelDielectric(cosI, sqrt(sqrcost), eta); } inline float fresnelDielectricEx(float cosI, float &cosT, float eta) { const float sqrcost = sqrCosT(cosI, eta); if (sqrcost < 0.0f) { cosT = 0.0f; return 1.0f; } cosT = sqrt(sqrcost); return fresnelDielectric(cosI, cosT, eta); } // F_{\mathit{avg}} = 2 \int_0^1 F(\mu) \mu d\mu // \mu = \cos(\theta) // Fit from [Kulla and Conty, 2017, "Revisiting Physically Based Shading at // Imageworks"] inline float fresnelDielectricAvg(float eta) { if (eta < 1.f) eta = rcp(eta); return (eta - 1.f) / (4.08567f + 1.00071f * eta); } /*! Computes fresnel coefficient for conductor medium with complex * refraction index (eta,k). The cosine has to be positive. */ inline vec3f fresnelConductor(float cosI, vec3f eta, vec3f k) { const vec3f tmp = sqr(eta) + sqr(k); const vec3f Rpar = (tmp * sqr(cosI) - 2.0f * eta * cosI + make_vec3f(1.f)) * rcp(tmp * sqr(cosI) + 2.0f * eta * cosI + make_vec3f(1.f)); const vec3f Rper = (tmp - 2.0f * eta * cosI + make_vec3f(sqr(cosI))) * rcp(tmp + 2.0f * eta * cosI + make_vec3f(sqr(cosI))); return 0.5f * (Rpar + Rper); } inline float fresnelConductor(float cosI, uniform float eta, uniform float k) { const uniform float tmp = sqr(eta) + sqr(k); const float Rpar = (tmp * sqr(cosI) - eta * (2.0f * cosI) + 1.f) * rcp(tmp * sqr(cosI) + eta * (2.0f * cosI) + 1.f); const float Rper = (tmp - 2.0f * eta * cosI + sqr(cosI)) * rcp(tmp + 2.0f * eta * cosI + sqr(cosI)); return 0.5f * (Rpar + Rper); } inline vec3f fresnelConductor(float cosI, spectrum eta, spectrum k) { vec3f rgb = make_vec3f(0.f); for (uniform int l = 0; l < SPECTRUM_SAMPLES; l++) rgb = rgb + fresnelConductor(cosI, eta[l], k[l]) * spectrum_sRGB(l); return clamp(rgb); } // mainly for abstracting the conductor variants struct Fresnel; typedef vec3f (*Fresnel_EvalFunc)(const Fresnel *uniform self, float cosI); // TODO change into member variable vec3f and implement for *all* Fresnels! typedef vec3f (*Fresnel_EvalAvgFunc)(const Fresnel *uniform self); enum FresnelType { FRESNEL_TYPE_CONDUCTOR_RGB_UNIFORM = 0, // TODO: is rgb varying conductor used? FRESNEL_TYPE_CONDUCTOR_RGB_VARYING = 1, FRESNEL_TYPE_SCHLICK = 2, FRESNEL_TYPE_CONDUCTOR_SPECTRAL = 3, FRESNEL_TYPE_CONDUCTOR_ARTISTIC = 4, FRESNEL_TYPE_UNKNOWN = 5 }; struct Fresnel { uniform FresnelType type; }; inline vec3f Fresnel_evalAvg(const Fresnel *uniform) { return make_vec3f(0.f); } inline void Fresnel_Constructor(Fresnel *uniform self, uniform FresnelType type) { self->type = type; } struct FresnelConductorRGBUniform { uniform Fresnel super; uniform vec3f eta; uniform vec3f k; }; inline vec3f FresnelConductorRGBUniform_eval( const Fresnel *uniform super, float cosI) { const FresnelConductorRGBUniform *uniform self = (const FresnelConductorRGBUniform *uniform)super; return make_vec3f(fresnelConductor(cosI, self->eta.x, self->k.x), fresnelConductor(cosI, self->eta.y, self->k.y), fresnelConductor(cosI, self->eta.z, self->k.z)); } inline Fresnel *uniform FresnelConductorRGBUniform_create( ShadingContext *uniform ctx, const uniform vec3f &eta, const uniform vec3f &k) { FresnelConductorRGBUniform *uniform self = (FresnelConductorRGBUniform * uniform) ShadingContext_alloc(ctx, sizeof(FresnelConductorRGBUniform)); Fresnel_Constructor(&self->super, FRESNEL_TYPE_CONDUCTOR_RGB_UNIFORM); self->eta = eta; self->k = k; return &self->super; } struct FresnelSchlick { uniform Fresnel super; varying vec3f r; // reflectivity at normal incidence (0 deg) varying vec3f g; // reflectivity at grazing angle (90 deg) }; inline vec3f FresnelSchlick_eval(const Fresnel *uniform super, float cosI) { const FresnelSchlick *uniform self = (const FresnelSchlick *uniform)super; const float c = 1.f - cosI; return lerp(sqr(sqr(c)) * c, self->r, self->g); } // Exact solution from [Kulla and Conty, 2017, "Revisiting Physically Based // Shading at Imageworks"] inline vec3f FresnelSchlick_evalAvg(const Fresnel *uniform super) { const FresnelSchlick *uniform self = (const FresnelSchlick *uniform)super; const vec3f r = self->r; const vec3f g = self->g; const float p = 1.f / 5.f; const float p2 = p * p; return (2.f * g * p2 + r + 3.f * p * r) * rcp(1.f + 3.f * p + 2.f * p2); } inline Fresnel *uniform FresnelSchlick_create( ShadingContext *uniform ctx, const varying vec3f &r, const varying vec3f &g) { FresnelSchlick *uniform self = (FresnelSchlick * uniform) ShadingContext_alloc(ctx, sizeof(FresnelSchlick)); Fresnel_Constructor(&self->super, FRESNEL_TYPE_SCHLICK); self->r = r; self->g = g; return &self->super; } struct FresnelConductorSpectral { uniform Fresnel super; uniform spectrum eta; uniform spectrum k; }; inline vec3f FresnelConductorSpectral_eval( const Fresnel *uniform super, float cosI) { const FresnelConductorSpectral *uniform self = (const FresnelConductorSpectral *uniform)super; return fresnelConductor(cosI, self->eta, self->k); } inline Fresnel *uniform FresnelConductorSpectral_create( ShadingContext *uniform ctx, const spectrum &eta, const spectrum &k) { FresnelConductorSpectral *uniform self = (FresnelConductorSpectral * uniform) ShadingContext_alloc(ctx, sizeof(FresnelConductorSpectral)); Fresnel_Constructor(&self->super, FRESNEL_TYPE_CONDUCTOR_SPECTRAL); self->eta = eta; self->k = k; return &self->super; } // [Gulbrandsen, 2014, "Artist Friendly Metallic Fresnel"] struct FresnelConductorArtistic { uniform Fresnel super; varying vec3f eta; varying vec3f k; varying vec3f r; varying vec3f g; }; inline vec3f FresnelConductorArtistic_eval( const Fresnel *uniform super, float cosI) { const FresnelConductorArtistic *uniform self = (const FresnelConductorArtistic *uniform)super; return fresnelConductor(cosI, self->eta, self->k); } // Fit from [Kulla and Conty, 2017, "Revisiting Physically Based Shading at // Imageworks"] inline vec3f FresnelConductorArtistic_evalAvg(const Fresnel *uniform super) { const FresnelConductorArtistic *uniform self = (const FresnelConductorArtistic *uniform)super; const vec3f r = self->r; const vec3f r2 = r * r; const vec3f r3 = r2 * r; const vec3f g = self->g; const vec3f g2 = g * g; const vec3f g3 = g2 * g; return 0.087237f + 0.0230685f * g - 0.0864902f * g2 + 0.0774594f * g3 + 0.782654f * r - 0.136432f * r2 + 0.278708f * r3 + 0.19744f * g * r + 0.0360605f * g2 * r - 0.2586f * g * r2; } inline Fresnel *uniform FresnelConductorArtistic_create( ShadingContext *uniform ctx, const vec3f &reflectivity, const vec3f &edgeTint) { FresnelConductorArtistic *uniform self = (FresnelConductorArtistic * uniform) ShadingContext_alloc(ctx, sizeof(FresnelConductorArtistic)); Fresnel_Constructor(&self->super, FRESNEL_TYPE_CONDUCTOR_ARTISTIC); const vec3f r = min(reflectivity, make_vec3f(0.99f)); const vec3f g = edgeTint; const vec3f n_min = (1.f - r) / (1.f + r); const vec3f n_max = (1.f + sqrt(r)) / (1.f - sqrt(r)); const vec3f n = g * n_min + (1.f - g) * n_max; const vec3f k2 = (sqr(n + 1.f) * r - sqr(n - 1.f)) / (1.f - r); self->eta = n; self->k = sqrt_safe(k2); // prevent NaN if k2==-0.0f (happens if r==0.0f) self->r = r; self->g = g; return &self->super; } inline vec3f Fresnel_dispatch_eval(const Fresnel *uniform self, float cosI) { switch (self->type) { case FRESNEL_TYPE_CONDUCTOR_RGB_UNIFORM: return FresnelConductorRGBUniform_eval(self, cosI); case FRESNEL_TYPE_SCHLICK: return FresnelSchlick_eval(self, cosI); case FRESNEL_TYPE_CONDUCTOR_SPECTRAL: return FresnelConductorSpectral_eval(self, cosI); case FRESNEL_TYPE_CONDUCTOR_ARTISTIC: return FresnelConductorArtistic_eval(self, cosI); default: break; } return make_vec3f(0.f); } inline vec3f Fresnel_dispatch_evalAvg(const Fresnel *uniform self) { switch (self->type) { case FRESNEL_TYPE_SCHLICK: return FresnelSchlick_evalAvg(self); case FRESNEL_TYPE_CONDUCTOR_ARTISTIC: return FresnelConductorArtistic_evalAvg(self); default: break; } // The default Fresnel_evalAvg just returns 0.f return Fresnel_evalAvg(self); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/GGXDistribution.ih000066400000000000000000000123501464752671100254620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MicrofacetDistribution.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // GGX (Trowbridge-Reitz) microfacet distribution // [Walter et al., 2007, "Microfacet Models for Refraction through Rough // Surfaces"] [Heitz, 2014, "Understanding the Masking-Shadowing Function in // Microfacet-Based BRDFs"] [Heitz and d'Eon, 2014, "Importance Sampling // Microfacet-Based BSDFs using the Distribution of Visible Normals"] [Heitz, // 2017, "A Simpler and Exact Sampling Routine for the GGX Distribution of // Visible Normals"] struct GGXDistribution { vec2f alpha; }; inline GGXDistribution make_GGXDistribution(const vec2f &alpha) { GGXDistribution self; self.alpha = alpha; return self; } // D(\omega_m) = \frac{1}{\pi \alpha_x \alpha_y \cos^4\theta_m \left(1 + // \tan^2\theta_m \left(\frac{\cos^2\phi_m}{\alpha_x^2} + // \frac{\sin^2\phi_m}{\alpha_y^2}\right)\right)^2} inline float eval(const GGXDistribution &self, const vec3f &wh) { float cosTheta = wh.z; float cosTheta2 = sqr(cosTheta); float e = (sqr(wh.x / self.alpha.x) + sqr(wh.y / self.alpha.y)) / cosTheta2; return rcp( (float)pi * self.alpha.x * self.alpha.y * sqr(cosTheta2 * (1.f + e))); } // p(\omega_m) = D(\omega_m) \cos\theta_m inline float eval(const GGXDistribution &self, const vec3f &wh, float &pdf) { float cosTheta = wh.z; float D = eval(self, wh); pdf = D * abs(cosTheta); return D; } // \theta_m = \arctan \left( \frac{\alpha\sqrt{\xi_1}}{\sqrt{1-\xi_1}} \right) // \phi_m = 2\pi \xi_2 // p(\omega_m) = D(\omega_m) \cos\theta_m inline vec3f sample(const GGXDistribution &self, float &pdf, const vec2f &s) { float phi; if (self.alpha.x == self.alpha.y) { phi = 2.f * (float)pi * s.y; } else { phi = atan(self.alpha.y / self.alpha.x * tan((float)pi * (2.f * s.y + 0.5f))); if (s.y > 0.5f) phi += (float)pi; } float sinPhi, cosPhi; sincos(phi, &sinPhi, &cosPhi); float alpha2; if (self.alpha.x == self.alpha.y) alpha2 = sqr(self.alpha.x); else alpha2 = rcp(sqr(cosPhi / self.alpha.x) + sqr(sinPhi / self.alpha.y)); float tanTheta2 = alpha2 * s.x / (1.f - s.x); float cosTheta = rsqrt(1.f + tanTheta2); float cosTheta3 = sqr(cosTheta) * cosTheta; float sinTheta = cos2sin(cosTheta); float e = tanTheta2 / alpha2; pdf = rcp((float)pi * self.alpha.x * self.alpha.y * cosTheta3 * sqr(1.f + e)); float x = cosPhi * sinTheta; float y = sinPhi * sinTheta; float z = cosTheta; return make_vec3f(x, y, z); } // Smith Lambda function [Heitz, 2014] // \Lambda(\omega_o) = \frac{-1 + \sqrt{1+\frac{1}{a^2}}}{2} // a = \frac{1}{\alpha_o \tan\theta_o} // \alpha_o = \sqrt{cos^2\phi_o \alpha_x^2 + sin^2\phi_o \alpha_y^2} inline float evalLambda(const GGXDistribution &self, const vec3f &wo) { float cosThetaO = wo.z; float cosThetaO2 = sqr(cosThetaO); float invA2 = (sqr(wo.x * self.alpha.x) + sqr(wo.y * self.alpha.y)) / cosThetaO2; return 0.5f * (-1.f + sqrt(1.f + invA2)); } inline float evalG1( const GGXDistribution &self, const vec3f &wo, float cosThetaOH) { float cosThetaO = wo.z; if (cosThetaO * cosThetaOH <= 0.f) return 0.f; return rcp(1.f + evalLambda(self, wo)); } // Smith's height-correlated masking-shadowing function // [Heitz, 2014, "Understanding the Masking-Shadowing Function in // Microfacet-Based BRDFs"] inline float evalG2(const GGXDistribution &self, const vec3f &wo, const vec3f &wi, float cosThetaOH, float cosThetaIH) { float cosThetaO = wo.z; float cosThetaI = wi.z; if (cosThetaO * cosThetaOH <= 0.f || cosThetaI * cosThetaIH <= 0.f) return 0.f; return rcp(1.f + evalLambda(self, wo) + evalLambda(self, wi)); } inline float evalVisible(const GGXDistribution &self, const vec3f &wh, const vec3f &wo, float cosThetaOH, float &pdf) { float cosThetaO = wo.z; float D = eval(self, wh); pdf = evalG1(self, wo, cosThetaOH) * abs(cosThetaOH) * D / abs(cosThetaO); return D; } // Fast visible normal sampling (wo must be in the upper hemisphere) // [Heitz, 2017, "A Simpler and Exact Sampling Routine for the GGX Distribution // of Visible Normals"] inline vec3f sampleVisible( const GGXDistribution &self, const vec3f &wo, float &pdf, const vec2f &s) { // Stretch wo vec3f V = normalize(make_vec3f(self.alpha.x * wo.x, self.alpha.y * wo.y, wo.z)); // Orthonormal basis vec3f T1 = (V.z < 0.9999f) ? normalize(cross(V, make_vec3f(0, 0, 1))) : make_vec3f(1, 0, 0); vec3f T2 = cross(T1, V); // Sample point with polar coordinates (r, phi) float a = 1.f / (1.f + V.z); float r = sqrt(s.x); float phi = (s.y < a) ? s.y / a * (float)pi : (float)pi + (s.y - a) / (1.f - a) * (float)pi; float sinPhi, cosPhi; sincos(phi, &sinPhi, &cosPhi); float P1 = r * cosPhi; float P2 = r * sinPhi * ((s.y < a) ? 1.f : V.z); // Compute normal vec3f wh = P1 * T1 + P2 * T2 + sqrt(max(0.f, 1.f - P1 * P1 - P2 * P2)) * V; // Unstretch wh = normalize( make_vec3f(self.alpha.x * wh.x, self.alpha.y * wh.y, max(0.f, wh.z))); // Compute pdf float cosThetaO = wo.z; pdf = evalG1(self, wo, dot(wo, wh)) * abs(dot(wo, wh)) * eval(self, wh) / abs(cosThetaO); return wh; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Lambert.ih000066400000000000000000000020631464752671100240230ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "math/sampling.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline BSDF_EvalRes Lambert_eval( const varying BSDF *uniform self, const vec3f &, const vec3f &wi) { BSDF_EvalRes res; float cosThetaI = max(dot(wi, getN(self)), 0.f); res.pdf = cosineSampleHemispherePDF(cosThetaI); res.value = self->albedo * (float)one_over_pi * cosThetaI; return res; } inline BSDF_SampleRes Lambert_sample( const varying BSDF *uniform self, const vec3f &, const vec2f &s, float) { const vec3f localDir = cosineSampleHemisphere(s); BSDF_SampleRes res; res.wi = getFrame(self) * localDir; res.pdf = cosineSampleHemispherePDF(localDir); res.type = BSDF_DIFFUSE_REFLECTION; res.weight = self->albedo; return res; } inline void Lambert_Constructor(varying BSDF *uniform self, const varying linear3f *uniform frame, const varying vec3f &R) { BSDF_Constructor(self, R, BSDF_DIFFUSE_REFLECTION, BSDF_TYPE_LAMBERT, frame); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/LambertTransmission.ih000066400000000000000000000027011464752671100264340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline BSDF_EvalRes LambertTransmission_eval( const varying BSDF *uniform self, const vec3f &, const vec3f &wi) { BSDF_EvalRes res; float cosThetaI = max(-dot(wi, getN(self)), 0.f); res.pdf = cosineSampleHemispherePDF(cosThetaI); res.value = self->albedo * (float)one_over_pi * cosThetaI; return res; } inline BSDF_SampleRes LambertTransmission_sample( const varying BSDF *uniform self, const vec3f &, const vec2f &s, float) { const vec3f localDir = cosineSampleHemisphere(s); BSDF_SampleRes res; res.wi = neg(getFrame(self) * localDir); res.pdf = cosineSampleHemispherePDF(localDir); res.type = BSDF_DIFFUSE_TRANSMISSION; res.weight = self->albedo; return res; } inline void LambertTransmission_Constructor(varying BSDF *uniform self, const varying linear3f *uniform frame, const varying vec3f &R) { BSDF_Constructor(self, R, BSDF_DIFFUSE_TRANSMISSION, BSDF_TYPE_LAMBERT_TRANSMISSION, frame); } inline varying BSDF *uniform LambertTransmission_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, const varying vec3f &R) { varying BSDF *uniform self = (varying BSDF * uniform) ShadingContext_alloc(ctx, sizeof(BSDF)); LambertTransmission_Constructor(self, frame, R); return self; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetAlbedo.ih000066400000000000000000000136251464752671100256260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Fresnel.ih" #include "GGXDistribution.ih" #include "SheenDistribution.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline float MicrofacetAlbedo_sample( float cosThetaO, const GGXDistribution µfacet, const vec2f &s) { // Handle edge cases cosThetaO = max(cosThetaO, 1e-6f); // Make an outgoing vector vec3f wo = make_vec3f(cos2sin(cosThetaO), 0.f, cosThetaO); // Sample the microfacet normal float whPdf; vec3f wh = sampleVisible(microfacet, wo, whPdf, s); float cosThetaOH = dot(wo, wh); // Sample the reflection vec3f wi = reflect(wo, wh, cosThetaOH); float cosThetaI = wi.z; if (cosThetaI <= 0.f) return 0.f; float cosThetaIH = dot(wi, wh); float G = evalG2(microfacet, wo, wi, cosThetaOH, cosThetaIH); return G * rcp_safe(evalG1(microfacet, wo, cosThetaOH)); } inline float MicrofacetDielectricAlbedo_sample(float cosThetaO, float eta, const GGXDistribution µfacet, const vec2f &s) { // Handle edge cases cosThetaO = max(cosThetaO, 1e-6f); // Make an outgoing vector vec3f wo = make_vec3f(cos2sin(cosThetaO), 0.f, cosThetaO); // Sample the microfacet normal float whPdf; vec3f wh = sampleVisible(microfacet, wo, whPdf, s); float cosThetaOH = dot(wo, wh); // Fresnel term float cosThetaTH; // positive float F = fresnelDielectricEx(cosThetaOH, cosThetaTH, eta); float weight = 0.f; // Sample the reflection vec3f wi = reflect(wo, wh, cosThetaOH); float cosThetaI = wi.z; if (cosThetaI > 0.f) { float cosThetaIH = dot(wi, wh); float G = evalG2(microfacet, wo, wi, cosThetaOH, cosThetaIH); weight += F * (G * rcp_safe(evalG1(microfacet, wo, cosThetaOH))); } // Sample the transmission // cosThetaTH = -cosThetaIH wi = refract(wo, wh, cosThetaOH, cosThetaTH, eta); cosThetaI = wi.z; if (cosThetaI < 0.f) { float cosThetaIH = dot(wi, wh); float G = evalG2(microfacet, wo, wi, cosThetaOH, cosThetaIH); weight += (1.f - F) * (G * rcp_safe(evalG1(microfacet, wo, cosThetaOH))); } return weight; } inline float MicrofacetDielectricReflectionAlbedo_sample(float cosThetaO, float eta, const GGXDistribution µfacet, const vec2f &s) { // Handle edge cases cosThetaO = max(cosThetaO, 1e-6f); // Make an outgoing vector vec3f wo = make_vec3f(cos2sin(cosThetaO), 0.f, cosThetaO); // Sample the microfacet normal float whPdf; vec3f wh = sampleVisible(microfacet, wo, whPdf, s); float cosThetaOH = dot(wo, wh); // Fresnel term float F = fresnelDielectric(cosThetaOH, eta); // Sample the reflection vec3f wi = reflect(wo, wh, cosThetaOH); float cosThetaI = wi.z; if (cosThetaI <= 0.f) return 0.f; float cosThetaIH = dot(wi, wh); float G = evalG2(microfacet, wo, wi, cosThetaOH, cosThetaIH); return F * (G * rcp_safe(evalG1(microfacet, wo, cosThetaOH))); } inline float MicrofacetSheenAlbedo_sample( float cosThetaO, const SheenDistribution µfacet, const vec2f &s) { // Handle edge cases cosThetaO = max(cosThetaO, 1e-6f); // Make an outgoing vector vec3f wo = make_vec3f(cos2sin(cosThetaO), 0.f, cosThetaO); // Sample the reflection vec3f wi = uniformSampleHemisphere(s); float cosThetaI = wi.z; // Compute the microfacet normal vec3f wh = normalize(wo + wi); float cosThetaH = wh.z; float cosThetaOH = dot(wo, wh); float cosThetaIH = dot(wi, wh); // Evaluate the reflection float D = eval(microfacet, cosThetaH); float G = evalG2(microfacet, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); float pdf = uniformSampleHemispherePDF(); return D * G * rcp(4.f * cosThetaO * pdf); } inline float MicrofacetAlbedo_integrate( float cosThetaO, float roughness, uniform int numSamples = 1024) { GGXDistribution microfacet = make_GGXDistribution(roughnessToAlpha(roughness, 0.f)); uniform int n = sqrt((uniform float)numSamples); float sum = 0.f; for (uniform int i = 0; i < n; i++) { for (uniform int j = 0; j < n; j++) { vec2f s = min((make_vec2f(i, j) + 0.5f) / n, make_vec2f(1.f - 1e-6f)); sum += MicrofacetAlbedo_sample(cosThetaO, microfacet, s); } } return min(sum / (n * n), 1.f); } inline float MicrofacetDielectricAlbedo_integrate( float cosThetaO, float eta, float roughness, uniform int numSamples = 1024) { GGXDistribution microfacet = make_GGXDistribution(roughnessToAlpha(roughness, 0.f)); uniform int n = sqrt((uniform float)numSamples); float sum = 0.f; for (uniform int i = 0; i < n; i++) { for (uniform int j = 0; j < n; j++) { vec2f s = min((make_vec2f(i, j) + 0.5f) / n, make_vec2f(1.f - 1e-6f)); sum += MicrofacetDielectricAlbedo_sample(cosThetaO, eta, microfacet, s); } } return min(sum / (n * n), 1.f); } inline float MicrofacetDielectricReflectionAlbedo_integrate( float cosThetaO, float eta, float roughness, uniform int numSamples = 1024) { GGXDistribution microfacet = make_GGXDistribution(roughnessToAlpha(roughness, 0.f)); uniform int n = sqrt((uniform float)numSamples); float sum = 0.f; for (uniform int i = 0; i < n; i++) { for (uniform int j = 0; j < n; j++) { vec2f s = min((make_vec2f(i, j) + 0.5f) / n, make_vec2f(1.f - 1e-6f)); sum += MicrofacetDielectricReflectionAlbedo_sample( cosThetaO, eta, microfacet, s); } } return min(sum / (n * n), 1.f); } inline float MicrofacetSheenAlbedo_integrate( float cosThetaO, float roughness, uniform int numSamples = 1024) { SheenDistribution microfacet = make_SheenDistribution(roughnessToAlpha(roughness)); uniform int n = sqrt((uniform float)numSamples); float sum = 0.f; for (uniform int i = 0; i < n; i++) { for (uniform int j = 0; j < n; j++) { vec2f s = min((make_vec2f(i, j) + 0.5f) / n, make_vec2f(1.f - 1e-6f)); sum += MicrofacetSheenAlbedo_sample(cosThetaO, microfacet, s); } } return min(sum / (n * n), 1.f); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetAlbedoTables.cpp000066400000000000000000000061171464752671100271410ustar00rootroot00000000000000#include "MicrofacetAlbedoTables.h" #include "render/bsdfs/MicrofacetAlbedoTablesShared.h" #ifndef OSPRAY_TARGET_SYCL #include "render/bsdfs/MicrofacetAlbedoTables_ispc.h" #else namespace ispc { void precomputeMicrofacetAlbedoTables(void *_tables); } #endif namespace ospray { MicrofacetAlbedoTables::MicrofacetAlbedoTables(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice()) { albedo_dir = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_ALBEDO_TABLE_SIZE * MICROFACET_ALBEDO_TABLE_SIZE); albedo_avg = devicert::make_buffer_shared_unique( device.getDRTDevice(), MICROFACET_ALBEDO_TABLE_SIZE); dielectricAlbedo_dir = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE); dielectricAlbedo_avg = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE); dielectricRcpEtaAlbedo_dir = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE); dielectricRcpEtaAlbedo_avg = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE); dielectricReflectionAlbedo_dir = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE); dielectricReflectionAlbedo_avg = devicert::make_buffer_shared_unique(device.getDRTDevice(), MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE * MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE); sheenAlbedo_dir = devicert::make_buffer_shared_unique( device.getDRTDevice(), MICROFACET_SHEEN_ALBEDO_TABLE_SIZE * MICROFACET_SHEEN_ALBEDO_TABLE_SIZE); getSh()->albedo_dir = albedo_dir->data(); getSh()->albedo_avg = albedo_avg->data(); getSh()->dielectricAlbedo_dir = dielectricAlbedo_dir->data(); getSh()->dielectricAlbedo_avg = dielectricAlbedo_avg->data(); getSh()->dielectricRcpEtaAlbedo_dir = dielectricRcpEtaAlbedo_dir->data(); getSh()->dielectricRcpEtaAlbedo_avg = dielectricRcpEtaAlbedo_avg->data(); getSh()->dielectricReflectionAlbedo_dir = dielectricReflectionAlbedo_dir->data(); getSh()->dielectricReflectionAlbedo_avg = dielectricReflectionAlbedo_avg->data(); getSh()->sheenAlbedo_dir = sheenAlbedo_dir->data(); // TODO: Could be a kernel dispatch for SYCL, right now it's run serially on // the host ispc::precomputeMicrofacetAlbedoTables(getSh()); } std::string MicrofacetAlbedoTables::toString() const { return "ospray::MicrofacetAlbedoTables"; } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetAlbedoTables.h000066400000000000000000000036241464752671100266060ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "ISPCDevice.h" #include "common/Managed.h" #include "common/StructShared.h" // ispc shared #include "MicrofacetAlbedoTablesShared.h" namespace ospray { /* Directional and average albedo tables for microfacet BSDFs * [Kulla and Conty, 2017, "Revisiting Physically Based Shading at * Imageworks"] * * These are stored in USM to reduce the kernel size and avoid issues about * global statics/initialization in SYCL where these are populated by a kernel, * not compile-time defined values */ struct OSPRAY_SDK_INTERFACE MicrofacetAlbedoTables : public AddStructShared { MicrofacetAlbedoTables(api::ISPCDevice &device); virtual std::string toString() const override; private: // Microfacet GGX albedo tables // directional 2D table (cosThetaO, roughness) BufferSharedUq albedo_dir; // average 1D table (roughness) BufferSharedUq albedo_avg; // Microfacet GGX dielectric albedo table. eta in [1/3, 1] // directional 3D table (cosThetaO, eta, roughness) BufferSharedUq dielectricAlbedo_dir; // average 2D table (eta, roughness) BufferSharedUq dielectricAlbedo_avg; // eta in [1, 3] // directional 3D table (cosThetaO, eta, roughness) BufferSharedUq dielectricRcpEtaAlbedo_dir; // average 2D table (eta, roughness) BufferSharedUq dielectricRcpEtaAlbedo_avg; // Microfacet GGX dielectric reflection-only albedo table. eta in [1/3, 1] // directional 3D table (cosThetaO, eta, roughness) BufferSharedUq dielectricReflectionAlbedo_dir; // average 2D table (eta, roughness) BufferSharedUq dielectricReflectionAlbedo_avg; // Microfacet sheen albedo table // directional 2D table (cosThetaO, roughness) BufferSharedUq sheenAlbedo_dir; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetAlbedoTables.ih000066400000000000000000000125701464752671100267570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MicrofacetAlbedoTablesShared.h" #include "math/interpolation.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline float MicrofacetAlbedoTable_eval( const MicrofacetAlbedoTables *uniform albedoTable, float cosThetaO, float roughness) { const uniform int size = MICROFACET_ALBEDO_TABLE_SIZE; const vec2f p = make_vec2f(cosThetaO, roughness) * (size - 1); return interp2DLinear(p, albedoTable->albedo_dir, make_vec2i(size)); } inline float MicrofacetAlbedoTable_evalAvg( const MicrofacetAlbedoTables *uniform albedoTable, float roughness) { const uniform int size = MICROFACET_ALBEDO_TABLE_SIZE; const float x = roughness * (size - 1); return interp1DLinear(x, albedoTable->albedo_avg, size); } inline float MicrofacetDielectricAlbedoTable_eval( const MicrofacetAlbedoTables *uniform albedoTable, float cosThetaO, float eta, float roughness) { const uniform int size = MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE; if (eta <= 1.f) { const uniform float minEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR); const uniform float maxEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR); const float etaParam = (eta - minEta) / (maxEta - minEta); const vec3f p = make_vec3f(cosThetaO, etaParam, roughness) * (size - 1); return interp3DLinear( p, albedoTable->dielectricAlbedo_dir, make_vec3i(size)); } else { const uniform float minEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR; const uniform float maxEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR; const float etaParam = (eta - minEta) / (maxEta - minEta); const vec3f p = make_vec3f(cosThetaO, etaParam, roughness) * (size - 1); return interp3DLinear( p, albedoTable->dielectricRcpEtaAlbedo_dir, make_vec3i(size)); } } inline float MicrofacetDielectricAlbedoTable_evalAvg( const MicrofacetAlbedoTables *uniform albedoTable, float eta, float roughness) { const uniform int size = MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE; if (eta <= 1.f) { const uniform float minEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR); const uniform float maxEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR); const float etaParam = (eta - minEta) / (maxEta - minEta); const vec2f p = make_vec2f(etaParam, roughness) * (size - 1); return interp2DLinear( p, albedoTable->dielectricAlbedo_avg, make_vec2i(size)); } else { const uniform float minEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR; const uniform float maxEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR; const float etaParam = (eta - minEta) / (maxEta - minEta); const vec2f p = make_vec2f(etaParam, roughness) * (size - 1); return interp2DLinear( p, albedoTable->dielectricRcpEtaAlbedo_avg, make_vec2i(size)); } } inline float MicrofacetDielectricReflectionAlbedoTable_eval( const MicrofacetAlbedoTables *uniform albedoTable, float cosThetaO, float eta, float roughness) { const uniform int size = MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE; // if (eta <= 1.f) { const uniform float minEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR); const uniform float maxEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR); const float etaParam = (eta - minEta) / (maxEta - minEta); const vec3f p = make_vec3f(cosThetaO, etaParam, roughness) * (size - 1); return interp3DLinear( p, albedoTable->dielectricReflectionAlbedo_dir, make_vec3i(size)); } /* else { const uniform float minEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR; const uniform float maxEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR; const float etaParam = (eta - minEta) / (maxEta - minEta); const vec3f p = make_vec3f(cosThetaO, etaParam, roughness) * (size-1); return interp3DLinear(p, MicrofacetDielectricReflectionRcpEtaAlbedoTable_dir, make_vec3i(size)); } */ } inline float MicrofacetDielectricReflectionAlbedoTable_evalAvg( const MicrofacetAlbedoTables *uniform albedoTable, float eta, float roughness) { const uniform int size = MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE; // if (eta <= 1.f) { const uniform float minEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR); const uniform float maxEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR); const float etaParam = (eta - minEta) / (maxEta - minEta); const vec2f p = make_vec2f(etaParam, roughness) * (size - 1); return interp2DLinear( p, albedoTable->dielectricReflectionAlbedo_avg, make_vec2i(size)); } /* else { const uniform float minEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR; const uniform float maxEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR; const float etaParam = (eta - minEta) / (maxEta - minEta); const vec2f p = make_vec2f(etaParam, roughness) * (size-1); return interp2DLinear(p, MicrofacetDielectricReflectionRcpEtaAlbedoTable_avg, make_vec2i(size)); } */ } inline float MicrofacetSheenAlbedoTable_eval( const MicrofacetAlbedoTables *uniform albedoTable, float cosThetaO, float roughness) { const uniform int size = MICROFACET_SHEEN_ALBEDO_TABLE_SIZE; const vec2f p = make_vec2f(cosThetaO, roughness) * (size - 1); return interp2DLinear(p, albedoTable->sheenAlbedo_dir, make_vec2i(size)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetAlbedoTables.ispc000066400000000000000000000120551464752671100273130ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "MicrofacetAlbedo.ih" #include "MicrofacetAlbedoTables.ih" #include "MicrofacetAlbedoTablesShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE static inline uniform float MicrofacetAlbedoTable_integrateAvg( const uniform float *uniform f, uniform int size, uniform int numSamples = 1024) { // Trapezoidal rule const uniform int n = numSamples + 1; float sum = 0.f; #ifdef OSPRAY_TARGET_SYCL for (int i = 0; i < n; ++i) { #else foreach (i = 0 ... n) { #endif const float cosThetaO = (float)i / (n - 1); const float x = cosThetaO * (size - 1); sum += interp1DLinear(x, f, size) * cosThetaO * ((i == 0 || i == n - 1) ? 0.5f : 1.f); } uniform float totalSum = reduce_add(sum); return min(2.f * (totalSum / (n - 1)), 1.f); } static void MicrofacetAlbedoTable_precompute( MicrofacetAlbedoTables *uniform tables) { const uniform int size = MICROFACET_ALBEDO_TABLE_SIZE; uniform float *uniform dirPtr = tables->albedo_dir; uniform float *uniform avgPtr = tables->albedo_avg; for (uniform int j = 0; j < size; j++) { const float roughness = (float)j / (size - 1); // compute the direction albedo for each cosThetaO #ifdef OSPRAY_TARGET_SYCL for (int i = 0; i < size; ++i) { #else foreach (i = 0 ... size) { #endif const float cosThetaO = (float)i / (size - 1); dirPtr[i] = MicrofacetAlbedo_integrate(cosThetaO, roughness); } // compute the average albedo *avgPtr = MicrofacetAlbedoTable_integrateAvg(dirPtr, size); dirPtr += size; avgPtr++; } } typedef float (*MicrofacetDielectricAlbedo_IntegrateFunc)( float cosThetaO, float eta, float roughness, uniform int numSamples); static void MicrofacetDielectricAlbedoTable_precompute( MicrofacetDielectricAlbedo_IntegrateFunc func, uniform int size, uniform float minEta, uniform float maxEta, uniform float *uniform dirValues, uniform float *uniform avgValues) { const uniform int numSamples = 1024; uniform float *uniform dirPtr = dirValues; uniform float *uniform avgPtr = avgValues; for (uniform int k = 0; k < size; k++) { const float roughness = (float)k / (size - 1); for (uniform int j = 0; j < size; j++) { const float eta = lerp((float)j / (size - 1), minEta, maxEta); // compute the direction albedo for each cosThetaO #ifdef OSPRAY_TARGET_SYCL for (int i = 0; i < size; ++i) { #else foreach (i = 0 ... size) { #endif const float cosThetaO = (float)i / (size - 1); dirPtr[i] = func(cosThetaO, eta, roughness, numSamples); } // compute the average albedo *avgPtr = MicrofacetAlbedoTable_integrateAvg(dirPtr, size); dirPtr += size; avgPtr++; } } } static void MicrofacetDielectricAlbedoTable_precompute( MicrofacetAlbedoTables *uniform tables) { const uniform int size = MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE; const uniform float minEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR); const uniform float maxEta = rcp(MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR); MicrofacetDielectricAlbedoTable_precompute( &MicrofacetDielectricAlbedo_integrate, size, minEta, maxEta, tables->dielectricAlbedo_dir, tables->dielectricAlbedo_avg); MicrofacetDielectricAlbedoTable_precompute( &MicrofacetDielectricReflectionAlbedo_integrate, size, minEta, maxEta, tables->dielectricReflectionAlbedo_dir, tables->dielectricReflectionAlbedo_avg); } static void MicrofacetDielectricRcpEtaAlbedoTable_precompute( MicrofacetAlbedoTables *uniform tables) { const uniform int size = MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE; const uniform float minEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR; const uniform float maxEta = MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR; MicrofacetDielectricAlbedoTable_precompute( &MicrofacetDielectricAlbedo_integrate, size, minEta, maxEta, tables->dielectricRcpEtaAlbedo_dir, tables->dielectricRcpEtaAlbedo_avg); } static void MicrofacetSheenAlbedoTable_precompute( MicrofacetAlbedoTables *uniform tables) { const uniform int size = MICROFACET_SHEEN_ALBEDO_TABLE_SIZE; uniform float *uniform dirPtr = tables->sheenAlbedo_dir; for (uniform int j = 0; j < size; j++) { const float roughness = (float)j / (size - 1); // compute the direction albedo for each cosThetaO #ifdef OSPRAY_TARGET_SYCL for (int i = 0; i < size; ++i) { #else foreach (i = 0 ... size) { #endif const float cosThetaO = (float)i / (size - 1); dirPtr[i] = MicrofacetSheenAlbedo_integrate(cosThetaO, roughness); } dirPtr += size; } } export void precomputeMicrofacetAlbedoTables(void *uniform _tables) { MicrofacetAlbedoTables *uniform tables = (MicrofacetAlbedoTables * uniform) _tables; MicrofacetAlbedoTable_precompute(tables); MicrofacetDielectricAlbedoTable_precompute(tables); MicrofacetDielectricRcpEtaAlbedoTable_precompute(tables); MicrofacetSheenAlbedoTable_precompute(tables); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetAlbedoTablesShared.h000066400000000000000000000034411464752671100277320ustar00rootroot00000000000000// Copyright 2009-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define MICROFACET_ALBEDO_TABLE_SIZE 32 #define MICROFACET_DIELECTRIC_ALBEDO_TABLE_SIZE 16 #define MICROFACET_DIELECTRIC_ALBEDO_TABLE_MIN_IOR 1.f #define MICROFACET_DIELECTRIC_ALBEDO_TABLE_MAX_IOR 3.f #define MICROFACET_SHEEN_ALBEDO_TABLE_SIZE 16 #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct MicrofacetAlbedoTables { // Microfacet GGX albedo tables // directional 2D table (cosThetaO, roughness) float *albedo_dir; // average 1D table (roughness) float *albedo_avg; // Microfacet GGX dielectric albedo table. eta in [1/3, 1] // directional 3D table (cosThetaO, eta, roughness) float *dielectricAlbedo_dir; // average 2D table (eta, roughness) float *dielectricAlbedo_avg; // eta in [1, 3] // directional 3D table (cosThetaO, eta, roughness) float *dielectricRcpEtaAlbedo_dir; // average 2D table (eta, roughness) float *dielectricRcpEtaAlbedo_avg; // Microfacet GGX dielectric reflection-only albedo table. eta in [1/3, 1] // directional 3D table (cosThetaO, eta, roughness) float *dielectricReflectionAlbedo_dir; // average 2D table (eta, roughness) float *dielectricReflectionAlbedo_avg; // Microfacet sheen albedo table // directional 2D table (cosThetaO, roughness) float *sheenAlbedo_dir; #ifdef __cplusplus MicrofacetAlbedoTables() : albedo_dir(nullptr), albedo_avg(nullptr), dielectricAlbedo_dir(nullptr), dielectricAlbedo_avg(nullptr), dielectricRcpEtaAlbedo_dir(nullptr), dielectricRcpEtaAlbedo_avg(nullptr), dielectricReflectionAlbedo_dir(nullptr), dielectricReflectionAlbedo_avg(nullptr), sheenAlbedo_dir(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetConductor.ih000066400000000000000000000120121464752671100263650ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "Fresnel.ih" #include "GGXDistribution.ih" #include "MicrofacetAlbedoTables.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Microfacet conductor BRDF with the Smith microsurface model and approximate // multiple scattering. [Kulla and Conty, 2017, "Revisiting Physically Based // Shading at Imageworks"] [Jakob et al., 2014, "A Comprehensive Framework for // Rendering Layered Materials", Extended Technical Report] struct MicrofacetConductor { BSDF super; Fresnel *uniform fresnel; GGXDistribution microfacet; float roughness; const MicrofacetAlbedoTables *uniform microfacetAlbedoTables; // Energy compensation [Kulla and Conty, 2017] float Eavg; vec3f fmsScale; }; inline BSDF_EvalRes MicrofacetConductor_eval( const varying MicrofacetConductor *uniform self, const vec3f &wo, const vec3f &wi) { BSDF_EvalRes res; float cosThetaO = dot(wo, getN(&self->super)); float cosThetaI = dot(wi, getN(&self->super)); if (cosThetaO <= 0.f || cosThetaI <= 0.f) return make_BSDF_EvalRes_zero(); // Compute the microfacet normal vec3f wh = normalize(wi + wo); float cosThetaOH = dot(wo, wh); float cosThetaIH = dot(wi, wh); linear3f toLocal = transposed(getFrame(&self->super)); vec3f wo0 = toLocal * wo; vec3f wi0 = toLocal * wi; vec3f wh0 = toLocal * wh; vec3f F = Fresnel_dispatch_eval(self->fresnel, cosThetaOH); float whPdf; float D = evalVisible(self->microfacet, wh0, wo0, cosThetaOH, whPdf); float G = evalG2(self->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); // Energy compensation float Eo = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->roughness); float Ei = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaI, self->roughness); vec3f fms = self->fmsScale * ((1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->Eavg)) * cosThetaI); res.pdf = whPdf * rcp(4.f * abs(cosThetaOH)); res.value = F * (D * G * rcp(4.f * cosThetaO)) + fms; return res; } inline BSDF_SampleRes MicrofacetConductor_sample( const varying MicrofacetConductor *uniform self, const vec3f &wo, const vec2f &s, float) { BSDF_SampleRes res; float cosThetaO = dot(wo, getN(&self->super)); if (cosThetaO <= 0.f) return make_BSDF_SampleRes_zero(); linear3f toGlobal = getFrame(&self->super); linear3f toLocal = transposed(getFrame(&self->super)); vec3f wo0 = toLocal * wo; // Sample the microfacet normal float whPdf; vec3f wh = toGlobal * sampleVisible(self->microfacet, wo0, whPdf, s); res.wi = reflect(wo, wh); float cosThetaI = dot(res.wi, getN(&self->super)); if (cosThetaI <= 0.f) return make_BSDF_SampleRes_zero(); float cosThetaOH = dot(wo, wh); float cosThetaIH = dot(res.wi, wh); vec3f wi0 = toLocal * res.wi; vec3f F = Fresnel_dispatch_eval(self->fresnel, cosThetaOH); float G = evalG2(self->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); // Energy compensation float Eo = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->roughness); float Ei = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaI, self->roughness); vec3f fms = self->fmsScale * ((1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->Eavg)) * cosThetaI); res.type = BSDF_GLOSSY_REFLECTION; res.pdf = whPdf * rcp(4.f * abs(cosThetaOH)); res.weight = F * (G * rcp_safe(evalG1(self->microfacet, wo0, cosThetaOH))) + (fms * rcp(res.pdf)); return res; } inline void MicrofacetConductor_Constructor( varying MicrofacetConductor *uniform self, MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, Fresnel *uniform fresnel, float roughness, float anisotropy) { // Energy compensation self->Eavg = MicrofacetAlbedoTable_evalAvg(microfacetAlbedoTables, roughness); vec3f Favg = Fresnel_dispatch_evalAvg(fresnel); self->fmsScale = sqr(Favg) * self->Eavg / (1.f - Favg * (1.f - self->Eavg)); // Stephen Hill's tweak BSDF_Constructor(&self->super, Favg * self->Eavg, // TODO better estimate BSDF_GLOSSY_REFLECTION, BSDF_TYPE_MICROFACET_CONDUCTOR, frame); self->fresnel = fresnel; self->microfacet = make_GGXDistribution(roughnessToAlpha(roughness, anisotropy)); self->roughness = roughness; self->microfacetAlbedoTables = microfacetAlbedoTables; } inline varying BSDF *uniform MicrofacetConductor_create( uniform ShadingContext *uniform ctx, MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, Fresnel *uniform fresnel, float roughness, float anisotropy) { varying MicrofacetConductor *uniform self = (varying MicrofacetConductor * uniform) ShadingContext_alloc(ctx, sizeof(MicrofacetConductor)); MicrofacetConductor_Constructor( self, microfacetAlbedoTables, frame, fresnel, roughness, anisotropy); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetDielectric.ih000066400000000000000000000225661464752671100265130ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "Fresnel.ih" #include "GGXDistribution.ih" #include "MicrofacetAlbedoTables.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Microfacet dielectric BSDF with the Smith microsurface model and approximate // multiple scattering. [Walter et al., 2007, "Microfacet Models for Refraction // through Rough Surfaces"] [Kulla and Conty, 2017, "Revisiting Physically Based // Shading at Imageworks"] [Jakob et al., 2014, "A Comprehensive Framework for // Rendering Layered Materials", Extended Technical Report] // FIXME: improve robustness struct MicrofacetDielectric { BSDF super; float eta; // etaO / etaI GGXDistribution microfacet; float roughness; const MicrofacetAlbedoTables *uniform microfacetAlbedoTables; // Energy compensation [Kulla and Conty, 2017] float EavgEta, EavgRcpEta; float FavgEta, FavgRcpEta; float fmsRatio; }; // Single-scattering lobe inline BSDF_EvalRes MicrofacetDielectric_evalSingle( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying MicrofacetDielectric *uniform self = (const varying MicrofacetDielectric *uniform)super; BSDF_EvalRes res; float cosThetaO = dot(wo, getN(super)); if (cosThetaO <= 0.f) return make_BSDF_EvalRes_zero(); float cosThetaI = dot(wi, getN(super)); bool isReflection = cosThetaI > 0.f; // Compute the microfacet normal vec3f wh; if (isReflection) { // Reflection wh = wo + wi; } else { // Transmission wh = self->eta * wo + wi; } wh = normalize(wh); float cosThetaH = dot(wh, getN(super)); // Ensure that the micronormal is in the same hemisphere as the macronormal if (cosThetaH < 0.f) wh = neg(wh); float cosThetaOH = dot(wo, wh); float cosThetaIH = dot(wi, wh); // Fresnel term float F = fresnelDielectric(cosThetaOH, self->eta); float value; if (isReflection) { // Reflection res.pdf = F * rcp(4.f * abs(cosThetaOH)); value = F * rcp(4.f * cosThetaO); } else { // Transmission res.pdf = (1.f - F) * rcp(sqr(self->eta)) * abs(cosThetaIH) * rcp(sqr(cosThetaOH + rcp(self->eta) * cosThetaIH)); value = res.pdf * abs(cosThetaOH) * rcp(cosThetaO); // ignore solid angle compression } linear3f toLocal = transposed(getFrame(super)); vec3f wo0 = toLocal * wo; vec3f wi0 = toLocal * wi; vec3f wh0 = toLocal * wh; float whPdf; float D = evalVisible(self->microfacet, wh0, wo0, cosThetaOH, whPdf); float G = evalG2(self->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); res.pdf *= whPdf; res.value = make_vec3f(value * D * G); return res; } inline BSDF_EvalRes MicrofacetDielectric_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying MicrofacetDielectric *uniform self = (const varying MicrofacetDielectric *uniform)super; BSDF_EvalRes res; float cosThetaO = dot(wo, getN(super)); if (cosThetaO <= 0.f) return make_BSDF_EvalRes_zero(); float cosThetaI = dot(wi, getN(super)); bool isReflection = cosThetaI > 0.f; // Evaluate the energy compensation lobe [Kulla and Conty, 2017] float Eo = MicrofacetDielectricAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->eta, self->roughness); BSDF_EvalRes fms; if (isReflection) { // Reflection float Ei = MicrofacetDielectricAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaI, self->eta, self->roughness); fms.pdf = self->fmsRatio * cosineSampleHemispherePDF(cosThetaI); fms.value = make_vec3f(self->fmsRatio * (1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->EavgEta)) * cosThetaI); } else { // Transmission float Ei = MicrofacetDielectricAlbedoTable_eval(self->microfacetAlbedoTables, abs(cosThetaI), rcp(self->eta), self->roughness); fms.pdf = (1.f - self->fmsRatio) * cosineSampleHemispherePDF(abs(cosThetaI)); fms.value = make_vec3f((1.f - self->fmsRatio) * (1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->EavgRcpEta)) * abs(cosThetaI)); } // Evaluate the single-scattering lobe BSDF_EvalRes single = MicrofacetDielectric_evalSingle(super, wo, wi); // Compute the final result float singlePickProb = Eo; res.pdf = singlePickProb * single.pdf + (1.f - singlePickProb) * fms.pdf; res.value = single.value + fms.value; return res; } inline BSDF_SampleRes MicrofacetDielectric_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying MicrofacetDielectric *uniform self = (const varying MicrofacetDielectric *uniform)super; BSDF_SampleRes res; float cosThetaO = dot(wo, getN(super)); if (cosThetaO <= 0.f) return make_BSDF_SampleRes_zero(); // Energy compensation float Eo = MicrofacetDielectricAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->eta, self->roughness); float singlePickProb = Eo; bool doReflection; bool doSingle = (ss <= singlePickProb); if (doSingle) { // Sample the single-scattering lobe linear3f toGlobal = getFrame(super); linear3f toLocal = transposed(getFrame(super)); vec3f wo0 = toLocal * wo; // Sample the microfacet normal float whPdf; vec3f wh = toGlobal * sampleVisible(self->microfacet, wo0, whPdf, s); float cosThetaOH = dot(wo, wh); // Fresnel term float cosThetaTH; // positive float F = fresnelDielectricEx(cosThetaOH, cosThetaTH, self->eta); // Sample the reflection or the transmission float ss1 = ss * rcp(singlePickProb); doReflection = (ss1 <= F); if (doReflection) { // Reflection res.type = BSDF_GLOSSY_REFLECTION; res.wi = reflect(wo, wh, cosThetaOH); } else { // Transmission res.type = BSDF_GLOSSY_TRANSMISSION; res.wi = refract(wo, wh, cosThetaOH, cosThetaTH, self->eta); } } else { // Sample the energy compensation lobe float ss1 = (ss - singlePickProb) * rcp(1.f - singlePickProb); doReflection = (ss1 <= self->fmsRatio); res.wi = getFrame(super) * cosineSampleHemisphere(s); if (doReflection) { // Reflection res.type = BSDF_DIFFUSE_REFLECTION; } else { // Transmission res.type = BSDF_DIFFUSE_TRANSMISSION; res.wi = neg(res.wi); } } float cosThetaI = dot(res.wi, getN(super)); if ((doReflection && cosThetaI <= 0.f) || (!doReflection && cosThetaI >= 0.f)) return make_BSDF_SampleRes_zero(); // Evaluate the energy compensation lobe BSDF_EvalRes fms; if (doReflection) { // Reflection float Ei = MicrofacetDielectricAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaI, self->eta, self->roughness); fms.pdf = self->fmsRatio * cosineSampleHemispherePDF(cosThetaI); fms.value = make_vec3f(self->fmsRatio * (1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->EavgEta)) * cosThetaI); } else { // Transmission float Ei = MicrofacetDielectricAlbedoTable_eval(self->microfacetAlbedoTables, abs(cosThetaI), rcp(self->eta), self->roughness); fms.pdf = (1.f - self->fmsRatio) * cosineSampleHemispherePDF(abs(cosThetaI)); fms.value = make_vec3f((1.f - self->fmsRatio) * (1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->EavgRcpEta)) * abs(cosThetaI)); } // Evaluate the single-scattering lobe BSDF_EvalRes single = MicrofacetDielectric_evalSingle(super, wo, res.wi); // Compute the final result res.pdf = singlePickProb * single.pdf + (1.f - singlePickProb) * fms.pdf; res.weight = (single.value + fms.value) * rcp(res.pdf); return res; } inline void MicrofacetDielectric_Constructor( varying MicrofacetDielectric *uniform self, MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, float eta, float roughness, float anisotropy) { BSDF_Constructor(&self->super, make_vec3f(0.9f), // TODO better estimate BSDF_GLOSSY | BSDF_DIFFUSE, BSDF_TYPE_MICROFACET_DIELECTRIC, frame); self->eta = eta; self->microfacet = make_GGXDistribution(roughnessToAlpha(roughness, anisotropy)); self->roughness = roughness; self->microfacetAlbedoTables = microfacetAlbedoTables; // Energy compensation self->EavgEta = MicrofacetDielectricAlbedoTable_evalAvg( microfacetAlbedoTables, eta, roughness); self->EavgRcpEta = MicrofacetDielectricAlbedoTable_evalAvg( microfacetAlbedoTables, rcp(eta), roughness); self->FavgEta = fresnelDielectricAvg(eta); self->FavgRcpEta = fresnelDielectricAvg(rcp(eta)); float a = (1.f - self->FavgEta) * rcp(1.f - self->EavgRcpEta); float b = (1.f - self->FavgRcpEta) * rcp(1.f - self->EavgEta) /* * sqr(eta)*/; // ignore solid angle compression float x = b * rcp(a + b); self->fmsRatio = (1.f - x * (1.f - self->FavgEta)); } inline varying BSDF *uniform MicrofacetDielectric_create( uniform ShadingContext *uniform ctx, MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, float eta, float roughness, float anisotropy) { varying MicrofacetDielectric *uniform self = (varying MicrofacetDielectric * uniform) ShadingContext_alloc(ctx, sizeof(MicrofacetDielectric)); MicrofacetDielectric_Constructor( self, microfacetAlbedoTables, frame, eta, roughness, anisotropy); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetDielectricLayer.ih000066400000000000000000000547521464752671100275120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MicrofacetAlbedoTables.ih" #include "MicrofacetDielectric.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Simplified, energy conserving Weidlich-Wilkie microfacet coating BSDF with // the Smith microsurface model. Refraction is ignored, but absorption is // computed from the refracted ray lengths. // [Weidlich and Wilkie, 2007, "Arbitrarily Layered Micro-Facet Surfaces"] // [Walter et al., 2007, "Microfacet Models for Refraction through Rough // Surfaces"] [Kulla and Conty, 2017, "Revisiting Physically Based Shading at // Imageworks"] [Kelemen and Szirmay-Kalos, 2001, "A Microfacet Based Coupled // Specular-Matte BRDF Model with Importance Sampling"] [Jakob et al., 2014, "A // Comprehensive Framework for Rendering Layered Materials", Extended Technical // Report] struct MicrofacetDielectricLayer { BSDF super; float weight; float eta; vec3f transmittance; float thickness; GGXDistribution microfacet; float roughness; const MicrofacetAlbedoTables *uniform microfacetAlbedoTables; // Energy conservation/compensation [Kulla and Conty, 2017] float Ravg; float Eavg; float fmsScale; }; inline void MicrofacetDielectricLayer_Constructor( varying MicrofacetDielectricLayer *uniform self, MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, varying BSDF *varying substrate, float eta, vec3f transmittance, float thickness, float roughness, float anisotropy, float weight) { // Energy conservation/compensation self->Eavg = MicrofacetAlbedoTable_evalAvg(microfacetAlbedoTables, roughness); float Favg = fresnelDielectricAvg(eta); self->fmsScale = Favg * (1.f - self->Eavg) * rcp(1.f - Favg * self->Eavg); self->Ravg = (MicrofacetDielectricReflectionAlbedoTable_evalAvg( microfacetAlbedoTables, self->eta, roughness) + self->fmsScale * (1.f - self->Eavg)) * weight; // add missing energy // XXX check const vec3f albedo = substrate->albedo * ((1.0f - weight) + pow(transmittance, thickness) * (1.f - Favg)); BSDF_Constructor(&self->super, albedo, BSDF_GLOSSY_REFLECTION | substrate->scatteringType, BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER, frame); self->eta = (eta <= 1.f) ? eta : rcp(eta); self->transmittance = transmittance; self->thickness = thickness; self->microfacet = make_GGXDistribution(roughnessToAlpha(roughness, anisotropy)); self->roughness = roughness; self->microfacetAlbedoTables = microfacetAlbedoTables; self->weight = weight; } inline varying BSDF *uniform MicrofacetDielectricLayer_create( uniform ShadingContext *uniform ctx, MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, varying BSDF *varying substrate, float eta, vec3f transmittance, float thickness, float roughness, float anisotropy, float weight) { varying MicrofacetDielectricLayer *uniform self = (varying MicrofacetDielectricLayer * uniform) ShadingContext_alloc(ctx, sizeof(MicrofacetDielectricLayer)); MicrofacetDielectricLayer_Constructor(self, microfacetAlbedoTables, frame, substrate, eta, transmittance, thickness, roughness, anisotropy, weight); return &self->super; } // Helper function for transparent shadow rays inline vec3f MicrofacetDielectricLayer_getTransparency( MicrofacetAlbedoTables *uniform microfacetAlbedoTables, float cosThetaO, float eta, vec3f transmittance, float thickness, float roughness, float, float weight) { if (eta > 1.f) eta = rcp(eta); // Apply the coating medium absorption // Use refracted angles for computing the absorption path length float lengthO1 = rcp(refract(cosThetaO, eta)); // rcp(cosThetaO1) vec3f value = lerp(weight, make_vec3f(1.f), pow(transmittance, thickness * lengthO1)); // Energy conservation float Eavg = MicrofacetAlbedoTable_evalAvg(microfacetAlbedoTables, roughness); float Favg = fresnelDielectricAvg(eta); float fmsScale = Favg * (1.f - Eavg) * rcp(1.f - Favg * Eavg); float Eo = MicrofacetAlbedoTable_eval(microfacetAlbedoTables, cosThetaO, roughness); float Ro = (MicrofacetDielectricReflectionAlbedoTable_eval( microfacetAlbedoTables, cosThetaO, eta, roughness) + fmsScale * (1.f - Eo)) * weight; // add missing energy float T = 1.f - Ro; // for generic (non-diffuse) substrates [Kulla and Conty, 2017] value = value * T; return value; } OSPRAY_END_ISPC_NAMESPACE // Eval macros #define MICROFACETDIELECTRICLAYER_EVAL( \ mdl_name, scatteringType, substrate_bsdf, substrate_fn) \ const varying MicrofacetDielectricLayer *uniform mdl = \ (const varying MicrofacetDielectricLayer *uniform) & mdl_name; \ \ float cosThetaO = dot(wo, getN(&mdl->super)); \ if (cosThetaO <= 0.f) \ return make_BSDF_EvalRes_zero(); \ float cosThetaI = dot(wi, getN(&mdl->super)); \ \ /* Evaluate the substrate */ \ /* Ignore refraction */ \ BSDF_EvalRes substrate = substrate_fn(substrate_bsdf, wo, wi); \ \ /* Apply the coating medium absorption */ \ /* Use refracted angles for computing the absorption path length */ \ float lengthO1 = rcp(refract(cosThetaO, mdl->eta)); /* rcp(cosThetaO1) */ \ float lengthI1 = \ rcp(refract(abs(cosThetaI), mdl->eta)); /* rcp(cosThetaI1) */ \ float length = lengthO1 + lengthI1; \ if (cosThetaI <= 0.f) \ length *= 0.5f; /* for transmission, use the average length */ \ substrate.value = lerp(mdl->weight, \ substrate.value, \ substrate.value * pow(mdl->transmittance, mdl->thickness * length)); \ \ /* Energy conservation */ \ float Eo = MicrofacetAlbedoTable_eval( \ mdl->microfacetAlbedoTables, cosThetaO, mdl->roughness); \ float Ei = MicrofacetAlbedoTable_eval( \ mdl->microfacetAlbedoTables, abs(cosThetaI), mdl->roughness); \ float Ro = \ (MicrofacetDielectricReflectionAlbedoTable_eval( \ mdl->microfacetAlbedoTables, cosThetaO, mdl->eta, mdl->roughness) \ + mdl->fmsScale * (1.f - Eo)) \ * mdl->weight; /* add missing energy */ \ float Ri = (MicrofacetDielectricReflectionAlbedoTable_eval( \ mdl->microfacetAlbedoTables, \ abs(cosThetaI), \ mdl->eta, \ mdl->roughness) \ + mdl->fmsScale * (1.f - Ei)) \ * mdl->weight; /* add missing energy */ \ float T; \ if (scatteringType & ~BSDF_DIFFUSE) \ T = min(1.f - Ro, 1.f - Ri); /* for generic (non-diffuse) substrates \ [Kulla and Conty, 2017] */ \ else \ T = (1.f - Ro) * (1.f - Ri) \ * rcp(1.f - mdl->Ravg); /* for diffuse substrates [Kelemen and \ Szirmay-Kalos, 2001] */ \ substrate.value = substrate.value * T; \ \ float coatPickProb = Ro; \ float substratePickProb = 1.f - coatPickProb; \ \ if (cosThetaI > 0.f) { \ /* Compute the microfacet normal */ \ vec3f wh = normalize(wo + wi); \ float cosThetaOH = dot(wo, wh); \ \ /* Fresnel term */ \ float F = fresnelDielectric(cosThetaOH, mdl->eta) * mdl->weight; \ \ /* Evaluate the coating reflection */ \ float cosThetaIH = dot(wi, wh); \ \ linear3f toLocal = transposed(getFrame(&mdl->super)); \ vec3f wo0 = toLocal * wo; \ vec3f wi0 = toLocal * wi; \ vec3f wh0 = toLocal * wh; \ \ float whPdf; \ float D = evalVisible(mdl->microfacet, wh0, wo0, cosThetaOH, whPdf); \ float G = evalG2(mdl->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); \ \ /* Energy compensation */ \ float fms = mdl->fmsScale \ * ((1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - mdl->Eavg)) \ * cosThetaI); \ \ BSDF_EvalRes coat; \ coat.pdf = whPdf * rcp(4.f * cosThetaOH); \ coat.value = make_vec3f(F * D * G * rcp(4.f * cosThetaO) + fms); \ \ /* Compute the total reflection */ \ substrate.pdf = \ coatPickProb * coat.pdf + substratePickProb * substrate.pdf; \ substrate.value = coat.value + substrate.value; \ } else { \ /* Return the substrate transmission */ \ substrate.pdf *= substratePickProb; \ } #define MICROFACETDIELECTRICLAYER_EVAL_GET() substrate // Sample macros #define MICROFACETDIELECTRICLAYER_SAMPLE(mdl_name, \ scatteringType, \ substrate_bsdf, \ substrate_eval, \ substrate_sample) \ const varying MicrofacetDielectricLayer *uniform mdl = \ (const varying MicrofacetDielectricLayer *uniform) & mdl_name; \ BSDF_SampleRes res; \ \ float cosThetaO = dot(wo, getN(&mdl->super)); \ if (cosThetaO <= 0.f) \ return make_BSDF_SampleRes_zero(); \ \ linear3f toGlobal = getFrame(&mdl->super); \ linear3f toLocal = transposed(getFrame(&mdl->super)); \ vec3f wo0 = toLocal * wo; \ \ /* Energy conservation */ \ float Eo = MicrofacetAlbedoTable_eval( \ mdl->microfacetAlbedoTables, cosThetaO, mdl->roughness); \ float Ro = \ MicrofacetDielectricReflectionAlbedoTable_eval( \ mdl->microfacetAlbedoTables, cosThetaO, mdl->eta, mdl->roughness) \ + mdl->fmsScale * (1.f - Eo) * mdl->weight; /* add missing energy */ \ \ /* Sample the coating or the substrate */ \ vec3f wh; \ BSDF_EvalRes substrate; \ \ float coatPickProb = Ro; \ float substratePickProb = 1.f - coatPickProb; \ \ if (ss < coatPickProb) { \ /* Sample the microfacet normal */ \ float whPdf; \ wh = toGlobal * sampleVisible(mdl->microfacet, wo0, whPdf, s); \ float cosThetaOH = dot(wo, wh); \ \ res.type = BSDF_GLOSSY_REFLECTION; \ res.wi = reflect(wo, wh, cosThetaOH); \ \ /* Evaluate the substrate */ \ /* Ignore refraction */ \ substrate = substrate_eval(substrate_bsdf, wo, res.wi); \ } else { \ /* Sample the substrate */ \ /* Ignore refraction */ \ float ss1 = \ (ss - coatPickProb) * rcp(substratePickProb); /* reallocate sample */ \ res = substrate_sample(substrate_bsdf, wo, s, ss1); \ if (reduce_max(res.weight) <= 0.f) \ return res; \ \ substrate.pdf = res.pdf; \ substrate.value = res.weight \ * ((res.type & BSDF_SPECULAR) \ ? 1.f \ : res.pdf); /* correctly handle delta distributions */ \ \ /* Compute the microfacet normal */ \ wh = normalize(wo + res.wi); \ } \ \ float cosThetaI = dot(res.wi, getN(&mdl->super)); \ float cosThetaOH = dot(wo, wh); \ \ /* Apply the coating medium absorption */ \ /* Use refracted angles for computing the absorption path length */ \ float lengthO1 = rcp(refract(cosThetaO, mdl->eta)); /* rcp(cosThetaO1) */ \ float lengthI1 = \ rcp(refract(abs(cosThetaI), mdl->eta)); /* rcp(cosThetaI1) */ \ float length = lengthO1 + lengthI1; \ if (cosThetaI <= 0.f) \ length *= 0.5f; /* for transmission, use the average length */ \ substrate.value = lerp(mdl->weight, \ substrate.value, \ substrate.value * pow(mdl->transmittance, mdl->thickness * length)); \ \ /* Energy conservation */ \ float Ei = MicrofacetAlbedoTable_eval( \ mdl->microfacetAlbedoTables, abs(cosThetaI), mdl->roughness); \ float Ri = (MicrofacetDielectricReflectionAlbedoTable_eval( \ mdl->microfacetAlbedoTables, \ abs(cosThetaI), \ mdl->eta, \ mdl->roughness) \ + mdl->fmsScale * (1.f - Ei)) \ * mdl->weight; /* add missing energy */ \ float T; \ if (scatteringType & ~BSDF_DIFFUSE) \ T = min(1.f - Ro, 1.f - Ri); /* for generic (non-diffuse) substrates \ [Kulla and Conty, 2017] */ \ else \ T = (1.f - Ro) * (1.f - Ri) \ * rcp(1.f - mdl->Ravg); /* for diffuse substrates [Kelemen and \ Szirmay-Kalos, 2001] */ \ substrate.value = substrate.value * T; \ \ if (res.type & BSDF_SPECULAR) { \ /* If we sampled a delta distribution, we don't have to evaluate the \ * coating reflection (see MultiBSDF_sample) */ \ res.weight = substrate.value * rcp(substratePickProb); \ } else if (cosThetaI <= 0.f) { \ /* If we sampled transmission, we just have to return the substrate \ * transmission */ \ res.pdf = substratePickProb * substrate.pdf; \ res.weight = substrate.value * rcp(res.pdf); \ } else { \ /* Fresnel term */ \ float F = fresnelDielectric(cosThetaOH, mdl->eta) * mdl->weight; \ \ /* Evaluate the coating reflection */ \ float cosThetaIH = dot(res.wi, wh); \ vec3f wi0 = toLocal * res.wi; \ vec3f wh0 = toLocal * wh; \ \ float whPdf; \ float D = evalVisible(mdl->microfacet, wh0, wo0, cosThetaOH, whPdf); \ float G = evalG2(mdl->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); \ \ /* Energy compensation */ \ float fms = mdl->fmsScale \ * ((1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - mdl->Eavg)) \ * cosThetaI); \ \ BSDF_EvalRes coat; \ coat.pdf = whPdf * rcp(4.f * cosThetaOH); \ coat.value = make_vec3f(F * D * G * rcp(4.f * cosThetaO) + fms); \ \ /* Compute the total reflection */ \ res.pdf = coatPickProb * coat.pdf + substratePickProb * substrate.pdf; \ res.weight = (coat.value + substrate.value) * rcp(res.pdf); \ } #define MICROFACETDIELECTRICLAYER_SAMPLE_GET() res RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetDistribution.ih000066400000000000000000000011451464752671100271110ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline float roughnessToAlpha(float roughness) { // Roughness is squared for perceptual reasons return max(sqr(roughness), 0.001f); } // [Burley, 2012, "Physically Based Shading at Disney", Course Notes, v3] inline vec2f roughnessToAlpha(float roughness, float anisotropy) { float aspect = sqrt(1.f - 0.9f * anisotropy); return make_vec2f(max(sqr(roughness) / aspect, 0.001f), max(sqr(roughness) * aspect, 0.001f)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MicrofacetSheenLayer.ih000066400000000000000000000311771464752671100265010ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "MicrofacetAlbedoTables.ih" #include "SheenDistribution.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Microfacet sheen BSDF for cloth-like materials. // [Conty and Kulla, 2017, "Production Friendly Microfacet Sheen BRDF"] // [Kulla and Conty, 2017, "Revisiting Physically Based Shading at Imageworks"] struct MicrofacetSheenLayer { BSDF super; float weight; vec3f R; SheenDistribution microfacet; float roughness; const MicrofacetAlbedoTables *uniform microfacetAlbedoTables; }; inline void MicrofacetSheenLayer_Constructor( varying MicrofacetSheenLayer *uniform self, const MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, varying BSDF *varying substrate, vec3f R, float roughness, float weight) { BSDF_Constructor(&self->super, lerp(weight * 0.1f, substrate->albedo, R), // lean towards substrate (sheen is only at edge) BSDF_DIFFUSE_REFLECTION | substrate->scatteringType, BSDF_TYPE_MICROFACET_SHEEN_LAYER, frame); self->R = R; self->microfacet = make_SheenDistribution(roughnessToAlpha(roughness)); self->roughness = roughness; self->weight = weight; self->microfacetAlbedoTables = microfacetAlbedoTables; } inline varying BSDF *uniform MicrofacetSheenLayer_create( uniform ShadingContext *uniform ctx, const MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, varying BSDF *varying substrate, vec3f R, float roughness, float weight) { varying MicrofacetSheenLayer *uniform self = (varying MicrofacetSheenLayer * uniform) ShadingContext_alloc(ctx, sizeof(MicrofacetSheenLayer)); MicrofacetSheenLayer_Constructor( self, microfacetAlbedoTables, frame, substrate, R, roughness, weight); return &self->super; } // Helper function for transparent shadow rays inline vec3f MicrofacetSheenLayer_getTransparency( const MicrofacetAlbedoTables *uniform microfacetAlbedoTables, float cosThetaO, float roughness, float weight) { // Energy conservation float Ro = MicrofacetSheenAlbedoTable_eval( microfacetAlbedoTables, cosThetaO, roughness) * weight; float T = 1.f - Ro; return make_vec3f(T); } OSPRAY_END_ISPC_NAMESPACE // Eval macros #define MICROFACETSHEENLAYER_EVAL(msl_name, substrate_bsdf, substrate_fn) \ const varying MicrofacetSheenLayer *uniform msl = \ (const varying MicrofacetSheenLayer *uniform) & msl_name; \ \ float cosThetaO = dot(wo, getN(&msl->super)); \ if (cosThetaO <= 0.f) \ return make_BSDF_EvalRes_zero(); \ float cosThetaI = dot(wi, getN(&msl->super)); \ \ /* Evaluate the substrate */ \ BSDF_EvalRes substrate = substrate_fn(substrate_bsdf, wo, wi); \ \ /* Energy conservation */ \ float Ro = MicrofacetSheenAlbedoTable_eval( \ msl->microfacetAlbedoTables, cosThetaO, msl->roughness) \ * msl->weight; \ float Ri = MicrofacetSheenAlbedoTable_eval( \ msl->microfacetAlbedoTables, abs(cosThetaI), msl->roughness) \ * msl->weight; \ float T = min(1.f - Ro, 1.f - Ri); \ substrate.value = substrate.value * T; \ \ float coatPickProb = Ro; \ float substratePickProb = 1.f - coatPickProb; \ \ if (cosThetaI > 0.f) { \ /* Compute the microfacet normal */ \ vec3f wh = normalize(wo + wi); \ float cosThetaH = dot(wh, getN(&msl->super)); \ float cosThetaOH = dot(wo, wh); \ float cosThetaIH = dot(wi, wh); \ \ /* Evaluate the coating reflection */ \ float D = eval(msl->microfacet, cosThetaH); \ float G = \ evalG2(msl->microfacet, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); \ \ BSDF_EvalRes coat; \ coat.pdf = uniformSampleHemispherePDF(); \ coat.value = msl->R * (D * G * rcp(4.f * cosThetaO) * msl->weight); \ \ /* Compute the total reflection */ \ substrate.pdf = \ coatPickProb * coat.pdf + substratePickProb * substrate.pdf; \ substrate.value = coat.value + substrate.value; \ } else { \ /* Return the substrate transmission */ \ substrate.pdf *= substratePickProb; \ } #define MICROFACETSHEENLAYER_EVAL_GET() substrate // Sample macros #define MICROFACETSHEENLAYER_SAMPLE( \ msl_name, substrate_bsdf, substrate_eval, substrate_sample) \ const varying MicrofacetSheenLayer *uniform msl = \ (const varying MicrofacetSheenLayer *uniform) & msl_name; \ BSDF_SampleRes res; \ \ float cosThetaO = dot(wo, getN(&msl->super)); \ if (cosThetaO <= 0.f) \ return make_BSDF_SampleRes_zero(); \ \ /* Energy conservation */ \ float Ro = MicrofacetSheenAlbedoTable_eval( \ msl->microfacetAlbedoTables, cosThetaO, msl->roughness) \ * msl->weight; \ \ /* Sample the coating or the substrate */ \ BSDF_EvalRes substrate; \ \ float coatPickProb = Ro; \ float substratePickProb = 1.f - coatPickProb; \ \ if (ss < coatPickProb) { \ /* Sample the coating reflection */ \ res.type = BSDF_DIFFUSE_REFLECTION; \ res.wi = getFrame(&msl->super) * uniformSampleHemisphere(s); \ \ /* Evaluate the substrate */ \ substrate = substrate_eval(substrate_bsdf, wo, res.wi); \ } else { \ /* Sample the substrate */ \ float ss1 = \ (ss - coatPickProb) * rcp(substratePickProb); /* reallocate sample */ \ res = substrate_sample(substrate_bsdf, wo, s, ss1); \ if (reduce_max(res.weight) <= 0.f) \ return res; \ \ substrate.pdf = res.pdf; \ substrate.value = res.weight \ * ((res.type & BSDF_SPECULAR) \ ? 1.f \ : res.pdf); /* correctly handle delta distributions */ \ } \ \ float cosThetaI = dot(res.wi, getN(&msl->super)); \ \ /* Energy conservation */ \ float Ri = MicrofacetSheenAlbedoTable_eval( \ msl->microfacetAlbedoTables, abs(cosThetaI), msl->roughness) \ * msl->weight; \ float T = min(1.f - Ro, 1.f - Ri); \ substrate.value = substrate.value * T; \ \ if (res.type & BSDF_SPECULAR) { \ /* If we sampled a delta distribution, we don't have to evaluate the \ * coating reflection (see MultiBSDF_sample) */ \ res.weight = substrate.value * rcp(substratePickProb); \ } else if (cosThetaI <= 0.f) { \ /* If we sampled transmission, we just have to return the substrate \ * transmission */ \ res.pdf = substratePickProb * substrate.pdf; \ res.weight = substrate.value * rcp(res.pdf); \ } else { \ /* Compute the microfacet normal */ \ vec3f wh = normalize(wo + res.wi); \ float cosThetaH = dot(wh, getN(&msl->super)); \ float cosThetaOH = dot(wo, wh); \ float cosThetaIH = dot(res.wi, wh); \ \ /* Evaluate the coating reflection */ \ float D = eval(msl->microfacet, cosThetaH); \ float G = \ evalG2(msl->microfacet, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); \ \ BSDF_EvalRes coat; \ coat.pdf = uniformSampleHemispherePDF(); \ coat.value = msl->R * (D * G * rcp(4.f * cosThetaO) * msl->weight); \ \ /* Compute the total reflection */ \ res.pdf = coatPickProb * coat.pdf + substratePickProb * substrate.pdf; \ res.weight = (coat.value + substrate.value) * rcp(res.pdf); \ } #define MICROFACETSHEENLAYER_SAMPLE_GET() res RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Minneart.ih000066400000000000000000000034401464752671100242120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "ShadingContext.ih" #include "math/sampling.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Minneart { BSDF super; /*! The amount of backscattering. A value of 0 means lambertian * diffuse, and inf means maximum backscattering. */ float b; }; inline BSDF_EvalRes Minneart_eval( const varying Minneart *uniform self, const vec3f &wo, const vec3f &wi) { BSDF_EvalRes res; const float cosThetaI = clamp(dot(wi, getN(&self->super))); const float backScatter = pow(clamp(dot(wo, wi)), self->b); res.pdf = cosineSampleHemispherePDF(cosThetaI); res.value = (backScatter * cosThetaI * (float)one_over_pi) * self->super.albedo; return res; } inline BSDF_SampleRes Minneart_sample(const varying Minneart *uniform self, const vec3f &wo, const vec2f &s, float) { BSDF_SampleRes res; const vec3f localDir = cosineSampleHemisphere(s); res.wi = getFrame(&self->super) * localDir; res.type = BSDF_DIFFUSE_REFLECTION; BSDF_EvalRes eval = Minneart_eval(self, wo, res.wi); res.pdf = eval.pdf; res.weight = eval.value * rcp(eval.pdf); return res; } inline void Minneart_Constructor(varying Minneart *uniform self, const varying linear3f *uniform frame, vec3f R, float b) { BSDF_Constructor( &self->super, R, BSDF_DIFFUSE_REFLECTION, BSDF_TYPE_MINNEART, frame); self->b = b; } inline varying BSDF *uniform Minneart_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, vec3f R, float b) { varying Minneart *uniform self = (varying Minneart * uniform) ShadingContext_alloc(ctx, sizeof(Minneart)); Minneart_Constructor(self, frame, R, b); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/MultiBSDF.ih000066400000000000000000000126431464752671100241730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "ShadingContext.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct MultiBSDF_Child { float weight; float importance; }; #define DEFINE_MULTIBSDF(size) \ BSDF super; \ float importanceSum; \ MultiBSDF_Child children[size] struct MultiBSDF { DEFINE_MULTIBSDF(1); }; inline void MultiBSDF_add(varying MultiBSDF *uniform self, const uniform int id, const varying BSDF *uniform bsdf, float weight = 1.f, float importance = 1.f) { self->super.albedo = self->super.albedo + bsdf->albedo * weight; self->super.scatteringType |= bsdf->scatteringType; if (!self->super.frame) // use first frame TODO use dominant frame self->super.frame = bsdf->frame; self->children[id].weight = weight; unmasked { self->children[id].importance = 0.f; } self->children[id].importance = importance; self->importanceSum += importance; } inline void MultiBSDF_Constructor( varying MultiBSDF *uniform self, const uniform int count) { BSDF_Constructor( &self->super, make_vec3f(0.f), BSDF_NONE, BSDF_TYPE_MULTI_BSDF, NULL); unmasked { self->importanceSum = 0.0f; for (uniform int i = 0; i < count; i++) { self->children[i].weight = 0.f; self->children[i].importance = 0.f; } } } OSPRAY_END_ISPC_NAMESPACE // Eval macros #define MULTIBSDF_EVAL_BEGIN() \ BSDF_EvalRes eRes = make_BSDF_EvalRes_zero(); \ const int choice = -1 #define MULTIBSDF_EVAL_CHILD(id, child_bsdf, eval_fn) \ if ((self->children[id].importance > 0.f) && (choice != id)) { \ BSDF_EvalRes cur = eval_fn(child_bsdf, wo, wi); \ cur.value = cur.value * self->children[id].weight; \ eRes.value = eRes.value + cur.value; \ eRes.pdf += cur.pdf * self->children[id].importance; \ } #define MULTIBSDF_EVAL_END() eRes.pdf *= rcp(self->importanceSum) #define MULTIBSDF_EVAL_GET() eRes // Sample macros #define MULTIBSDF_SAMPLE_BEGIN() \ BSDF_SampleRes res = make_BSDF_SampleRes_zero(); \ float x = ss * self->importanceSum; \ int choice = 0; \ float prefixSum = 0.f; \ if (self->importanceSum == 0.f) { \ return res #define MULTIBSDF_SAMPLE_CHILD(id, child_bsdf, sample_fn) \ } \ else if (x < (prefixSum += self->children[id].importance)) \ { \ choice = id; \ \ ss = (x + self->children[id].importance - prefixSum) \ * rcp(self->children[id].importance); \ \ res = sample_fn(child_bsdf, wo, s, ss); \ res.weight = res.weight * self->children[id].weight #define MULTIBSDF_SAMPLE_EVAL() \ } \ if (eq(res.weight, make_vec3f(0.0f)) || (res.pdf == 0.0f)) \ return make_BSDF_SampleRes_zero(); \ \ /* if the sampled BSDF is specular (has a delta distribution), we cannot add \ * the contributions from the other BSDFs [Pharr et al., 2016, "Physically \ * Based Rendering", 3rd Edition, Section 14.1.6] */ \ if (res.type & BSDF_SPECULAR) { \ /* scale by rcp(selection pdf) */ \ res.weight = res.weight \ * (self->importanceSum * rcp(self->children[choice].importance)); \ return res; \ } \ BSDF_EvalRes eRes; \ eRes.value = res.weight * res.pdf; \ res.pdf *= self->children[choice].importance; \ eRes.pdf = res.pdf; \ const vec3f wi = res.wi #define MULTIBSDF_SAMPLE_END() \ res.pdf = eRes.pdf; \ res.pdf *= rcp(self->importanceSum); \ res.weight = eRes.value * rcp(res.pdf) #define MULTIBSDF_SAMPLE_GET() res RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Optics.ih000066400000000000000000000031771464752671100237050ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE /*! Reflects a viewing vector I at a normal N. Cosine between I * and N is given as input. */ inline vec3f reflect(const vec3f &I, const vec3f &N, float cosI) { return (2.0f * cosI) * N - I; } /*! Reflects a viewing vector I at a normal N. */ inline vec3f reflect(const vec3f &I, const vec3f &N) { return reflect(I, N, dot(I, N)); } // helper function which computes cosT^2 from cosI and eta inline float sqrCosT(const float cosI, const float eta) { return 1.0f - sqr(eta) * (1.0f - sqr(cosI)); } //! \brief Refracts a viewing vector I at a normal N /*! \detailed Refracts a viewing vector I at a normal N using the * relative refraction index eta. Eta is refraction index of outside * medium (where N points into) divided by refraction index of the * inside medium. The vectors I and N have to point towards the same * side of the surface. The cosine between I and N, and the cosine of -N and * the refracted ray is given as input */ inline vec3f refract( const vec3f &I, const vec3f &N, float cosI, float cosT, float eta) { return eta * (cosI * N - I) - cosT * N; } inline vec3f refract(const vec3f &I, const vec3f &N, float cosI, float eta) { const float sqrcost = sqrCosT(cosI, eta); if (sqrcost < 0.0f) return make_vec3f(0.f); return refract(I, N, cosI, sqrt(sqrcost), eta); } inline float refract(float cosI, float eta) { const float sqrcost = sqrCosT(cosI, eta); return sqrt(max(sqrcost, 0.0f)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/OrenNayar.ih000066400000000000000000000040541464752671100243350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "GGXDistribution.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Oren-Nayar BRDF. // [Fujii, 2012, "A tiny improvement of Oren-Nayar reflectance model"] struct OrenNayar { BSDF super; float roughness; }; inline BSDF_EvalRes OrenNayar_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying OrenNayar *uniform self = (const varying OrenNayar *uniform)super; BSDF_EvalRes res; float cosThetaO = max(dot(wo, getN(super)), 0.f); float cosThetaI = max(dot(wi, getN(super)), 0.f); float s = dot(wo, wi) - cosThetaO * cosThetaI; float sInvt = (s > 0.f) ? (s * rcp_safe(max(cosThetaO, cosThetaI))) : s; res.value = self->super.albedo * (cosThetaI * (1.f + self->roughness * sInvt) * rcp((float)pi + ((float)pi / 2.f - 2.f / 3.f) * self->roughness)); res.pdf = cosineSampleHemispherePDF(cosThetaI); return res; } inline BSDF_SampleRes OrenNayar_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float) { const vec3f localDir = cosineSampleHemisphere(s); BSDF_SampleRes res; res.wi = getFrame(super) * localDir; BSDF_EvalRes eval = OrenNayar_eval(super, wo, res.wi); res.pdf = eval.pdf; res.type = BSDF_DIFFUSE_REFLECTION; res.weight = eval.value * rcp(eval.pdf); return res; } inline void OrenNayar_Constructor(varying OrenNayar *uniform self, const varying linear3f *uniform frame, const vec3f &R, float roughness) { BSDF_Constructor( &self->super, R, BSDF_DIFFUSE_REFLECTION, BSDF_TYPE_OREN_NAYAR, frame); self->roughness = roughness; } inline varying BSDF *uniform OrenNayar_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, const vec3f &R, float roughness) { varying OrenNayar *uniform self = (varying OrenNayar * uniform) ShadingContext_alloc(ctx, sizeof(OrenNayar)); OrenNayar_Constructor(self, frame, R, roughness); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/PassthroughLayer.ih000066400000000000000000000015001464752671100257340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PassthroughLayer { BSDF super; float weight; }; inline void PassthroughLayer_Constructor( varying PassthroughLayer *uniform self, varying BSDF *uniform substrate) { BSDF_Constructor(&self->super, substrate->albedo, substrate->scatteringType, substrate->bsdfType, substrate->frame); self->weight = 0.f; } #ifndef OSPRAY_TARGET_SYCL inline void PassthroughLayer_Constructor( varying PassthroughLayer *uniform self, varying BSDF *varying substrate) { foreach_unique (s in substrate) { BSDF_Constructor( &self->super, s->albedo, s->scatteringType, s->bsdfType, s->frame); } self->weight = 0.f; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/PowerCosineDistribution.ih000066400000000000000000000016231464752671100272730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/math.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PowerCosineDistribution { float exp; }; inline float eval( const PowerCosineDistribution &self, float cosThetaH, float &pdf) { pdf = powerCosineSampleHemispherePDF(cosThetaH, self.exp); return (self.exp + 2) * one_over_two_pi * pow(abs(cosThetaH), self.exp); // TODO: check with powerCosineSampleHemispherePDF } /*! Samples the power cosine distribution. */ inline vec3f sample( const PowerCosineDistribution &self, float &pdf, const vec2f &s) { const vec3f wh = powerCosineSampleHemisphere(self.exp, s); pdf = powerCosineSampleHemispherePDF(wh, self.exp); return wh; } inline PowerCosineDistribution make_PowerCosineDistribution(float _exp) { PowerCosineDistribution m; m.exp = _exp; return m; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Reflection.ih000066400000000000000000000022411464752671100245250ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline BSDF_EvalRes Reflection_eval(const varying BSDF *uniform, const vec3f &, const vec3f &, const uniform FeatureFlagsHandler &) { return make_BSDF_EvalRes_zero(); } inline BSDF_SampleRes Reflection_sample(const varying BSDF *uniform self, const vec3f &wo, const vec2f &, float, const uniform FeatureFlagsHandler &) { BSDF_SampleRes res; res.wi = reflect(wo, getN(self)); res.pdf = inf; res.type = BSDF_SPECULAR_REFLECTION; res.weight = self->albedo; return res; } inline varying BSDF *uniform Reflection_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, vec3f reflectance) { varying BSDF *uniform self = (varying BSDF * uniform) ShadingContext_alloc(ctx, sizeof(BSDF)); BSDF_Constructor(self, reflectance, BSDF_SPECULAR_REFLECTION, BSDF_TYPE_REFLECTION, #ifdef OSPRAY_TARGET_SYCL NULL, NULL, #else Reflection_eval, Reflection_sample, #endif frame); return self; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/RobustDielectric.ih000066400000000000000000000154751464752671100257160ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "Fresnel.ih" #include "common/DifferentialGeometry.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // FIXME: this should be cleaned up and integrated into Dielectric and // MicrofacetDielectric struct RobustDielectric { BSDF super; float eta; // FIXME: BSDFs should *not* store the DifferentialGeometry or similar // parameters (i.e., Ng, Ns). These should be passed to sample/eval // DifferentialGeometry dgeom; vec3f Ng; vec3f Ns; }; struct RefractionResult { vec3f outgoingDirection; float FresnelReflectionCoefficient; bool mustReflect; }; inline RefractionResult RefractionDirection( const vec3f &incomingDir, const vec3f &surfaceNormal, const float eta) { RefractionResult res; res.mustReflect = false; float cos1 = dot(incomingDir, surfaceNormal); float cos1_abs = cos1; if (cos1_abs < 0.f) { cos1_abs = -cos1_abs; } // For head-on collisions the cosine of the angle of the ray with the surface // normal will be equal to one or minus one. bool headOn = (1.f - 1e-6f < cos1_abs && cos1_abs < 1.f - 1e-6f); if (headOn) { res.FresnelReflectionCoefficient = sqr((eta - 1.f) / (eta + 1.f)); res.outgoingDirection = incomingDir; } else { vec3f dirParallelToNormal = cos1 * surfaceNormal; vec3f dirPerpendicularToNormal = incomingDir - dirParallelToNormal; vec3f b = normalize(dirPerpendicularToNormal); float sin1 = dot(dirPerpendicularToNormal, b); float sin2 = sin1 / eta; if (sin2 > 1.0f) { // Total internal reflection. res.outgoingDirection = make_vec3f(0.f); // Can't refract. res.FresnelReflectionCoefficient = 1.f; res.mustReflect = true; } else { // Refracting. float cos2 = sqrt(clamp(1.f - sin2 * sin2)); vec3f N2 = normalize(dirParallelToNormal); res.outgoingDirection = N2 * cos2 + b * sin2; float c1 = cos1_abs; float c2 = cos2; float r1 = (eta * c1 - c2) / (eta * c1 + c2); float r2 = (c1 - eta * c2) / (c1 + eta * c2); res.FresnelReflectionCoefficient = 0.5f * (r1 * r1 + r2 * r2); } } // Clamp in case of roundoff error. res.FresnelReflectionCoefficient = clamp(res.FresnelReflectionCoefficient); return res; } inline vec3f ReflectionDirection(const vec3f &incomingDir, const vec3f &normal) { // Imagine a particle traveling toward the surface and then bouncing off in // the // reflection direction. // Parallel or anti-parallel direction. vec3f dirParallelToNormal = dot(incomingDir, normal) * normal; vec3f dirPerpendicularToNormal = incomingDir - dirParallelToNormal; // Outgoing direction. return (dirPerpendicularToNormal - dirParallelToNormal); } inline BSDF_SampleRes RobustDielectric_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f & /*randomV*/, float randomF) { const varying RobustDielectric *uniform self = (const varying RobustDielectric *uniform)super; BSDF_SampleRes res; res.pdf = inf; // We want the actual ray direction into the surface. vec3f incomingDir = neg(wo); vec3f shadingNormal = self->Ns; vec3f geometricNormal = self->Ng; float eta = 1.f / self->eta; // ior(outside) / ior(inside) float glass_epsilon = 1e-6f; bool canReflect = (eta < 1.f - glass_epsilon || eta > 1.f + glass_epsilon); bool be_careful = true; // Extra test for edge cases when the shading normal // is different from the geometry normal. bool nudge = true; // When we have grazing angles. Only used if be_careful==true. if (be_careful) { // Flip the normals to be on the same side of the surface as the incoming // ray. if (dot(incomingDir, shadingNormal) > 0.f) { shadingNormal = neg(shadingNormal); } if (dot(incomingDir, geometricNormal) > 0.f) { geometricNormal = neg(geometricNormal); } } float geometricCosine; vec3f dirR = ReflectionDirection(incomingDir, shadingNormal); RefractionResult refractionRes = RefractionDirection(incomingDir, shadingNormal, eta); vec3f dirT = refractionRes.outgoingDirection; float FresnelR = refractionRes.FresnelReflectionCoefficient; bool mustReflect = refractionRes.mustReflect; res.weight = make_vec3f(1.f); // Sample the reflection or the transmission using the provided random number. if ((randomF < FresnelR && canReflect) || mustReflect) { // Reflection res.wi = dirR; // Outgoing ray direction. res.type = BSDF_SPECULAR_REFLECTION; if (be_careful) { geometricCosine = dot(res.wi, geometricNormal); if (geometricCosine >= 0.f) { // Reflecting as expected. if (nudge && (geometricCosine < glass_epsilon)) { // Grazing angle. res.wi = res.wi + glass_epsilon * geometricNormal; // Nudge the ray away from the surface. res.wi = normalize(res.wi); } } else { // geometricCosine < 0 // We actually "refracted" since we are now on the other side of the // surface. Keep the ray type as reflection, but move the ray above the // surface. res.wi = res.wi - 2.f * geometricNormal * geometricCosine; } } } else { // Transmission res.wi = dirT; // Outgoing ray direction. res.type = BSDF_SPECULAR_TRANSMISSION; // res.weight = make_vec3f(rsqrt(self->eta));// Solid angle compression. if (be_careful) { geometricCosine = dot(res.wi, geometricNormal); if (geometricCosine <= 0.f) { // Transmitting as expected. if (nudge && (geometricCosine > -glass_epsilon)) { // Grazing angle. res.wi = res.wi - glass_epsilon * geometricNormal; // Nudge the ray away from the surface. res.wi = normalize(res.wi); } } else { // geometricCosine > 0 // We actually "reflected" since we are still on the same side of the // surface. Change ray type to reflection. res.type = BSDF_SPECULAR_REFLECTION; } } } return res; } inline void RobustDielectric_Constructor(varying RobustDielectric *uniform self, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, float eta) { const varying linear3f *uniform shadingframe = LinearSpace3f_create(ctx, frame(dg.Ns)); BSDF_Constructor(&self->super, make_vec3f(1.0f), BSDF_SPECULAR, BSDF_TYPE_ROBUST_DIELECTRIC, shadingframe); self->eta = eta; self->Ns = dg.Ns; self->Ng = dg.Ng; } inline varying BSDF *uniform RobustDielectric_create( uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, float eta) { varying RobustDielectric *uniform self = (varying RobustDielectric * uniform) ShadingContext_alloc(ctx, sizeof(RobustDielectric)); RobustDielectric_Constructor(self, ctx, dg, eta); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/RobustThinDielectric.ih000066400000000000000000000060261464752671100265310ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Dielectric.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Thin dielectric BSDF. // It represents a transparent slab with unit thickness, and ignores refraction. struct RobustThinDielectric { BSDF super; float eta; vec3f attenuation; }; inline BSDF_SampleRes RobustThinDielectric_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &, float ss) { const varying RobustThinDielectric *uniform self = (const varying RobustThinDielectric *uniform)super; BSDF_SampleRes res; float cosThetaO = max(dot(wo, getN(super)), 0.f); // Fresnel terms float cosThetaT; // positive float Fo = fresnelDielectricEx(cosThetaO, cosThetaT, self->eta); float Ft = fresnelDielectric(cosThetaT, rcp(self->eta)); // Attenuation for crossing the slab once float length = rcp(cosThetaT); vec3f A = expf(self->attenuation * length); // Reflection and transmission weights vec3f R = Fo + (1.f - Fo) * (1.f - Ft) * (Ft * sqr(A)) * rcp(1.f - sqr(Ft * A)); vec3f T = (1.f - Fo) * A * (1.f - Ft) * (1.f + sqr(Ft * A) * rcp(1.f - sqr(Ft * A))); // Sample the reflection or the transmission float pR = luminance(R); float pT = luminance(T); float p = clamp(pR * rcp(pR + pT), 0.25f, 0.75f); bool doReflection = (ss <= p); if (doReflection) { // Reflection res.wi = reflect(wo, getN(super), cosThetaO); res.type = BSDF_SPECULAR_REFLECTION; res.weight = R * rcp(p); } else { // Transmission res.wi = neg(wo); res.type = BSDF_SPECULAR_TRANSMISSION; res.weight = T * rcp(1.f - p); } res.pdf = inf; return res; } inline void RobustThinDielectric_Constructor( varying RobustThinDielectric *uniform self, const varying linear3f *uniform frame, float eta, vec3f attenuation) { BSDF_Constructor(&self->super, expf(attenuation), BSDF_SPECULAR, BSDF_TYPE_ROBUST_THIN_DIELECTRIC, frame); self->eta = eta; self->attenuation = attenuation; } inline varying BSDF *uniform RobustThinDielectric_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, float eta, vec3f attenuation) { varying RobustThinDielectric *uniform self = (varying RobustThinDielectric * uniform) ShadingContext_alloc(ctx, sizeof(RobustThinDielectric)); RobustThinDielectric_Constructor(self, frame, eta, attenuation); return &self->super; } // Helper function for transparent shadow rays inline vec3f RobustThinDielectric_getTransparency( float cosThetaO, float eta, vec3f attenuation) { // Fresnel terms float cosThetaT; // positive float Fo = fresnelDielectricEx(cosThetaO, cosThetaT, eta); float Ft = fresnelDielectric(cosThetaT, rcp(eta)); // Attenuation for crossing the slab once float length = rcp(cosThetaT); vec3f A = expf(attenuation * length); // Transmission weight vec3f T = (1.f - Fo) * A * (1.f - Ft) * (1.f + sqr(Ft * A) * rcp(1.f - sqr(Ft * A))); return T; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Scale.ih000066400000000000000000000034341464752671100234670ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Scale { BSDF super; const varying BSDF *uniform base; float factor; }; inline BSDF_EvalRes Scale_eval(const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi, const uniform FeatureFlagsHandler &ffh) { const varying Scale *uniform self = (const varying Scale *uniform)super; BSDF_EvalRes res = BSDF_dispatch_eval_base(self->base, wo, wi, ffh); res.value = res.value * self->factor; return res; } inline BSDF_SampleRes Scale_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss, const uniform FeatureFlagsHandler &ffh) { const varying Scale *uniform self = (const varying Scale *uniform)super; BSDF_SampleRes res = BSDF_dispatch_sample_base(self->base, wo, s, ss, ffh); res.weight = res.weight * self->factor; return res; } inline void Scale_Constructor(varying Scale *uniform self, const varying linear3f *uniform frame, const varying BSDF *uniform base, float factor) { BSDF_Constructor(&self->super, base->albedo * factor, base->bsdfType, BSDF_TYPE_SCALE, #ifdef OSPRAY_TARGET_SYCL NULL, NULL, #else Scale_eval, Scale_sample, #endif frame); self->base = base; self->factor = factor; } inline varying BSDF *uniform Scale_create(uniform ShadingContext *uniform ctx, const varying BSDF *uniform base, float factor) { varying Scale *uniform self = (varying Scale * uniform) ShadingContext_alloc(ctx, sizeof(Scale)); Scale_Constructor(self, LinearSpace3f_create(ctx, make_LinearSpace3f_varying_identity()), base, factor); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/ShadingContext.ih000066400000000000000000000027311464752671100253610ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/ISPCMessages.h" #include "rkcommon/math/LinearSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #define SHADINGCONTEXT_SIZE (programCount * programCount * 1024) #define SHADINGCONTEXT_ALIGNMENT 64 struct ShadingContext { /*! Data storage. Has to be at the beginning of the class due to alignment. */ uniform int8 data[SHADINGCONTEXT_SIZE]; //!< Storage for BSDFs uniform uint32 size; //!< Number of bytes occupied in storage varying int dummy; // FIXME: needed to force correct alignment }; inline void ShadingContext_Constructor(uniform ShadingContext *uniform self) { self->size = 0; } /*! Allocates aligned data. */ inline void *uniform ShadingContext_alloc( uniform ShadingContext *uniform self, uniform uint32 size) { // print("ShadingContext_alloc: %, %\n", this->size, size); void *uniform ptr = &self->data[self->size]; self->size = (self->size + size + SHADINGCONTEXT_ALIGNMENT - 1) & ((uint32)(-SHADINGCONTEXT_ALIGNMENT)); #ifndef OSPRAY_TARGET_SYCL if (self->size > SHADINGCONTEXT_SIZE) postStatusMsg(ISPC_MSG_SHADING_CONTEXT, OSP_LOG_ERROR); #endif return ptr; } inline varying linear3f *uniform LinearSpace3f_create( uniform ShadingContext *uniform ctx, const linear3f &l) { varying linear3f *uniform ptr = (varying linear3f * uniform) ShadingContext_alloc(ctx, sizeof(linear3f)); *ptr = l; return ptr; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/SheenDistribution.ih000066400000000000000000000046451464752671100261070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MicrofacetDistribution.ih" #include "math/sampling.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Cylindrical microfiber distribution for sheen // [Conty and Kulla, 2017, "Production Friendly Microfacet Sheen BRDF"] // [Kulla and Conty, 2017, "Revisiting Physically Based Shading at Imageworks"] struct SheenDistribution { float r; // in (0, 1] }; inline SheenDistribution make_SheenDistribution(float r) { SheenDistribution self; self.r = r; return self; } inline float eval(const SheenDistribution &self, float cosTheta) { float sinTheta = cos2sin(cosTheta); float invr = rcp(self.r); return (2.f + invr) * pow(sinTheta, invr) * (float)one_over_two_pi; } // Helper function for computing Lambda inline float evalL(const SheenDistribution &self, float x) { const float a0 = 25.3245f; const float a1 = 21.5473f; const float b0 = 3.32435f; const float b1 = 3.82987f; const float c0 = 0.16801f; const float c1 = 0.19823f; const float d0 = -1.27393f; const float d1 = -1.97760f; const float e0 = -4.85967f; const float e1 = -4.32054f; float r = self.r; float w0 = sqr(1.f - r); float w1 = 1.f - w0; float a = w0 * a0 + w1 * a1; float b = w0 * b0 + w1 * b1; float c = w0 * c0 + w1 * c1; float d = w0 * d0 + w1 * d1; float e = w0 * e0 + w1 * e1; return a / (1.f + b * pow(x, c)) + d * x + e; } inline float evalLambda(const SheenDistribution &self, float cosTheta) { if (cosTheta < 0.5f) return exp(evalL(self, cosTheta)); else return exp(2.f * evalL(self, 0.5f) - evalL(self, 1.f - cosTheta)); } // Non-physical artistic adjustment for a softer light terminator inline float evalLambdaI(const SheenDistribution &self, float cosTheta) { float x = 1.f + 2.f * sqr(sqr(sqr(1.f - cosTheta))); return pow(evalLambda(self, cosTheta), x); } // Smith's height-correlated masking-shadowing function // [Heitz, 2014, "Understanding the Masking-Shadowing Function in // Microfacet-Based BRDFs"] inline float evalG2(const SheenDistribution &self, float cosThetaO, float cosThetaI, float cosThetaOH, float cosThetaIH) { if (cosThetaO * cosThetaOH <= 0.f || cosThetaI * cosThetaIH <= 0.f) return 0.f; // return rcp(1.f + evalLambda(self, cosThetaO) + evalLambda(self, // cosThetaI)); return rcp(1.f + evalLambda(self, cosThetaO) + evalLambdaI(self, cosThetaI)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Specular.ih000066400000000000000000000043241464752671100242150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "Optics.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // uses a variant of Blinn-Phong BRDF: // f = r*(n+2)/(4pi(2-2^(-n/2)))*cos(HN)^n/cos(LN) struct Specular { BSDF super; vec3f ks; // reflectivity albedo, including normalization vec3f weight; // = constant part of f * cosNL/pdf float ns; // exponent }; inline BSDF_EvalRes Specular_eval( const varying Specular *uniform self, const vec3f &wo, const vec3f &wi) { BSDF_EvalRes res; const vec3f N = getN(&self->super); const float cosThetaO = dot(wo, N); const float cosThetaI = dot(wi, N); if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) return make_BSDF_EvalRes_zero(); const vec3f wh = normalize(wo + wi); const float cosThetaH = dot(wh, N); res.pdf = powerCosineSampleHemispherePDF(cosThetaH, self->ns) * rcp(4.0f * dot(wo, wh)); res.value = self->ks * powf(cosThetaH, self->ns); return res; } inline BSDF_SampleRes Specular_sample(const varying Specular *uniform self, const vec3f &wo, const vec2f &s, float) { BSDF_SampleRes res; const vec3f wh_local = powerCosineSampleHemisphere(self->ns, s); const vec3f wh = getFrame(&self->super) * wh_local; const float cosThetaOH = dot(wo, wh); res.wi = reflect(wo, wh, cosThetaOH); const float cosThetaI = dot(res.wi, getN(&self->super)); if (cosThetaI <= 0.0f) // below surface? return make_BSDF_SampleRes_zero(); const float cosThetaH = wh_local.z; res.pdf = powerCosineSampleHemispherePDF(cosThetaH, self->ns) * rcp(4.0f * cosThetaOH); res.type = BSDF_GLOSSY_REFLECTION; res.weight = self->weight * cosThetaOH; return res; } inline void Specular_Constructor(varying Specular *uniform self, const varying linear3f *uniform frame, vec3f R, float exp_) { BSDF_Constructor( &self->super, R, BSDF_GLOSSY_REFLECTION, BSDF_TYPE_SPECULAR, frame); // convert from Phong exponent to Blinn self->ns = exp_ * 4.f; const float tmp = (self->ns + 2.f) * rcp(2.f - exp(self->ns * -(float)lntwo_over_two)); self->ks = R * ((float)one_over_four_pi * tmp); self->weight = R * (2.f * tmp * rcp(self->ns + 1.f)); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/ThinDielectric.ih000066400000000000000000000050321464752671100253260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Dielectric.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Thin dielectric BSDF. // It represents a transparent slab with unit thickness, and ignores refraction. struct ThinDielectric { BSDF super; float eta; vec3f attenuation; }; inline BSDF_EvalRes ThinDielectric_eval( const varying BSDF *uniform, const vec3f &, const vec3f &) { return make_BSDF_EvalRes_zero(); } inline BSDF_SampleRes ThinDielectric_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &, float ss) { const varying ThinDielectric *uniform self = (const varying ThinDielectric *uniform)super; BSDF_SampleRes res; float cosThetaO = max(dot(wo, getN(super)), 0.f); // Fresnel term float cosThetaT; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaT, self->eta); res.pdf = inf; // Sample the reflection or the transmission bool doReflection = (ss <= F); if (doReflection) { // Reflection res.wi = reflect(wo, getN(super), cosThetaO); res.type = BSDF_SPECULAR_REFLECTION; res.weight = make_vec3f(1.f); } else { // Transmission // Attenuation for crossing the slab once float length = rcp(cosThetaT); vec3f A = expf(self->attenuation * length); res.wi = neg(wo); res.type = BSDF_SPECULAR_TRANSMISSION; res.weight = A; } return res; } inline void ThinDielectric_Constructor(varying ThinDielectric *uniform self, const varying linear3f *uniform frame, float eta, vec3f attenuation) { BSDF_Constructor(&self->super, expf(attenuation), BSDF_SPECULAR, BSDF_TYPE_THIN_DIELECTRIC, frame); self->eta = eta; self->attenuation = attenuation; } inline varying BSDF *uniform ThinDielectric_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, float eta, vec3f attenuation) { varying ThinDielectric *uniform self = (varying ThinDielectric * uniform) ShadingContext_alloc(ctx, sizeof(ThinDielectric)); ThinDielectric_Constructor(self, frame, eta, attenuation); return &self->super; } // Helper function for transparent shadow rays inline vec3f ThinDielectric_getTransparency( float cosThetaO, float eta, vec3f attenuation) { // Fresnel term float cosThetaT; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaT, eta); // Attenuation for crossing the slab once float length = rcp(cosThetaT); vec3f A = expf(attenuation * length); return (1.f - F) * A; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/ThinMicrofacetDielectric.ih000066400000000000000000000165501464752671100273320ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MicrofacetAlbedoTablesShared.h" #include "MicrofacetDielectric.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Thin microfacet dielectric BSDF with the Smith microsurface model. // It represents a transparent slab with unit thickness, and ignores refraction. // [Walter et al., 2007, "Microfacet Models for Refraction through Rough // Surfaces"] [Kulla and Conty, 2017, "Revisiting Physically Based Shading at // Imageworks"] [Jakob et al., 2014, "A Comprehensive Framework for Rendering // Layered Materials", Extended Technical Report] // FIXME: rough transmission struct ThinMicrofacetDielectric { BSDF super; float eta; vec3f attenuation; GGXDistribution microfacet; float roughness; const MicrofacetAlbedoTables *uniform microfacetAlbedoTables; // Energy compensation [Kulla and Conty, 2017] float Eavg; float fmsScale; }; inline BSDF_EvalRes ThinMicrofacetDielectric_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying ThinMicrofacetDielectric *uniform self = (const varying ThinMicrofacetDielectric *uniform)super; float cosThetaO = dot(wo, getN(super)); if (cosThetaO <= 0.f) return make_BSDF_EvalRes_zero(); float cosThetaI = dot(wi, getN(super)); bool isReflection = cosThetaI > 0.f; if (isReflection) { // Compute the microfacet normal vec3f wh = normalize(wo + wi); float cosThetaOH = dot(wo, wh); float cosThetaIH = dot(wi, wh); linear3f toLocal = transposed(getFrame(super)); vec3f wo0 = toLocal * wo; vec3f wi0 = toLocal * wi; vec3f wh0 = toLocal * wh; float F = fresnelDielectric(cosThetaOH, self->eta); float whPdf; float D = evalVisible(self->microfacet, wh0, wo0, cosThetaOH, whPdf); float G = evalG2(self->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); // Energy compensation float Eo = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->roughness); float Ei = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaI, self->roughness); float fms = self->fmsScale * ((1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->Eavg)) * cosThetaI); // Energy conservation float R = MicrofacetDielectricReflectionAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->eta, self->roughness) + self->fmsScale * (1.f - Eo); // add missing energy BSDF_EvalRes res; res.pdf = whPdf * rcp(4.f * cosThetaOH) * R; res.value = make_vec3f(F * D * G * rcp(4.f * cosThetaO) + fms); return res; } else { return make_BSDF_EvalRes_zero(); } } inline BSDF_SampleRes ThinMicrofacetDielectric_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying ThinMicrofacetDielectric *uniform self = (const varying ThinMicrofacetDielectric *uniform)super; BSDF_SampleRes res; float cosThetaO = dot(wo, getN(super)); if (cosThetaO <= 0.f) return make_BSDF_SampleRes_zero(); // Energy conservation float Eo = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->roughness); float R = MicrofacetDielectricReflectionAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaO, self->eta, self->roughness) + self->fmsScale * (1.f - Eo); // add missing energy if (ss < R) { // Reflection linear3f toGlobal = getFrame(super); linear3f toLocal = transposed(getFrame(super)); vec3f wo0 = toLocal * wo; // Sample the microfacet normal float whPdf; vec3f wh = toGlobal * sampleVisible(self->microfacet, wo0, whPdf, s); res.wi = reflect(wo, wh); float cosThetaI = dot(res.wi, getN(super)); if (cosThetaI <= 0.f) return make_BSDF_SampleRes_zero(); float cosThetaOH = dot(wo, wh); float cosThetaIH = dot(res.wi, wh); vec3f wi0 = toLocal * res.wi; float F = fresnelDielectric(cosThetaOH, self->eta); float G = evalG2(self->microfacet, wo0, wi0, cosThetaOH, cosThetaIH); // Energy compensation float Ei = MicrofacetAlbedoTable_eval( self->microfacetAlbedoTables, cosThetaI, self->roughness); float fms = self->fmsScale * ((1.f - Eo) * (1.f - Ei) * rcp((float)pi * (1.f - self->Eavg)) * cosThetaI); res.type = BSDF_GLOSSY_REFLECTION; res.pdf = whPdf * rcp(4.f * abs(cosThetaOH)) * R; res.weight = (make_vec3f(F * G * rcp_safe(evalG1(self->microfacet, wo0, cosThetaOH)) * rcp(R)) + (fms * rcp(res.pdf))); } else { // Transmission // Attenuation for crossing the slab once float length = rcp(refract(cosThetaO, self->eta)); // rcp(cosThetaO1) vec3f A = expf(self->attenuation * length); res.type = BSDF_SPECULAR_TRANSMISSION; res.wi = neg(wo); res.pdf = inf; res.weight = A; } return res; } inline void ThinMicrofacetDielectric_Constructor( varying ThinMicrofacetDielectric *uniform self, const MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, float eta, float roughness, float anisotropy, vec3f attenuation) { BSDF_Constructor(&self->super, expf(attenuation), BSDF_GLOSSY_REFLECTION | BSDF_SPECULAR_TRANSMISSION, BSDF_TYPE_THIN_MICROFACET_DIELECTRIC, frame); self->eta = eta; self->microfacet = make_GGXDistribution(roughnessToAlpha(roughness, anisotropy)); self->roughness = roughness; self->attenuation = attenuation; self->microfacetAlbedoTables = microfacetAlbedoTables; // Energy compensation self->Eavg = MicrofacetAlbedoTable_evalAvg(self->microfacetAlbedoTables, roughness); float Favg = fresnelDielectricAvg(eta); self->fmsScale = Favg * (1.f - self->Eavg) * rcp(1.f - Favg * self->Eavg); } inline varying BSDF *uniform ThinMicrofacetDielectric_create( uniform ShadingContext *uniform ctx, const MicrofacetAlbedoTables *uniform microfacetAlbedoTables, const varying linear3f *uniform frame, float eta, float roughness, float anisotropy, vec3f attenuation) { varying ThinMicrofacetDielectric *uniform self = (varying ThinMicrofacetDielectric * uniform) ShadingContext_alloc(ctx, sizeof(ThinMicrofacetDielectric)); ThinMicrofacetDielectric_Constructor(self, microfacetAlbedoTables, frame, eta, roughness, anisotropy, attenuation); return &self->super; } // Helper function for transparent shadow rays inline vec3f ThinMicrofacetDielectric_getTransparency( const MicrofacetAlbedoTables *uniform microfacetAlbedoTables, float cosThetaO, float eta, float roughness, vec3f attenuation) { // Energy conservation/compensation float Eavg = MicrofacetAlbedoTable_evalAvg(microfacetAlbedoTables, roughness); float Favg = fresnelDielectricAvg(eta); float fmsScale = Favg * (1.f - Eavg) * rcp(1.f - Favg * Eavg); float Eo = MicrofacetAlbedoTable_eval(microfacetAlbedoTables, cosThetaO, roughness); float R = MicrofacetDielectricReflectionAlbedoTable_eval( microfacetAlbedoTables, cosThetaO, eta, roughness) + fmsScale * (1.f - Eo); // add missing energy // Attenuation for crossing the slab once float length = rcp(refract(cosThetaO, eta)); // rcp(cosThetaO1) vec3f A = expf(attenuation * length); return (1.f - R) * A; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Transmission.ih000066400000000000000000000017431464752671100251320ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" #include "ShadingContext.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline BSDF_SampleRes Transmission_sample( const varying BSDF *uniform self, const vec3f &wo, const vec2f &, float) { BSDF_SampleRes res; res.wi = neg(wo); res.pdf = inf; res.type = BSDF_SPECULAR_TRANSMISSION; res.weight = self->albedo; return res; } inline void Transmission_Constructor( varying BSDF *uniform self, const varying linear3f *uniform frame, vec3f T) { BSDF_Constructor( self, T, BSDF_SPECULAR_TRANSMISSION, BSDF_TYPE_TRANSMISSION, frame); } inline varying BSDF *uniform Transmission_create( uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, vec3f T) { varying BSDF *uniform self = (varying BSDF * uniform) ShadingContext_alloc(ctx, sizeof(BSDF)); Transmission_Constructor(self, frame, T); return self; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/bsdfs/Velvety.ih000066400000000000000000000034541464752671100241000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "BSDF.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Velvety { BSDF super; /*! The falloff of horizon scattering. 0 no falloff, * and inf means maximum falloff. */ float f; }; inline BSDF_EvalRes Velvety_eval( const varying Velvety *uniform self, const vec3f &wo, const vec3f &wi) { BSDF_EvalRes res; const float cosThetaO = clamp(dot(wo, getN(&self->super))); const float cosThetaI = clamp(dot(wi, getN(&self->super))); const float sinThetaO = sqrt(1.0f - cosThetaO * cosThetaO); const float horizonScatter = pow(sinThetaO, self->f); res.pdf = cosineSampleHemispherePDF(cosThetaI); res.value = (horizonScatter * cosThetaI * (float)one_over_pi) * self->super.albedo; return res; } inline BSDF_SampleRes Velvety_sample( const varying Velvety *uniform self, const vec3f &wo, const vec2f &s, float) { BSDF_SampleRes res; const vec3f localDir = cosineSampleHemisphere(s); res.wi = getFrame(&self->super) * localDir; res.type = BSDF_DIFFUSE_REFLECTION; BSDF_EvalRes eval = Velvety_eval(self, wo, res.wi); res.pdf = eval.pdf; res.weight = eval.value * rcp(eval.pdf); return res; } inline void Velvety_Constructor(varying Velvety *uniform self, const varying linear3f *uniform frame, vec3f R, float f) { BSDF_Constructor( &self->super, R, BSDF_DIFFUSE_REFLECTION, BSDF_TYPE_VELVETY, frame); self->f = f; } inline varying BSDF *uniform Velvety_create(uniform ShadingContext *uniform ctx, const varying linear3f *uniform frame, vec3f R, float f) { varying Velvety *uniform self = (varying Velvety * uniform) ShadingContext_alloc(ctx, sizeof(Velvety)); Velvety_Constructor(self, frame, R, f); return &self->super; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/debug/000077500000000000000000000000001464752671100220775ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/debug/DebugRenderer.cpp000066400000000000000000000057471464752671100253350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "DebugRenderer.h" #include "camera/Camera.h" #include "common/DeviceRT.h" #include "common/FeatureFlagsEnum.h" #include "common/World.h" #include "fb/FrameBuffer.h" // Kernel launcher is defined in another compilation unit DECLARE_RENDERER_KERNEL_LAUNCHER(DebugRenderer_renderTaskLauncher); namespace ospray { // Helper functions ///////////////////////////////////////////////////////// static ispc::DebugRendererType typeFromString(const std::string &name) { if (name == "rayDir") return ispc::DebugRendererType::RAY_DIR; else if (name == "eyeLight") return ispc::DebugRendererType::EYE_LIGHT; else if (name == "Ng") return ispc::DebugRendererType::NG; else if (name == "Ns") return ispc::DebugRendererType::NS; else if (name == "color") return ispc::DebugRendererType::COLOR; else if (name == "texCoord") return ispc::DebugRendererType::TEX_COORD; else if (name == "backfacing_Ng") return ispc::DebugRendererType::BACKFACING_NG; else if (name == "backfacing_Ns") return ispc::DebugRendererType::BACKFACING_NS; else if (name == "dPds") return ispc::DebugRendererType::DPDS; else if (name == "dPdt") return ispc::DebugRendererType::DPDT; else if (name == "primID") return ispc::DebugRendererType::PRIM_ID; else if (name == "geomID") return ispc::DebugRendererType::GEOM_ID; else if (name == "instID") return ispc::DebugRendererType::INST_ID; else if (name == "volume") return ispc::DebugRendererType::VOLUME; else return ispc::DebugRendererType::TEST_FRAME; } // DebugRenderer definitions //////////////////////////////////////////////// DebugRenderer::DebugRenderer(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) {} std::string DebugRenderer::toString() const { return "ospray::DebugRenderer"; } void DebugRenderer::commit() { Renderer::commit(); const std::string method = getParam("method", "eyeLight"); getSh()->type = typeFromString(method); } devicert::AsyncEvent DebugRenderer::renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *, const utility::ArrayView &taskIDs) const { // Gather feature flags from all components FeatureFlags ff = world->getFeatureFlags(); ff |= featureFlags; ff |= fb->getFeatureFlags(); ff |= camera->getFeatureFlags(); // Prepare parameters for kernel launch auto *rendererSh = &getSh()->super; auto *fbSh = fb->getSh(); auto *cameraSh = camera->getSh(); auto *worldSh = world->getSh(); const size_t numTasks = taskIDs.size(); const vec2i taskSize = fb->getRenderTaskSize(); const vec3ui itemDims = vec3ui(taskSize.x, taskSize.y, numTasks); // Launch rendering kernel on the device return drtDevice.launchRendererKernel(itemDims, ispc::DebugRenderer_renderTaskLauncher, rendererSh, fbSh, cameraSh, worldSh, taskIDs.data(), ff); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/debug/DebugRenderer.h000066400000000000000000000012621464752671100247660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "common/StructShared.h" #include "render/Renderer.h" // ispc shared #include "DebugRendererShared.h" namespace ospray { struct DebugRenderer : public AddStructShared { DebugRenderer(api::ISPCDevice &device); virtual ~DebugRenderer() override = default; std::string toString() const override; void commit() override; virtual devicert::AsyncEvent renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *perFrameData, const utility::ArrayView &taskIDs) const override; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/debug/DebugRenderer.ispc000066400000000000000000000304141464752671100254760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/DeviceRT.ih" #include "common/FeatureFlagsEnum.h" #include "common/Intersect.ih" #include "common/World.ih" #include "fb/FrameBuffer.ih" #include "fb/FrameBufferDispatch.ih" #include "fb/RenderTaskDesc.ih" #include "math/random.ih" #include "pf/PixelFilterDispatch.ih" #include "render/Renderer.ih" #include "render/ScreenSample.ih" #include "rkcommon/utility/random.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/VolumetricModel.ih" #include "volume/transferFunction/TransferFunctionDispatch.ih" #endif // c++ shared #include "DebugRendererShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // common utility function, traces ray and handles default and background inline bool hitBackground(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { traceRay(world, sample.ray, ffh); sample.z = sample.ray.t; sample.alpha = 1.f; sample.rgb = make_vec3f(Renderer_getBackground(self, sample.pos, ffh)); return noHit(sample.ray); } inline float eyeLight(varying ScreenSample &sample) { 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 returns a well-defined test frame (mostly useful for debugging whether frame buffers are properly set up etcpp */ static void DebugRenderer_testFrame( Renderer *uniform, World *uniform, varying ScreenSample &sample) { sample.rgb.x = ((sample.sampleID.x) % 256) / 255.f; sample.rgb.y = ((sample.sampleID.y) % 256) / 255.f; sample.rgb.z = ((sample.sampleID.x + sample.sampleID.y + sample.sampleID.z) % 256) / 255.f; sample.alpha = 1.f; sample.z = 1.f; } /* a simple test-frame renderer that doesn't even trace a ray, just returns the absolute of the ray direction */ static void DebugRenderer_rayDir( Renderer *uniform, World *uniform, varying ScreenSample &sample) { sample.rgb = absf(sample.ray.dir); sample.alpha = 1.f; sample.z = 1.f; } static void DebugRenderer_eyeLight(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) { return; } sample.rgb = make_vec3f(eyeLight(sample)); } static void DebugRenderer_Ng(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect( world, self, dg, sample.ray, sample.rayCone, DG_NORMALIZE | DG_NG, ffh); sample.rgb = absf(dg.Ng); } static void DebugRenderer_Ns(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect( world, self, dg, sample.ray, sample.rayCone, DG_NORMALIZE | DG_NS, ffh); sample.rgb = absf(dg.Ns); } static void DebugRenderer_texCoord(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect(world, self, dg, sample.ray, sample.rayCone, DG_TEXCOORD, ffh); sample.rgb = abs(make_vec3f(dg.st.x, dg.st.y, 0.0f)); } static void DebugRenderer_dPds(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect(world, self, dg, sample.ray, sample.rayCone, DG_TANGENTS, ffh); sample.rgb = normalize(dg.dPds); if (sample.rgb.x < 0.f) sample.rgb.x = sample.rgb.x * -0.3f; if (sample.rgb.y < 0.f) sample.rgb.y = sample.rgb.y * -0.3f; if (sample.rgb.z < 0.f) sample.rgb.z = sample.rgb.z * -0.3f; } static void DebugRenderer_dPdt(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect(world, self, dg, sample.ray, sample.rayCone, DG_TANGENTS, ffh); sample.rgb = normalize(dg.dPdt); if (sample.rgb.x < 0.f) sample.rgb.x = sample.rgb.x * -0.3f; if (sample.rgb.y < 0.f) sample.rgb.y = sample.rgb.y * -0.3f; if (sample.rgb.z < 0.f) sample.rgb.z = sample.rgb.z * -0.3f; } static void DebugRenderer_vertexColor(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect( world, self, dg, sample.ray, sample.rayCone, DG_COLOR | DG_NS, ffh); sample.rgb = make_vec3f(dg.color) * abs(dot(normalize(sample.ray.dir), normalize(dg.Ns))); } static void DebugRenderer_primID(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; sample.rgb = eyeLight(sample) * makeRandomColor(sample.ray.primID); } static void DebugRenderer_instID(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; sample.rgb = eyeLight(sample) * makeRandomColor(sample.ray.instID); } static void DebugRenderer_geomID(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; sample.rgb = eyeLight(sample) * makeRandomColor(sample.ray.geomID); } static void DebugRenderer_backfacing_Ng(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; sample.rgb = make_vec3f(eyeLight(sample)); if (dot(sample.ray.Ng, sample.ray.dir) > 0.f) sample.rgb.y = 0.f; } static void DebugRenderer_backfacing_Ns(Renderer *uniform self, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { if (hitBackground(self, world, sample, ffh)) return; DifferentialGeometry dg; postIntersect( world, self, dg, sample.ray, sample.rayCone, DG_NORMALIZE | DG_NS, ffh); const float c = dot(dg.Ns, sample.ray.dir); sample.rgb = make_vec3f(.2f + .8f * abs(c)); if (c > 0.f) sample.rgb.y = 0.f; } static void DebugRenderer_volume(Renderer *uniform self, FrameBuffer *uniform fb, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { #ifdef OSPRAY_ENABLE_VOLUMES const uniform FeatureFlags ff = getFeatureFlags(ffh); if (!(ff.other & FFO_VOLUME_IN_SCENE)) { return; } RandomSampler randomSampler; RandomSampler_init(&randomSampler, sample.sampleID.x + fb->size.x * sample.sampleID.y, sample.sampleID.z); vec3f &color = sample.rgb; float &alpha = sample.alpha; vec4f bgColor = Renderer_getBackground(self, sample.pos, ffh); color = make_vec3f(bgColor); alpha = bgColor.w; VolumeInterval vInterval; traceVolumeRay(world, sample.ray, vInterval); if (!hasInterval(vInterval)) { return; } VolumetricModel *varying model = vInterval.volumetricModel; Ray &ray = sample.ray; ray.t0 = vInterval.interval.lower; ray.t = vInterval.interval.upper; const float jitter = RandomSampler_getFloat(&randomSampler); uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; foreach_unique (m in model) { Volume *uniform volume = m->volume; float time = 0.5f; VKLIntervalIterator intervalIterator = vklInitIntervalIteratorV(&m->vklIntervalContext, (varying vkl_vec3f *)&ray.org, (varying vkl_vec3f *)&ray.dir, (varying vkl_range1f *)&vInterval.interval, #ifndef OSPRAY_TARGET_SYCL & #endif time, (void *uniform)intervalIteratorBuffer #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ); VKLInterval interval; static const uniform float samplingRate = 0.5f; while (vklIterateIntervalV(intervalIterator, &interval #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ) && alpha < 0.99f) { const float nominalSamplingDt = interval.nominalDeltaT / samplingRate; // initial sub interval, based on our renderer-defined sampling rate // and the volume's nominal dt box1f subInterval = make_box1f(interval.tRange.lower, min(interval.tRange.lower + nominalSamplingDt, interval.tRange.upper)); while (subInterval.upper - subInterval.lower > 0.f && alpha < 0.99f) { ray.t0 = subInterval.lower + jitter * (subInterval.upper - subInterval.lower); const float dt = subInterval.upper - subInterval.lower; // Get volume sample vec3f p = ray.org + ray.t0 * ray.dir; const float sample = vklComputeSampleV(&volume->vklSampler, (const varying vkl_vec3f *uniform) & p #ifdef OSPRAY_TARGET_SYCL , 0, time, ff.volume #endif ); if (!isnan(sample)) { vec4f sampleColorOpacity = TransferFunction_dispatch_get(m->transferFunction, sample); const float clampedOpacity = clamp(sampleColorOpacity.w * dt); color = color + ((1.f - alpha) * clampedOpacity * make_vec3f(sampleColorOpacity)); alpha = alpha + ((1.f - alpha) * clampedOpacity); } // compute next sub interval subInterval.lower = subInterval.upper; subInterval.upper = min(subInterval.lower + nominalSamplingDt, interval.tRange.upper); } } } #else (void)self; (void)fb; (void)world; (void)sample; (void)ffh; #endif } static void DebugRenderer_renderSample(Renderer *uniform _self, FrameBuffer *uniform fb, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { DebugRenderer *uniform self = (DebugRenderer * uniform) _self; const DebugRendererType debugType = self->type; switch (debugType) { case TEST_FRAME: DebugRenderer_testFrame(_self, world, sample); break; case RAY_DIR: DebugRenderer_rayDir(_self, world, sample); break; case EYE_LIGHT: DebugRenderer_eyeLight(_self, world, sample, ffh); break; case NG: DebugRenderer_Ng(_self, world, sample, ffh); break; case NS: DebugRenderer_Ns(_self, world, sample, ffh); break; case COLOR: DebugRenderer_vertexColor(_self, world, sample, ffh); break; case TEX_COORD: DebugRenderer_texCoord(_self, world, sample, ffh); break; case DPDS: DebugRenderer_dPds(_self, world, sample, ffh); break; case DPDT: DebugRenderer_dPdt(_self, world, sample, ffh); break; case PRIM_ID: DebugRenderer_primID(_self, world, sample, ffh); break; case GEOM_ID: DebugRenderer_geomID(_self, world, sample, ffh); break; case INST_ID: DebugRenderer_instID(_self, world, sample, ffh); break; case BACKFACING_NG: DebugRenderer_backfacing_Ng(_self, world, sample, ffh); break; case BACKFACING_NS: DebugRenderer_backfacing_Ns(_self, world, sample, ffh); break; case VOLUME: DebugRenderer_volume(_self, fb, world, sample, ffh); break; default: DebugRenderer_testFrame(_self, world, sample); break; }; } #define renderSampleFn DebugRenderer_renderSample #include "render/RendererRenderTaskFn.inl" #undef renderSampleFn inline void DebugRenderer_renderTask(const uniform vec3ui itemIndex, Renderer *uniform self, FrameBuffer *uniform fb, Camera *uniform camera, World *uniform world, const uint32 *uniform taskIDs, const uniform FeatureFlagsHandler &ffh) { Renderer_default_renderTask(itemIndex, self, fb, camera, world, taskIDs, ffh); } DEFINE_RENDERER_KERNEL_LAUNCHER(DebugRenderer_renderTask); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/debug/DebugRendererShared.h000066400000000000000000000010401464752671100261070ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/RendererShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus enum DebugRendererType { TEST_FRAME, RAY_DIR, EYE_LIGHT, NG, NS, COLOR, TEX_COORD, DPDS, DPDT, PRIM_ID, GEOM_ID, INST_ID, BACKFACING_NG, BACKFACING_NS, VOLUME }; struct DebugRenderer { Renderer super; DebugRendererType type; #ifdef __cplusplus DebugRenderer() : type(TEST_FRAME) {} #endif }; #ifdef __cplusplus } #endif RenderKit-ospray-85af292/modules/cpu/render/materials/000077500000000000000000000000001464752671100227725ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/materials/Alloy.cpp000066400000000000000000000020571464752671100245620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Alloy.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Alloy_ispc.h" #endif namespace ospray { namespace pathtracer { Alloy::Alloy(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_ALLOY) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast(ispc::Alloy_getBSDF_addr()); #endif } std::string Alloy::toString() const { return "ospray::pathtracer::Alloy"; } //! \brief commit the material's parameters void Alloy::commit() { color = getMaterialParam3f("color", vec3f(0.9f)); edgeColor = getMaterialParam3f("edgeColor", vec3f(1.f)); roughness = getMaterialParam1f("roughness", 0.1f); getSh()->color = color.factor; getSh()->colorMap = color.tex; getSh()->edgeColor = edgeColor.factor; getSh()->edgeColorMap = edgeColor.tex; getSh()->roughness = roughness.factor; getSh()->roughnessMap = roughness.tex; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Alloy.h000066400000000000000000000010051464752671100242170ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "AlloyShared.h" namespace ospray { namespace pathtracer { struct Alloy : public AddStructShared { Alloy(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; private: MaterialParam3f color; MaterialParam3f edgeColor; MaterialParam1f roughness; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Alloy.ih000066400000000000000000000017471464752671100244050ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Alloy_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes AlloyRough_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes AlloyRough_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); SYCL_EXTERNAL BSDF_SampleRes Alloy_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Alloy.ispc000066400000000000000000000046111464752671100247340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Alloy.ih" #include "render/Material.ih" #include "render/bsdfs/Conductor.ih" #include "render/bsdfs/MicrofacetConductor.ih" #include "texture/TextureParam.ih" // c++ shared #include "AlloyShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL const varying BSDF *uniform Alloy_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { const uniform Alloy *uniform self = (const uniform Alloy *uniform)super; varying linear3f *uniform shadingframe = LinearSpace3f_create(ctx, frame(dg.Ns)); const vec3f color = self->color * make_vec3f(dg.color) * get3f(self->colorMap, dg, make_vec3f(1.f)); const vec3f edgeColor = self->edgeColor * get3f(self->edgeColorMap, dg, make_vec3f(1.f)); Fresnel *uniform fresnel = FresnelSchlick_create(ctx, color, edgeColor); varying BSDF *uniform bsdf; if (self->roughness == 0.0f) { bsdf = Conductor_create(ctx, shadingframe, fresnel); bsdf->bsdfType = BSDF_TYPE_ALLOY; } else { bsdf = MicrofacetConductor_create(ctx, super->microfacetAlbedoTables, shadingframe, fresnel, self->roughness * get1f(self->roughnessMap, dg, 1.f), 0.f); bsdf->bsdfType = BSDF_TYPE_ALLOY_ROUGH; } return bsdf; } SYCL_EXTERNAL BSDF_EvalRes AlloyRough_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { return MicrofacetConductor_eval( (const varying MicrofacetConductor *uniform)super, wo, wi); } SYCL_EXTERNAL BSDF_SampleRes AlloyRough_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return MicrofacetConductor_sample( (const varying MicrofacetConductor *uniform)super, wo, s, ss); } SYCL_EXTERNAL BSDF_SampleRes Alloy_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return Conductor_sample(super, wo, s, ss); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Alloy_getBSDF_addr() { return (void *uniform)Alloy_getBSDF; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/AlloyShared.h000066400000000000000000000012771464752671100253610ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Alloy { Material super; vec3f color; // reflectivity at normal incidence (0 deg) TextureParam colorMap; vec3f edgeColor; // reflectivity at grazing angle (90 deg) TextureParam edgeColorMap; float roughness; // in [0, 1]; 0==ideally smooth (mirror) TextureParam roughnessMap; #ifdef __cplusplus Alloy() : color(.9f), edgeColor(1.f), roughness(.1f) { super.type = ispc::MATERIAL_TYPE_ALLOY; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/CarPaint.cpp000066400000000000000000000063361464752671100252070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "CarPaint.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/CarPaint_ispc.h" #endif namespace ospray { namespace pathtracer { CarPaint::CarPaint(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_CARPAINT) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast( ispc::CarPaint_getBSDF_addr()); #endif } std::string CarPaint::toString() const { return "ospray::pathtracer::CarPaint"; } void CarPaint::commit() { baseColor = getMaterialParam3f("baseColor", vec3f(0.8f)); roughness = getMaterialParam1f("roughness", 0.f); normal = getMaterialParam1f("normal", 1.f); bool useFlakeColor = findParam("flakeColor") != nullptr; flakeColor = getMaterialParam3f("flakeColor", vec3f(0.f)); flakeScale = getMaterialParam1f("flakeScale", 100.f); flakeDensity = getMaterialParam1f("flakeDensity", 0.f); flakeSpread = getMaterialParam1f("flakeSpread", 0.3f); flakeJitter = getMaterialParam1f("flakeJitter", 0.75f); flakeRoughness = getMaterialParam1f("flakeRoughness", 0.3f); coat = getMaterialParam1f("coat", 1.f); coatIor = getMaterialParam1f("coatIor", 1.5f); coatColor = getMaterialParam3f("coatColor", vec3f(1.f)); coatThickness = getMaterialParam1f("coatThickness", 1.f); coatRoughness = getMaterialParam1f("coatRoughness", 0.f); coatNormal = getMaterialParam1f("coatNormal", 1.f); flipflopColor = getMaterialParam3f("flipflopColor", vec3f(1.f)); flipflopFalloff = getMaterialParam1f("flipflopFalloff", 1.f); getSh()->baseColor = baseColor.factor; getSh()->baseColorMap = baseColor.tex; getSh()->roughness = roughness.factor; getSh()->roughnessMap = roughness.tex; getSh()->normal = normal.factor; getSh()->normalMap = normal.tex; getSh()->normalRot = normal.rot; getSh()->useFlakeColor = useFlakeColor; getSh()->flakeColor = flakeColor.factor; getSh()->flakeColorMap = flakeColor.tex; getSh()->flakeScale = flakeScale.factor; getSh()->flakeScaleMap = flakeScale.tex; getSh()->flakeDensity = flakeDensity.factor; getSh()->flakeDensityMap = flakeDensity.tex; getSh()->flakeSpread = flakeSpread.factor; getSh()->flakeSpreadMap = flakeSpread.tex; getSh()->flakeJitter = flakeJitter.factor; getSh()->flakeJitterMap = flakeJitter.tex; getSh()->flakeRoughness = flakeRoughness.factor; getSh()->flakeRoughnessMap = flakeRoughness.tex; getSh()->coat = coat.factor; getSh()->coatMap = coat.tex; getSh()->coatIor = coatIor.factor; getSh()->coatIorMap = coatIor.tex; getSh()->coatColor = coatColor.factor; getSh()->coatColorMap = coatColor.tex; getSh()->coatThickness = coatThickness.factor; getSh()->coatThicknessMap = coatThickness.tex; getSh()->coatRoughness = coatRoughness.factor; getSh()->coatRoughnessMap = coatRoughness.tex; getSh()->coatNormal = coatNormal.factor; getSh()->coatNormalMap = coatNormal.tex; getSh()->coatNormalRot = coatNormal.rot; getSh()->flipflopColor = flipflopColor.factor; getSh()->flipflopColorMap = flipflopColor.tex; getSh()->flipflopFalloff = flipflopFalloff.factor; getSh()->flipflopFalloffMap = flipflopFalloff.tex; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/CarPaint.h000066400000000000000000000017021464752671100246440ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "CarPaintShared.h" namespace ospray { namespace pathtracer { struct CarPaint : public AddStructShared { CarPaint(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; private: MaterialParam3f baseColor; MaterialParam1f roughness; MaterialParam1f normal; MaterialParam3f flakeColor; MaterialParam1f flakeScale; MaterialParam1f flakeDensity; MaterialParam1f flakeSpread; MaterialParam1f flakeJitter; MaterialParam1f flakeRoughness; MaterialParam1f coat; MaterialParam1f coatIor; MaterialParam3f coatColor; MaterialParam1f coatThickness; MaterialParam1f coatRoughness; MaterialParam1f coatNormal; MaterialParam3f flipflopColor; MaterialParam1f flipflopFalloff; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/CarPaint.ih000066400000000000000000000015261464752671100250210ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform CarPaint_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes CarPaint_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes CarPaint_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/CarPaint.ispc000066400000000000000000000265621464752671100253660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "CarPaint.ih" #include "common/Ray.ih" #include "render/Material.ih" #include "render/bsdfs/Conductor.ih" #include "render/bsdfs/DielectricLayer.ih" #include "render/bsdfs/Lambert.ih" #include "render/bsdfs/MicrofacetConductor.ih" #include "render/bsdfs/MicrofacetDielectricLayer.ih" #include "render/bsdfs/OrenNayar.ih" #include "render/bsdfs/PassthroughLayer.ih" #include "render/shaders/Flakes.ih" #include "texture/TextureParam.ih" // c++ shared #include "CarPaintShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE struct CarPaint_BSDF { BSDF root; MicrofacetDielectricLayer dielectricLayer; int flakeMask; MicrofacetConductor conductor; OrenNayar baseDiffuse; }; SYCL_EXTERNAL const varying BSDF *uniform CarPaint_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium &, const uniform FeatureFlagsHandler &) { const uniform CarPaint *uniform self = (const uniform CarPaint *uniform)super; varying linear3f *uniform frame = LinearSpace3f_create(ctx, makeShadingFrame(dg, self->normalMap, self->normalRot, self->normal)); // Allocate memory and initialize material BSDF varying CarPaint_BSDF *uniform bsdf = (varying CarPaint_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(CarPaint_BSDF)); const float flakeDensity = clamp(self->flakeDensity * get1f(self->flakeDensityMap, dg, 1.f)); int flakeMask = 0; varying linear3f *uniform flakeFrame = NULL; varying BSDF *varying substrate = NULL; // metallic flakes in the clear coat layer if (flakeDensity > EPS) { const float flakeScale = max(self->flakeScale * get1f(self->flakeScaleMap, dg, 1.f), 0.f); const float flakeSpread = max(self->flakeSpread * get1f(self->flakeSpreadMap, dg, 1.f), 0.f); const float flakeJitter = clamp(self->flakeJitter * get1f(self->flakeJitterMap, dg, 1.f)); Flakes flakes; flakes.scale = flakeScale; flakes.density = flakeDensity; flakes.spread = flakeSpread; flakes.jitter = flakeJitter; const vec3f flakeN = Flakes_eval(flakes, dg.P, flakeMask); if (flakeMask) { flakeFrame = LinearSpace3f_create(ctx, makeShadingFrame(dg, flakeN)); Fresnel *uniform flakeFresnel; if (self->useFlakeColor) { const vec3f r = clamp( self->flakeColor * get3f(self->flakeColorMap, dg, make_vec3f(1.f))); const vec3f g = make_vec3f(1.f); flakeFresnel = FresnelSchlick_create(ctx, r, g); } else { // flakes are made of aluminum const uniform vec3f flakeEta = make_vec3f(1.69700277f, 0.879832864f, 0.5301736f); const uniform vec3f flakeK = make_vec3f(9.30200672f, 6.27604008f, 4.89433956f); flakeFresnel = FresnelConductorRGBUniform_create(ctx, flakeEta, flakeK); } if (self->flakeRoughness < EPS) Conductor_Constructor((varying Conductor * uniform) & bsdf->conductor, flakeFrame, flakeFresnel); else MicrofacetConductor_Constructor(&bsdf->conductor, super->microfacetAlbedoTables, flakeFrame, flakeFresnel, max(self->flakeRoughness * get1f(self->flakeRoughnessMap, dg, 1.f), 0.f), 0.f); substrate = &bsdf->conductor.super; } } // base diffuse layer if (!flakeMask) { const vec3f baseColor = clamp(self->baseColor * get3f(self->baseColorMap, dg, make_vec3f(1.f)) * make_vec3f(dg.color)); if (self->roughness < EPS) Lambert_Constructor( (varying BSDF * uniform) & bsdf->baseDiffuse, frame, baseColor); else OrenNayar_Constructor(&bsdf->baseDiffuse, frame, baseColor, max(self->roughness * get1f(self->roughnessMap, dg, 1.f), 0.f)); substrate = &bsdf->baseDiffuse.super; } bsdf->flakeMask = flakeMask; // clear coat layer if ((self->coat > EPS) && (abs(self->coatIor - 1.f) > EPS || valid(self->coatIorMap))) { const float coat = max(self->coat * get1f(self->coatMap, dg, 1.f), 0.f); float coatIor = self->coatIor * get1f(self->coatIorMap, dg, 1.f); if (coatIor < 1.f) coatIor = rcp(coatIor); coatIor = clamp(coatIor, 1.f, 3.f); // clamp to common range due to LUTs // compute the final coat color const vec3f coatColor = clamp(self->coatColor * get3f(self->coatColorMap, dg, make_vec3f(1.f))); vec3f coatFinalColor = coatColor; if (flakeMask) { const float flipflopFalloff = clamp( self->flipflopFalloff * get1f(self->flipflopFalloffMap, dg, 1.f)); if (flipflopFalloff < 1.f - EPS) { // pearlescent flakes const vec3f flipflopColor = clamp(self->flipflopColor * get3f(self->flipflopColorMap, dg, make_vec3f(1.f))); const float cosThetaO = max(-dot(ray.dir, flakeFrame->vz), 0.f); const float weight = pow(1.f - cosThetaO, rcp(1.f - flipflopFalloff)); // use Schlick for the blending weight coatFinalColor = lerp(weight, coatColor, flipflopColor); } } const float coatThickness = max(self->coatThickness * get1f(self->coatThicknessMap, dg, 1.f), 0.f); varying linear3f *uniform coatFrame = LinearSpace3f_create(ctx, makeShadingFrame( dg, self->coatNormalMap, self->coatNormalRot, self->coatNormal)); if (self->coatRoughness < EPS) { DielectricLayer_Constructor( (varying DielectricLayer * uniform) & bsdf->dielectricLayer, coatFrame, substrate, rcp(coatIor), coatFinalColor, coatThickness, coat); } else { MicrofacetDielectricLayer_Constructor(&bsdf->dielectricLayer, super->microfacetAlbedoTables, coatFrame, substrate, rcp(coatIor), coatFinalColor, coatThickness, max(self->coatRoughness * get1f(self->coatRoughnessMap, dg, 1.f), 0.f), 0.f, coat); } } else { PassthroughLayer_Constructor( (varying PassthroughLayer * uniform) & bsdf->dielectricLayer, substrate); } bsdf->root = bsdf->dielectricLayer.super; bsdf->root.bsdfType = BSDF_TYPE_CARPAINT; return &bsdf->root; } // Conductor BSDF inline BSDF_EvalRes ConductorBSDF_eval( const varying MicrofacetConductor *uniform self, const vec3f &wo, const vec3f &wi) { if (self->super.bsdfType == BSDF_TYPE_MICROFACET_CONDUCTOR) return MicrofacetConductor_eval(self, wo, wi); else return make_BSDF_EvalRes_zero(); } inline BSDF_SampleRes ConductorBSDF_sample( const varying MicrofacetConductor *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->super.bsdfType == BSDF_TYPE_MICROFACET_CONDUCTOR) return MicrofacetConductor_sample(self, wo, s, ss); else return Conductor_sample(&self->super, wo, s, ss); } // Diffuse BSDF inline BSDF_EvalRes DiffuseBSDF_eval( const varying OrenNayar *uniform self, const vec3f &wo, const vec3f &wi) { if (self->super.bsdfType == BSDF_TYPE_OREN_NAYAR) return OrenNayar_eval(&self->super, wo, wi); else return Lambert_eval(&self->super, wo, wi); } inline BSDF_SampleRes DiffuseBSDF_sample(const varying OrenNayar *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->super.bsdfType == BSDF_TYPE_OREN_NAYAR) return OrenNayar_sample(&self->super, wo, s, ss); else return Lambert_sample(&self->super, wo, s, ss); } // Base layer BSDF __noinline BSDF_EvalRes BaseBSDF_eval( const varying CarPaint_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { if (self->flakeMask) { return ConductorBSDF_eval(&self->conductor, wo, wi); } else { return DiffuseBSDF_eval(&self->baseDiffuse, wo, wi); } } __noinline BSDF_SampleRes BaseBSDF_sample( const varying CarPaint_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->flakeMask) { return ConductorBSDF_sample(&self->conductor, wo, s, ss); } else { return DiffuseBSDF_sample(&self->baseDiffuse, wo, s, ss); } } // DielectricLayer BSDF inline BSDF_EvalRes DielectricLayerBSDF_eval( const varying CarPaint_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { BSDFScatteringType scatteringType = (self->flakeMask) ? self->conductor.super.scatteringType : self->baseDiffuse.super.scatteringType; DIELECTRICLAYER_EVAL( self->dielectricLayer, scatteringType, self, BaseBSDF_eval); return DIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes DielectricLayerBSDF_sample( const varying CarPaint_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { BSDFScatteringType scatteringType = (self->flakeMask) ? self->conductor.super.scatteringType : self->baseDiffuse.super.scatteringType; DIELECTRICLAYER_SAMPLE( self->dielectricLayer, scatteringType, self, BaseBSDF_sample); return DIELECTRICLAYER_SAMPLE_GET(); } // MicrofacetDielectricLayer BSDF inline BSDF_EvalRes MicrofacetDielectricLayerBSDF_eval( const varying CarPaint_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { BSDFScatteringType scatteringType = (self->flakeMask) ? self->conductor.super.scatteringType : self->baseDiffuse.super.scatteringType; MICROFACETDIELECTRICLAYER_EVAL( self->dielectricLayer, scatteringType, self, BaseBSDF_eval); return MICROFACETDIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes MicrofacetDielectricLayerBSDF_sample( const varying CarPaint_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { BSDFScatteringType scatteringType = (self->flakeMask) ? self->conductor.super.scatteringType : self->baseDiffuse.super.scatteringType; MICROFACETDIELECTRICLAYER_SAMPLE(self->dielectricLayer, scatteringType, self, BaseBSDF_eval, BaseBSDF_sample); return MICROFACETDIELECTRICLAYER_SAMPLE_GET(); } // CarPaint BSDF SYCL_EXTERNAL BSDF_EvalRes CarPaint_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying CarPaint_BSDF *uniform self = (const varying CarPaint_BSDF *uniform)super; // Skip dielectric layer if no clear coat if (self->dielectricLayer.weight < EPS) return BaseBSDF_eval(self, wo, wi); if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return MicrofacetDielectricLayerBSDF_eval(self, wo, wi); else return DielectricLayerBSDF_eval(self, wo, wi); } SYCL_EXTERNAL BSDF_SampleRes CarPaint_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying CarPaint_BSDF *uniform self = (const varying CarPaint_BSDF *uniform)super; // Skip dielectric layer if no clear coat if (self->dielectricLayer.weight < EPS) return BaseBSDF_sample(self, wo, s, ss); if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return MicrofacetDielectricLayerBSDF_sample(self, wo, s, ss); else return DielectricLayerBSDF_sample(self, wo, s, ss); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform CarPaint_getBSDF_addr() { return (void *uniform)CarPaint_getBSDF; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/CarPaintShared.h000066400000000000000000000037541464752671100260040ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct CarPaint { Material super; vec3f baseColor; TextureParam baseColorMap; float roughness; TextureParam roughnessMap; float normal; // scale TextureParam normalMap; linear2f normalRot; bool useFlakeColor; // if disabled, flakes are Aluminium vec3f flakeColor; TextureParam flakeColorMap; float flakeScale; TextureParam flakeScaleMap; float flakeDensity; TextureParam flakeDensityMap; float flakeSpread; TextureParam flakeSpreadMap; float flakeJitter; TextureParam flakeJitterMap; float flakeRoughness; TextureParam flakeRoughnessMap; // dielectric clear coat reflectivity in [0, 1] float coat; TextureParam coatMap; // dielectric clear coat index of refraction in [1, 3] float coatIor; TextureParam coatIorMap; float coatThickness; TextureParam coatThicknessMap; float coatRoughness; TextureParam coatRoughnessMap; float coatNormal; // scale TextureParam coatNormalMap; linear2f coatNormalRot; vec3f coatColor; TextureParam coatColorMap; vec3f flipflopColor; TextureParam flipflopColorMap; float flipflopFalloff; TextureParam flipflopFalloffMap; #ifdef __cplusplus CarPaint() : baseColor(0.8f), roughness(0.f), normal(1.f), normalRot(one), useFlakeColor(false), flakeColor(0.f), flakeScale(0.f), flakeDensity(0.f), flakeSpread(0.f), flakeJitter(0.f), flakeRoughness(0.f), coat(1.f), coatIor(1.5f), coatThickness(1.f), coatRoughness(0.f), coatNormal(1.f), coatNormalRot(one), coatColor(1.f), flipflopColor(1.f), flipflopFalloff(1.f) { super.type = ispc::MATERIAL_TYPE_CARPAINT; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Glass.cpp000066400000000000000000000037661464752671100245630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Glass.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Glass_ispc.h" #endif namespace ospray { namespace pathtracer { Glass::Glass(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_GLASS) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast(ispc::Glass_getBSDF_addr()); getSh()->super.getTransparency = reinterpret_cast( ispc::Glass_getTransparency_addr()); getSh()->super.selectNextMedium = reinterpret_cast( ispc::Glass_selectNextMedium_addr()); #endif } std::string Glass::toString() const { return "ospray::pathtracer::Glass"; } void Glass::commit() { const float etaInside = getParam("etaInside", getParam("eta", 1.5f)); const float etaOutside = getParam("etaOutside", 1.f); const vec3f &attenuationColorInside = getParam("attenuationColorInside", getParam("attenuationColor", vec3f(1.f))); const vec3f &attenuationColorOutside = getParam("attenuationColorOutside", vec3f(1.f)); const float attenuationDistance = getParam("attenuationDistance", 1.0f); getSh()->mediumInside.ior = etaInside; getSh()->mediumInside.attenuation = vec3f(log(attenuationColorInside.x), log(attenuationColorInside.y), log(attenuationColorInside.z)) / std::max(attenuationDistance, EPS); getSh()->mediumOutside.ior = etaOutside; getSh()->mediumOutside.attenuation = vec3f(log(attenuationColorOutside.x), log(attenuationColorOutside.y), log(attenuationColorOutside.z)) / std::max(attenuationDistance, EPS); } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Glass.h000066400000000000000000000006471464752671100242230ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "GlassShared.h" namespace ospray { namespace pathtracer { struct Glass : public AddStructShared { Glass(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Glass.ih000066400000000000000000000021001464752671100243560ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Glass_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f Glass_getTransparency(const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL void Glass_selectNextMedium(const uniform Material *uniform super, const DifferentialGeometry &dg, Medium ¤tMedium); SYCL_EXTERNAL BSDF_SampleRes Glass_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Glass.ispc000066400000000000000000000050531464752671100247260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Glass.ih" #include "Medium.ih" #include "common/Ray.ih" #include "render/Material.ih" #include "render/bsdfs/RobustDielectric.ih" // c++ shared #include "GlassShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL const varying BSDF *uniform Glass_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium ¤tMedium, const uniform FeatureFlagsHandler &) { uniform const Glass *uniform self = (uniform const Glass *uniform)super; float eta = eq(currentMedium, self->mediumOutside) ? self->mediumOutside.ior * rcp(self->mediumInside.ior) : self->mediumInside.ior * rcp(self->mediumOutside.ior); varying BSDF *uniform bsdf = RobustDielectric_create(ctx, dg, eta); bsdf->bsdfType = BSDF_TYPE_GLASS; return bsdf; } SYCL_EXTERNAL vec3f Glass_getTransparency( const uniform Material *uniform material, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &) { const uniform Glass *uniform self = (const uniform Glass *uniform)material; float eta = eq(currentMedium, self->mediumOutside) ? self->mediumOutside.ior * rcp(self->mediumInside.ior) : self->mediumInside.ior * rcp(self->mediumOutside.ior); float cosThetaO = max(-dot(ray.dir, dg.Ns), 0.0f); return make_vec3f(1.0f - fresnelDielectric(cosThetaO, eta)); } SYCL_EXTERNAL void Glass_selectNextMedium(const uniform Material *uniform super, const DifferentialGeometry &, Medium ¤tMedium) { const uniform Glass *uniform self = (const uniform Glass *uniform)super; if (eq(currentMedium, self->mediumOutside)) currentMedium = self->mediumInside; else currentMedium = self->mediumOutside; } SYCL_EXTERNAL BSDF_SampleRes Glass_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return RobustDielectric_sample(super, wo, s, ss); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Glass_getBSDF_addr() { return (void *uniform)Glass_getBSDF; } export void *uniform Glass_getTransparency_addr() { return (void *uniform)Glass_getTransparency; } export void *uniform Glass_selectNextMedium_addr() { return (void *uniform)Glass_selectNextMedium; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/GlassShared.h000066400000000000000000000006741464752671100253520ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MediumShared.h" #include "render/MaterialShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Glass { Material super; Medium mediumInside; Medium mediumOutside; #ifdef __cplusplus Glass() { super.type = ispc::MATERIAL_TYPE_GLASS; } #endif }; #ifdef __cplusplus } // namespace ispc #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Luminous.cpp000066400000000000000000000024301464752671100253100ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Luminous.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Luminous_ispc.h" #endif namespace ospray { namespace pathtracer { Luminous::Luminous(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_LUMINOUS) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast( ispc::Luminous_getBSDF_addr()); getSh()->super.getTransparency = reinterpret_cast( ispc::Luminous_getTransparency_addr()); getSh()->super.getEmission = reinterpret_cast( ispc::Luminous_getEmission_addr()); #endif } std::string Luminous::toString() const { return "ospray::pathtracer::Luminous"; } void Luminous::commit() { emissiveColor = getMaterialParam3f("color", vec3f(1.f)); const vec3f radiance = emissiveColor.factor * getParam("intensity", 1.f); const float transparency = getParam("transparency", 0.f); getSh()->radiance = radiance; getSh()->emissionMap = emissiveColor.tex; getSh()->transparency = transparency; getSh()->super.isEmissive = isEmissive(); } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Luminous.h000066400000000000000000000011501464752671100247530ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "LuminousShared.h" namespace ospray { namespace pathtracer { struct Luminous : public AddStructShared { Luminous(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; virtual bool isEmissive() const override; private: MaterialParam3f emissiveColor; }; inline bool Luminous::isEmissive() const { return reduce_max(getSh()->radiance) > 0.f; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Luminous.ih000066400000000000000000000021361464752671100251310ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Luminous_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f Luminous_getTransparency( const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_SampleRes Luminous_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); SYCL_EXTERNAL vec3f Luminous_getEmission(const Material *uniform super, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Luminous.ispc000066400000000000000000000041761464752671100254750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Luminous.ih" #include "render/Material.ih" #include "render/bsdfs/Transmission.ih" // c++ shared #include "LuminousShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL const varying BSDF *uniform Luminous_getBSDF( const uniform Material *uniform _self, uniform ShadingContext *uniform ctx, const DifferentialGeometry &, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { uniform Luminous *uniform self = (uniform Luminous * uniform) _self; varying BSDF *uniform bsdf = NULL; if (self->transparency > 0.0f) { vec3f T = make_vec3f(self->transparency); bsdf = Transmission_create(ctx, NULL /*no frame needed*/, T); bsdf->bsdfType = BSDF_TYPE_LUMINOUS; } return bsdf; } SYCL_EXTERNAL vec3f Luminous_getTransparency( const uniform Material *uniform _self, const DifferentialGeometry &, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { uniform Luminous *uniform self = (uniform Luminous * uniform) _self; return make_vec3f(self->transparency); } SYCL_EXTERNAL BSDF_SampleRes Luminous_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return Transmission_sample(super, wo, s, ss); } SYCL_EXTERNAL vec3f Luminous_getEmission(const Material *uniform _self, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &) { const Luminous *uniform self = (Luminous * uniform) _self; return make_vec3f(self->radiance) * get3f(self->emissionMap, dg, make_vec3f(1.f)); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Luminous_getBSDF_addr() { return (void *uniform)Luminous_getBSDF; } export void *uniform Luminous_getTransparency_addr() { return (void *uniform)Luminous_getTransparency; } export void *uniform Luminous_getEmission_addr() { return (void *uniform)Luminous_getEmission; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/LuminousShared.h000066400000000000000000000007341464752671100261110ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Luminous { Material super; float transparency; vec3f radiance; TextureParam emissionMap; #ifdef __cplusplus Luminous() : super(), transparency(0.f), radiance(1.f) { super.type = ispc::MATERIAL_TYPE_LUMINOUS; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Medium.ih000066400000000000000000000015011464752671100245310ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" #include "MediumShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline Medium make_Medium(const vec3f attenuation, const float ior) { Medium m; m.attenuation = attenuation; m.ior = ior; return m; } inline Medium make_Medium_vacuum() { return make_Medium(make_vec3f(0.0f), 1.0f); } inline bool eq(const Medium &a, const Medium &b) { return (a.ior == b.ior) & eq(a.attenuation, b.attenuation); } #ifdef ISPC inline bool eq(const Medium &a, const uniform Medium &b) { return (a.ior == b.ior) & eq(a.attenuation, b.attenuation); } inline uniform bool eq(const uniform Medium &a, const uniform Medium &b) { return (a.ior == b.ior) & eq(a.attenuation, b.attenuation); } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/MediumShared.h000066400000000000000000000007031464752671100255120ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Medium { vec3f attenuation; //!< negative Napierian attenuation coefficient, // i.e. wrt. the natural base e float ior; //!< Refraction index of medium. #ifdef __cplusplus Medium() : attenuation(0.f), ior(1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Metal.cpp000066400000000000000000000035571464752671100245520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Metal.h" #include "common/Data.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Metal_ispc.h" #endif namespace ospray { namespace pathtracer { Metal::Metal(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_METAL) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast(ispc::Metal_getBSDF_addr()); #endif } std::string Metal::toString() const { return "ospray::pathtracer::Metal"; } void Metal::commit() { auto ior = getParamDataT("ior"); const vec3f &eta = getParam("eta", vec3f(RGB_AL_ETA)); const vec3f &k = getParam("k", vec3f(RGB_AL_K)); roughness = getMaterialParam1f("roughness", 0.1f); if (ior) { // resample, relies on ordered samples spectrum etaResampled; spectrum kResampled; auto iorP = ior->begin(); auto iorPrev = *iorP; const auto iorLast = ior->end(); float wl = SPECTRUM_FIRSTWL; for (int l = 0; l < SPECTRUM_SAMPLES; wl += SPECTRUM_SPACING, l++) { for (; iorP != iorLast && iorP->x < wl; iorP++) iorPrev = *iorP; if (iorP->x == iorPrev.x) { etaResampled[l] = iorPrev.y; kResampled[l] = iorPrev.z; } else { auto f = (wl - iorPrev.x) / (iorP->x - iorPrev.x); etaResampled[l] = (1.f - f) * iorPrev.y + f * iorP->y; kResampled[l] = (1.f - f) * iorPrev.z + f * iorP->z; } } getSh()->spectral = true; getSh()->eta = etaResampled; getSh()->k = kResampled; } else { // default to Aluminium, used when ior not given getSh()->spectral = false; getSh()->etaRGB = eta; getSh()->kRGB = k; } getSh()->roughness = roughness.factor; getSh()->roughnessMap = roughness.tex; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Metal.h000066400000000000000000000007521464752671100242110ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "math/spectrum.h" #include "render/Material.h" // ispc shared #include "MetalShared.h" namespace ospray { namespace pathtracer { struct Metal : public AddStructShared { Metal(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; private: MaterialParam1f roughness; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Metal.ih000066400000000000000000000017471464752671100243670ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Metal_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes MetalRough_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes MetalRough_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); SYCL_EXTERNAL BSDF_SampleRes Metal_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Metal.ispc000066400000000000000000000045311464752671100247170ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Metal.ih" #include "math/spectrum.ih" #include "render/Material.ih" #include "render/bsdfs/Conductor.ih" #include "render/bsdfs/MicrofacetConductor.ih" #include "texture/TextureParam.ih" // c++ shared #include "MetalShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL const varying BSDF *uniform Metal_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { const uniform Metal *uniform self = (const uniform Metal *uniform)super; varying linear3f *uniform shadingframe = LinearSpace3f_create(ctx, frame(dg.Ns)); Fresnel *uniform fresnel; if (self->spectral) fresnel = FresnelConductorSpectral_create(ctx, self->eta, self->k); else fresnel = FresnelConductorRGBUniform_create(ctx, self->etaRGB, self->kRGB); varying BSDF *uniform bsdf; if (self->roughness == 0.0f) { bsdf = Conductor_create(ctx, shadingframe, fresnel); bsdf->bsdfType = BSDF_TYPE_METAL; } else { bsdf = MicrofacetConductor_create(ctx, super->microfacetAlbedoTables, shadingframe, fresnel, self->roughness * get1f(self->roughnessMap, dg, 1.f), 0.f); bsdf->bsdfType = BSDF_TYPE_METAL_ROUGH; } return bsdf; } SYCL_EXTERNAL BSDF_EvalRes MetalRough_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { return MicrofacetConductor_eval( (const varying MicrofacetConductor *uniform)super, wo, wi); } SYCL_EXTERNAL BSDF_SampleRes MetalRough_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return MicrofacetConductor_sample( (const varying MicrofacetConductor *uniform)super, wo, s, ss); } SYCL_EXTERNAL BSDF_SampleRes Metal_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return Conductor_sample(super, wo, s, ss); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Metal_getBSDF_addr() { return (void *uniform)Metal_getBSDF; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/MetalShared.h000066400000000000000000000016041464752671100253350ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus #include "math/spectrum.h" #else #include "math/spectrum.ih" #endif #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Metal { Material super; bool spectral; spectrum eta; // index of refraction spectrum k; // index of refraction, imaginary part vec3f etaRGB; // index of refraction vec3f kRGB; // index of refraction, imaginary part float roughness; // in [0, 1]; 0==ideally smooth (mirror) TextureParam roughnessMap; #ifdef __cplusplus Metal() : spectral(false), eta{}, k{}, etaRGB(RGB_AL_ETA), kRGB(RGB_AL_K), roughness(.1f) { super.type = ispc::MATERIAL_TYPE_METAL; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/MetallicPaint.cpp000066400000000000000000000023711464752671100262270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "MetallicPaint.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/MetallicPaint_ispc.h" #endif namespace ospray { namespace pathtracer { MetallicPaint::MetallicPaint(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_METALLICPAINT) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast( ispc::MetallicPaint_getBSDF_addr()); #endif } std::string MetallicPaint::toString() const { return "ospray::pathtracer::MetallicPaint"; } void MetallicPaint::commit() { color = getMaterialParam3f("baseColor", vec3f(0.8f)); const float flakeAmount = getParam("flakeAmount", 0.3f); const vec3f &flakeColor = getParam("flakeColor", vec3f(RGB_AL_COLOR)); const float flakeSpread = getParam("flakeSpread", 0.5f); const float eta = getParam("eta", 1.5f); getSh()->baseColor = color.factor * (1.f - flakeAmount); getSh()->baseColorMap = color.tex; getSh()->flakeAmount = flakeAmount; getSh()->flakeColor = flakeColor * flakeAmount; getSh()->flakeSpread = flakeSpread; getSh()->eta = rcp(eta); } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/MetallicPaint.h000066400000000000000000000010061464752671100256660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "math/spectrum.h" #include "render/Material.h" // ispc shared #include "MetallicPaintShared.h" namespace ospray { namespace pathtracer { struct MetallicPaint : public AddStructShared { MetallicPaint(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; private: MaterialParam3f color; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/MetallicPaint.ih000066400000000000000000000015451464752671100260470ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform MetallicPaint_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes MetallicPaint_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes MetallicPaint_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/MetallicPaint.ispc000066400000000000000000000112361464752671100264030ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "MetallicPaint.ih" #include "render/Material.ih" #include "render/bsdfs/DielectricLayer.ih" #include "render/bsdfs/Lambert.ih" #include "render/bsdfs/MicrofacetConductor.ih" #include "render/bsdfs/MultiBSDF.ih" #include "texture/TextureParam.ih" // c++ shared #include "MetallicPaintShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE struct MetallicPaint_MultiBSDF { DEFINE_MULTIBSDF(2); BSDF lambert; MicrofacetConductor microfacetConductor; }; struct MetallicPaint_BSDF { DielectricLayer dielectricLayer; MetallicPaint_MultiBSDF multi; }; SYCL_EXTERNAL const varying BSDF *uniform MetallicPaint_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { const uniform MetallicPaint *uniform self = (const uniform MetallicPaint *uniform)super; varying LinearSpace3f *uniform shadingFrame = LinearSpace3f_create(ctx, frame(dg.Ns)); // Allocate memory and initialize material BSDF varying MetallicPaint_BSDF *uniform bsdf = (varying MetallicPaint_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(MetallicPaint_BSDF)); varying MultiBSDF *uniform bsdfMulti = (varying MultiBSDF * uniform) & bsdf->multi; MultiBSDF_Constructor(bsdfMulti, 2); const vec3f color = self->baseColor * make_vec3f(dg.color) * get3f(self->baseColorMap, dg, make_vec3f(1.f)); Lambert_Constructor(&bsdf->multi.lambert, shadingFrame, color); MultiBSDF_add(bsdfMulti, 0, &bsdf->multi.lambert, 1.f, luminance(color)); if (self->flakeAmount > 0.f) { const vec3f r = self->flakeColor; const vec3f g = make_vec3f(self->flakeAmount); Fresnel *uniform fresnel = FresnelSchlick_create(ctx, r, g); MicrofacetConductor_Constructor(&bsdf->multi.microfacetConductor, super->microfacetAlbedoTables, shadingFrame, fresnel, self->flakeSpread, 0.f); MultiBSDF_add(bsdfMulti, 1, (varying BSDF * uniform) & bsdf->multi.microfacetConductor, 1.f, luminance(r)); } DielectricLayer_Constructor(&bsdf->dielectricLayer, shadingFrame, &bsdf->multi.super, self->eta, make_vec3f(1.0f), 1.0f, 1.0f); bsdf->dielectricLayer.super.bsdfType = BSDF_TYPE_METALLICPAINT; return &bsdf->dielectricLayer.super; } inline BSDF_EvalRes MultiBSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying MetallicPaint_MultiBSDF *uniform self = (const varying MetallicPaint_MultiBSDF *uniform)super; MULTIBSDF_EVAL_BEGIN(); MULTIBSDF_EVAL_CHILD(0, &self->lambert, Lambert_eval); MULTIBSDF_EVAL_CHILD(1, &self->microfacetConductor, MicrofacetConductor_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } inline BSDF_SampleRes MultiBSDF_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying MetallicPaint_MultiBSDF *uniform self = (const varying MetallicPaint_MultiBSDF *uniform)super; MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, &self->lambert, Lambert_sample); MULTIBSDF_SAMPLE_CHILD( 1, &self->microfacetConductor, MicrofacetConductor_sample); MULTIBSDF_SAMPLE_EVAL(); MULTIBSDF_EVAL_CHILD(0, &self->lambert, Lambert_eval); MULTIBSDF_EVAL_CHILD(1, &self->microfacetConductor, MicrofacetConductor_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } SYCL_EXTERNAL BSDF_EvalRes MetallicPaint_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying MetallicPaint_BSDF *uniform self = (const varying MetallicPaint_BSDF *uniform)super; DIELECTRICLAYER_EVAL(self->dielectricLayer, self->multi.super.scatteringType, &self->multi.super, MultiBSDF_eval); return DIELECTRICLAYER_EVAL_GET(); } SYCL_EXTERNAL BSDF_SampleRes MetallicPaint_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying MetallicPaint_BSDF *uniform self = (const varying MetallicPaint_BSDF *uniform)super; DIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->multi.super.scatteringType, &self->multi.super, MultiBSDF_sample); return DIELECTRICLAYER_SAMPLE_GET(); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform MetallicPaint_getBSDF_addr() { return (void *uniform)MetallicPaint_getBSDF; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/MetallicPaintShared.h000066400000000000000000000012731464752671100270230ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct MetallicPaint { Material super; vec3f baseColor; TextureParam baseColorMap; float flakeAmount; vec3f flakeColor; float flakeSpread; float eta; #ifdef __cplusplus MetallicPaint() : baseColor(.25f), flakeAmount(.5f), flakeColor(flakeAmount * vec3f(RGB_AL_COLOR)), flakeSpread(0.5f), eta(1.f / 1.6f) { super.type = ispc::MATERIAL_TYPE_METALLICPAINT; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Mix.cpp000066400000000000000000000023741464752671100242410ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Mix.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Mix_ispc.h" #endif namespace ospray { namespace pathtracer { MixMaterial::MixMaterial(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_MIX) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast(ispc::Mix_getBSDF_addr()); getSh()->super.getTransparency = reinterpret_cast( ispc::Mix_getTransparency_addr()); getSh()->super.getEmission = reinterpret_cast( ispc::Mix_getEmission_addr()); #endif } std::string MixMaterial::toString() const { return "ospray::pathtracer::MixMaterial"; } void MixMaterial::commit() { factor = getMaterialParam1f("factor", .5f); mat1 = getParamObject("material1"); mat2 = getParamObject("material2"); getSh()->factor = clamp(factor.factor); getSh()->factorMap = factor.tex; getSh()->mat1 = mat1 ? mat1->getSh() : nullptr; getSh()->mat2 = mat2 ? mat2->getSh() : nullptr; getSh()->super.isEmissive = isEmissive(); } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Mix.h000066400000000000000000000012361464752671100237020ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "MixShared.h" namespace ospray { namespace pathtracer { struct MixMaterial : public AddStructShared { MixMaterial(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; virtual bool isEmissive() const override; protected: Ref mat1; Ref mat2; private: MaterialParam1f factor; }; inline bool MixMaterial::isEmissive() const { return mat1->isEmissive() || mat2->isEmissive(); } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Mix.ih000066400000000000000000000023301464752671100240470ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" #ifndef OSPRAY_TARGET_SYCL OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Mix_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f Mix_getTransparency(const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f Mix_getEmission(const Material *uniform super, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes Mix_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes Mix_BSDF_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE #endifRenderKit-ospray-85af292/modules/cpu/render/materials/Mix.ispc000066400000000000000000000112761464752671100244160ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Mix.ih" #include "common/FeatureFlags.ih" #include "render/Material.ih" #include "render/MaterialDispatch.ih" #include "render/bsdfs/MultiBSDF.ih" #include "texture/TextureParam.ih" // c++ shared #include "MixShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation #ifndef OSPRAY_TARGET_SYCL OSPRAY_BEGIN_ISPC_NAMESPACE #define MULTIBSDF_SIZE 2 struct Mix_BSDF { DEFINE_MULTIBSDF(MULTIBSDF_SIZE); const varying BSDF *uniform bsdf1; const varying BSDF *uniform bsdf2; }; SYCL_EXTERNAL const varying BSDF *uniform Mix_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh) { const Mix *uniform self = (const Mix *uniform)super; // Allocate memory and initialize material BSDF varying Mix_BSDF *uniform bsdf = (varying Mix_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(Mix_BSDF)); varying MultiBSDF *uniform mbsdf = (varying MultiBSDF * uniform) bsdf; MultiBSDF_Constructor(mbsdf, MULTIBSDF_SIZE); bsdf->super.bsdfType = BSDF_TYPE_MIX; bsdf->bsdf1 = NULL; bsdf->bsdf2 = NULL; float factor = self->factor * clamp(get1f(self->factorMap, dg, 1.f)); if (self->mat1) { bsdf->bsdf1 = self->mat1->getBSDF(self->mat1, ctx, dg, ray, currentMedium, ffh); if (bsdf->bsdf1) MultiBSDF_add(mbsdf, 0, bsdf->bsdf1, 1.0f - factor, 1.0f - factor); } if (self->mat2) { bsdf->bsdf2 = self->mat2->getBSDF(self->mat2, ctx, dg, ray, currentMedium, ffh); if (bsdf->bsdf2) MultiBSDF_add(mbsdf, 1, bsdf->bsdf2, factor, factor); } return &bsdf->super; } SYCL_EXTERNAL vec3f Mix_getTransparency(const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh) { const Mix *uniform self = (const Mix *uniform)super; vec3f t1 = make_vec3f(0.f); if (self->mat1) t1 = self->mat1->getTransparency(self->mat1, dg, ray, currentMedium, ffh); vec3f t2 = make_vec3f(0.f); if (self->mat2) t2 = self->mat2->getTransparency(self->mat2, dg, ray, currentMedium, ffh); float factor = self->factor * clamp(get1f(self->factorMap, dg, 1.f)); return lerp(factor, t1, t2); } SYCL_EXTERNAL vec3f Mix_getEmission(const Material *uniform super, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { const Mix *uniform self = (const Mix *uniform)super; vec3f t1 = make_vec3f(0.f); if (self->mat1) t1 = self->mat1->getEmission(self->mat1, dg, ffh); vec3f t2 = make_vec3f(0.f); if (self->mat2) t2 = self->mat2->getEmission(self->mat2, dg, ffh); float factor = self->factor * clamp(get1f(self->factorMap, dg, 1.f)); return lerp(factor, t1, t2); } inline BSDF_EvalRes BSDF_dispatch_eval( const varying BSDF *uniform self, const vec3f &wo, const vec3f &wi) { uniform FeatureFlagsHandler ffh; return BSDF_dispatch_eval(self, wo, wi, ffh); } inline BSDF_SampleRes BSDF_dispatch_sample( const varying BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { uniform FeatureFlagsHandler ffh; return BSDF_dispatch_sample(self, wo, s, ss, ffh); } SYCL_EXTERNAL BSDF_EvalRes Mix_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying Mix_BSDF *uniform self = (const varying Mix_BSDF *uniform)super; MULTIBSDF_EVAL_BEGIN(); MULTIBSDF_EVAL_CHILD(0, self->bsdf1, BSDF_dispatch_eval); MULTIBSDF_EVAL_CHILD(1, self->bsdf2, BSDF_dispatch_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } SYCL_EXTERNAL BSDF_SampleRes Mix_BSDF_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying Mix_BSDF *uniform self = (const varying Mix_BSDF *uniform)super; MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, self->bsdf1, BSDF_dispatch_sample); MULTIBSDF_SAMPLE_CHILD(1, self->bsdf2, BSDF_dispatch_sample); MULTIBSDF_SAMPLE_EVAL(); MULTIBSDF_EVAL_CHILD(0, self->bsdf1, BSDF_dispatch_eval); MULTIBSDF_EVAL_CHILD(1, self->bsdf2, BSDF_dispatch_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Mix_getBSDF_addr() { return (void *uniform)Mix_getBSDF; } export void *uniform Mix_getTransparency_addr() { return (void *uniform)Mix_getTransparency; } export void *uniform Mix_getEmission_addr() { return (void *uniform)Mix_getEmission; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/materials/MixShared.h000066400000000000000000000007771464752671100250420ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Mix { Material super; float factor; TextureParam factorMap; Material *mat1; Material *mat2; #ifdef __cplusplus Mix() : factor(.5f), mat1(nullptr), mat2(nullptr) { super.type = ispc::MATERIAL_TYPE_MIX; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/OBJ.cpp000066400000000000000000000035761464752671100241230ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "OBJ.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/OBJ_ispc.h" #endif namespace ospray { namespace pathtracer { OBJMaterial::OBJMaterial(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_OBJ) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast(ispc::OBJ_getBSDF_addr()); getSh()->super.getTransparency = reinterpret_cast( ispc::OBJ_getTransparency_addr()); #endif } std::string OBJMaterial::toString() const { return "ospray::pathtracer::obj"; } void OBJMaterial::commit() { d = getMaterialParam1f("d", 1.f); Kd = getMaterialParam3f("kd", vec3f(0.8f)); Ks = getMaterialParam3f("ks", vec3f(0.f)); Ns = getMaterialParam1f("ns", 10.f); vec3f Tf = getParam("tf", vec3f(0.f)); ref_bumpTex = getParamObject("map_bump"); ispc::TextureParam bumpTex = getTextureParam("map_bump", ref_bumpTex); linear2f bumpRot = ((linear2f *)(&bumpTex.xform2f.l))->orthogonal().transposed(); const float color_total = reduce_max(Kd.factor + Ks.factor + Tf); if (color_total > 1.f) { postStatusMsg(OSP_LOG_DEBUG) << "#osp:PT OBJ material produces energy " << "(kd + ks + tf = " << color_total << ", should be <= 1). Scaling down to 1."; Kd.factor /= color_total; Ks.factor /= color_total; Tf /= color_total; } getSh()->dMap = d.tex; getSh()->d = d.factor; getSh()->KdMap = Kd.tex; getSh()->Kd = Kd.factor; getSh()->KsMap = Ks.tex; getSh()->Ks = Ks.factor; getSh()->NsMap = Ns.tex; getSh()->Ns = Ns.factor; getSh()->Tf = Tf; getSh()->bumpMap = bumpTex; getSh()->bumpRot = bumpRot; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/OBJ.h000066400000000000000000000010561464752671100235570ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "OBJShared.h" namespace ospray { namespace pathtracer { struct OBJMaterial : public AddStructShared { OBJMaterial(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; private: Ref ref_bumpTex; MaterialParam1f d; MaterialParam3f Kd; MaterialParam3f Ks; MaterialParam1f Ns; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/OBJ.ih000066400000000000000000000020721464752671100237270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform OBJ_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f OBJ_getTransparency(const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes OBJ_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes OBJ_BSDF_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/OBJ.ispc000066400000000000000000000114651464752671100242730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "OBJ.ih" #include "render/Material.ih" #include "render/bsdfs/Lambert.ih" #include "render/bsdfs/MultiBSDF.ih" #include "render/bsdfs/Specular.ih" #include "render/bsdfs/Transmission.ih" #include "texture/TextureParam.ih" // c++ shared #include "OBJShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE #define MULTIBSDF_SIZE 3 struct OBJ_BSDF { DEFINE_MULTIBSDF(MULTIBSDF_SIZE); BSDF lambert; BSDF transmission; Specular specular; }; SYCL_EXTERNAL const varying BSDF *uniform OBJ_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &ffh) { uniform const OBJ *uniform self = (uniform const OBJ *uniform)super; // Allocate memory and initialize material BSDF varying OBJ_BSDF *uniform bsdf = (varying OBJ_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(OBJ_BSDF)); varying MultiBSDF *uniform mbsdf = (varying MultiBSDF * uniform) bsdf; MultiBSDF_Constructor(mbsdf, MULTIBSDF_SIZE); bsdf->super.bsdfType = BSDF_TYPE_OBJ; // textures modify (mul) values, see http://paulbourke.net/dataformats/mtl/ // Normal map varying linear3f *uniform shadingFrame = LinearSpace3f_create( ctx, makeShadingFrame_ff(dg, self->bumpMap, self->bumpRot, ffh)); /*! cut-out opacity */ float d = self->d * get1f_ff(self->dMap, dg, 1.f, ffh) * dg.color.w; const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); // Diffuse component vec3f Kd = self->Kd; if (valid(self->KdMap) && (ffo & FFO_TEXTURE_IN_MATERIAL)) { vec4f Kd_from_map = get4f(self->KdMap, dg); Kd = Kd * make_vec3f(Kd_from_map); d *= Kd_from_map.w; } // Lambert shading Kd = Kd * d * make_vec3f(dg.color); if (reduce_max(Kd) > 0.0f) { Lambert_Constructor(&bsdf->lambert, shadingFrame, Kd); MultiBSDF_add(mbsdf, 0, &bsdf->lambert, 1.f, luminance(Kd)); } // Transmission component vec3f T = self->Tf * d + make_vec3f(1.f - d); if (reduce_max(T) > 0.0f) { Transmission_Constructor(&bsdf->transmission, shadingFrame, T); MultiBSDF_add(mbsdf, 1, &bsdf->transmission, 1.f, luminance(T)); } /*! specular component */ float Ns = self->Ns * get1f_ff(self->NsMap, dg, 1.0f, ffh); vec3f Ks = d * self->Ks * get3f_ff(self->KsMap, dg, make_vec3f(1.f), ffh); if (reduce_max(Ks) > 0.0f) { Specular_Constructor(&bsdf->specular, shadingFrame, Ks, Ns); MultiBSDF_add(mbsdf, 2, (varying BSDF * uniform) & bsdf->specular, 1.f, luminance(Ks)); } return &bsdf->super; } SYCL_EXTERNAL vec3f OBJ_getTransparency(const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &ffh) { uniform const OBJ *uniform self = (uniform const OBJ *uniform)super; const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); /*! cut-out opacity */ float d = self->d * get1f_ff(self->dMap, dg, 1.f, ffh) * dg.color.w; if (hasAlpha(self->KdMap) && (ffo & FFO_TEXTURE_IN_MATERIAL)) { vec4f Kd_from_map = get4f(self->KdMap, dg); d *= Kd_from_map.w; } // Transmission component vec3f T = self->Tf * d + make_vec3f(1.f - d); return T; } SYCL_EXTERNAL BSDF_EvalRes OBJ_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying OBJ_BSDF *uniform self = (const varying OBJ_BSDF *uniform)super; MULTIBSDF_EVAL_BEGIN(); MULTIBSDF_EVAL_CHILD(0, &self->lambert, Lambert_eval); // 1 - omitted, no evaluation needed for transmission BSDF MULTIBSDF_EVAL_CHILD(2, &self->specular, Specular_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } SYCL_EXTERNAL BSDF_SampleRes OBJ_BSDF_sample(const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying OBJ_BSDF *uniform self = (const varying OBJ_BSDF *uniform)super; MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, &self->lambert, Lambert_sample); MULTIBSDF_SAMPLE_CHILD(1, &self->transmission, Transmission_sample); MULTIBSDF_SAMPLE_CHILD(2, &self->specular, Specular_sample); MULTIBSDF_SAMPLE_EVAL(); MULTIBSDF_EVAL_CHILD(0, &self->lambert, Lambert_eval); // 1 - omitted, no evaluation needed for transmission BSDF MULTIBSDF_EVAL_CHILD(2, &self->specular, Specular_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform OBJ_getBSDF_addr() { return (void *uniform)OBJ_getBSDF; } export void *uniform OBJ_getTransparency_addr() { return (void *uniform)OBJ_getTransparency; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/OBJShared.h000066400000000000000000000014111464752671100247010ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct OBJ { Material super; float d; // cut-out opacity TextureParam dMap; vec3f Kd; TextureParam KdMap; vec3f Ks; TextureParam KsMap; float Ns; TextureParam NsMap; vec3f Tf; // transmission filter TextureParam bumpMap; linear2f bumpRot; // just the inverse of rotational/mirror part (must be // orthonormal) of tc xfrom #ifdef __cplusplus OBJ() : d(1.f), Kd(.8f), Ks(0.f), Ns(2.f), Tf(0.f), bumpRot(one) { super.type = MATERIAL_TYPE_OBJ; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Plastic.cpp000066400000000000000000000016541464752671100251030ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Plastic.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Plastic_ispc.h" #endif namespace ospray { namespace pathtracer { Plastic::Plastic(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_PLASTIC) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast( ispc::Plastic_getBSDF_addr()); #endif } std::string Plastic::toString() const { return "ospray::pathtracer::Plastic"; } void Plastic::commit() { const vec3f pigmentColor = getParam("pigmentColor", vec3f(1.f)); const float eta = getParam("eta", 1.4f); const float roughness = getParam("roughness", 0.01f); getSh()->pigmentColor = pigmentColor; getSh()->eta = rcp(eta); getSh()->roughness = roughness; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Plastic.h000066400000000000000000000006571464752671100245520ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "PlasticShared.h" namespace ospray { namespace pathtracer { struct Plastic : public AddStructShared { Plastic(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Plastic.ih000066400000000000000000000015231464752671100247140ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Plastic_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes Plastic_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes Plastic_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Plastic.ispc000066400000000000000000000105141464752671100252520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Plastic.ih" #include "render/Material.ih" #include "render/bsdfs/DielectricLayer.ih" #include "render/bsdfs/Lambert.ih" #include "render/bsdfs/MicrofacetDielectricLayer.ih" // c++ shared #include "PlasticShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE struct Plastic_BSDF { BSDF root; MicrofacetDielectricLayer dielectricLayer; BSDF lambert; }; SYCL_EXTERNAL const varying BSDF *uniform Plastic_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { const uniform Plastic *uniform self = (const uniform Plastic *uniform)super; varying LinearSpace3f *uniform shadingFrame = LinearSpace3f_create(ctx, frame(dg.Ns)); // Allocate memory and initialize material BSDF varying Plastic_BSDF *uniform bsdf = (varying Plastic_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(Plastic_BSDF)); const vec3f _pigmentColor = self->pigmentColor; Lambert_Constructor(&bsdf->lambert, shadingFrame, _pigmentColor); if (self->roughness == 0.0f) { DielectricLayer_Constructor( (varying DielectricLayer * uniform) & bsdf->dielectricLayer, shadingFrame, &bsdf->lambert, self->eta, make_vec3f(1.0f), 1.0f, 1.0f); } else { MicrofacetDielectricLayer_Constructor(&bsdf->dielectricLayer, super->microfacetAlbedoTables, shadingFrame, &bsdf->lambert, self->eta, make_vec3f(1.0f), 1.0f, self->roughness, 0.f, 1.0f); } bsdf->root = bsdf->dielectricLayer.super; bsdf->root.bsdfType = BSDF_TYPE_PLASTIC; return &bsdf->root; } // DielectricLayer BSDF inline BSDF_EvalRes DielectricLayerBSDF_eval( const varying Plastic_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { DIELECTRICLAYER_EVAL(self->dielectricLayer, self->lambert.scatteringType, &self->lambert, Lambert_eval); return DIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes DielectricLayerBSDF_sample( const varying Plastic_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { DIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->lambert.scatteringType, &self->lambert, Lambert_sample); return DIELECTRICLAYER_SAMPLE_GET(); } // MicrofacetDielectricLayer BSDF inline BSDF_EvalRes MicrofacetDielectricLayerBSDF_eval( const varying Plastic_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { MICROFACETDIELECTRICLAYER_EVAL(self->dielectricLayer, self->lambert.scatteringType, &self->lambert, Lambert_eval); return MICROFACETDIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes MicrofacetDielectricLayerBSDF_sample( const varying Plastic_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { MICROFACETDIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->lambert.scatteringType, &self->lambert, Lambert_eval, Lambert_sample); return MICROFACETDIELECTRICLAYER_SAMPLE_GET(); } // Plastic BSDF SYCL_EXTERNAL __noinline BSDF_EvalRes Plastic_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying Plastic_BSDF *uniform self = (const varying Plastic_BSDF *uniform)super; if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return MicrofacetDielectricLayerBSDF_eval(self, wo, wi); else return DielectricLayerBSDF_eval(self, wo, wi); } SYCL_EXTERNAL __noinline BSDF_SampleRes Plastic_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying Plastic_BSDF *uniform self = (const varying Plastic_BSDF *uniform)super; if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return MicrofacetDielectricLayerBSDF_sample(self, wo, s, ss); else return DielectricLayerBSDF_sample(self, wo, s, ss); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Plastic_getBSDF_addr() { return (void *uniform)Plastic_getBSDF; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/PlasticShared.h000066400000000000000000000007201464752671100256700ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Plastic { Material super; vec3f pigmentColor; float eta; float roughness; #ifdef __cplusplus Plastic() : pigmentColor(1.f), eta(1.4f), roughness(0.01f) { super.type = ispc::MATERIAL_TYPE_PLASTIC; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Principled.cpp000066400000000000000000000133411464752671100255710ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Principled.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Principled_ispc.h" #endif namespace ospray { namespace pathtracer { Principled::Principled(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_PRINCIPLED) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast( ispc::Principled_getBSDF_addr()); getSh()->super.getTransparency = reinterpret_cast( ispc::Principled_getTransparency_addr()); getSh()->super.selectNextMedium = reinterpret_cast( ispc::Principled_selectNextMedium_addr()); getSh()->super.getEmission = reinterpret_cast( ispc::Principled_getEmission_addr()); #endif } std::string Principled::toString() const { return "ospray::pathtracer::Principled"; } void Principled::commit() { baseColor = getMaterialParam3f("baseColor", vec3f(0.8f)); edgeColor = getMaterialParam3f("edgeColor", vec3f(1.f)); metallic = getMaterialParam1f("metallic", 0.f); diffuse = getMaterialParam1f("diffuse", 1.f); specular = getMaterialParam1f("specular", 1.f); ior = getMaterialParam1f("ior", 1.f); transmission = getMaterialParam1f("transmission", 0.f); transmissionColor = getMaterialParam3f("transmissionColor", vec3f(1.f)); transmissionDepth = getMaterialParam1f("transmissionDepth", 1.f); roughness = getMaterialParam1f("roughness", 0.f); anisotropy = getMaterialParam1f("anisotropy", 0.f); rotation = getMaterialParam1f("rotation", 0.f); normal = getMaterialParam1f("normal", 1.f); baseNormal = getMaterialParam1f("baseNormal", 1.f); coat = getMaterialParam1f("coat", 0.f); coatIor = getMaterialParam1f("coatIor", 1.5f); coatColor = getMaterialParam3f("coatColor", vec3f(1.f)); coatThickness = getMaterialParam1f("coatThickness", 1.f); coatRoughness = getMaterialParam1f("coatRoughness", 0.f); coatNormal = getMaterialParam1f("coatNormal", 1.f); sheen = getMaterialParam1f("sheen", 0.f); sheenColor = getMaterialParam3f("sheenColor", vec3f(1.f)); sheenTint = getMaterialParam1f("sheenTint", 0.f); sheenRoughness = getMaterialParam1f("sheenRoughness", 0.2f); opacity = getMaterialParam1f("opacity", 1.f); bool thin = getParam("thin", false); backlight = getMaterialParam1f("backlight", 0.f); thickness = getMaterialParam1f("thickness", 1.f); float outsideIor = getParam("outsideIor", 1.f); vec3f outsideTransmissionColor = getParam("outsideTransmissionColor", vec3f(1.f)); float outsideTransmissionDepth = getParam("outsideTransmissionDepth", 1.f); emissiveColor = getMaterialParam3f("emissiveColor", vec3f(0.f)); // intensity is an additional constant factor to emission emissiveColor.factor *= getParam("intensity", 1.f); getSh()->emission = emissiveColor.factor; getSh()->emissionMap = emissiveColor.tex; getSh()->baseColor = baseColor.factor; getSh()->baseColorMap = baseColor.tex; getSh()->edgeColor = edgeColor.factor; getSh()->edgeColorMap = edgeColor.tex; getSh()->metallic = metallic.factor; getSh()->metallicMap = metallic.tex; getSh()->diffuse = diffuse.factor; getSh()->diffuseMap = diffuse.tex; getSh()->specular = specular.factor; getSh()->specularMap = specular.tex; getSh()->ior = ior.factor; getSh()->iorMap = ior.tex; getSh()->transmission = transmission.factor; getSh()->transmissionMap = transmission.tex; getSh()->transmissionColor = transmissionColor.factor; getSh()->transmissionColorMap = transmissionColor.tex; getSh()->transmissionDepth = transmissionDepth.factor; getSh()->transmissionDepthMap = transmissionDepth.tex; getSh()->roughness = roughness.factor; getSh()->roughnessMap = roughness.tex; getSh()->anisotropy = anisotropy.factor; getSh()->anisotropyMap = anisotropy.tex; getSh()->rotation = rotation.factor; getSh()->rotationMap = rotation.tex; getSh()->normal = normal.factor; getSh()->normalMap = normal.tex; getSh()->normalRot = normal.rot; getSh()->baseNormal = baseNormal.factor; getSh()->baseNormalMap = baseNormal.tex; getSh()->baseNormalRot = baseNormal.rot; getSh()->coat = coat.factor; getSh()->coatMap = coat.tex; getSh()->coatIor = coatIor.factor; getSh()->coatIorMap = coatIor.tex; getSh()->coatColor = coatColor.factor; getSh()->coatColorMap = coatColor.tex; getSh()->coatThickness = coatThickness.factor; getSh()->coatThicknessMap = coatThickness.tex; getSh()->coatRoughness = coatRoughness.factor; getSh()->coatRoughnessMap = coatRoughness.tex; getSh()->coatNormal = coatNormal.factor; getSh()->coatNormalMap = coatNormal.tex; getSh()->coatNormalRot = coatNormal.rot; getSh()->sheen = sheen.factor; getSh()->sheenMap = sheen.tex; getSh()->sheenColor = sheenColor.factor; getSh()->sheenColorMap = sheenColor.tex; getSh()->sheenTint = sheenTint.factor; getSh()->sheenTintMap = sheenTint.tex; getSh()->sheenRoughness = sheenRoughness.factor; getSh()->sheenRoughnessMap = sheenRoughness.tex; getSh()->opacity = opacity.factor; getSh()->opacityMap = opacity.tex; getSh()->thin = thin; getSh()->backlight = backlight.factor; getSh()->backlightMap = backlight.tex; getSh()->thickness = thickness.factor; getSh()->thicknessMap = thickness.tex; getSh()->outsideMedium.ior = outsideIor >= 1.f ? outsideIor : rcp(outsideIor); vec3f otc = vec3f(log(outsideTransmissionColor.x), log(outsideTransmissionColor.y), log(outsideTransmissionColor.z)); getSh()->outsideMedium.attenuation = otc / outsideTransmissionDepth; getSh()->super.isEmissive = isEmissive(); } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Principled.h000066400000000000000000000026121464752671100252350ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "PrincipledShared.h" namespace ospray { namespace pathtracer { struct Principled : public AddStructShared { Principled(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; virtual bool isEmissive() const override; private: MaterialParam3f baseColor; MaterialParam3f edgeColor; MaterialParam1f metallic; MaterialParam1f diffuse; MaterialParam1f specular; MaterialParam1f ior; MaterialParam1f transmission; MaterialParam3f transmissionColor; MaterialParam1f transmissionDepth; MaterialParam1f roughness; MaterialParam1f anisotropy; MaterialParam1f rotation; MaterialParam1f normal; MaterialParam1f baseNormal; MaterialParam1f coat; MaterialParam1f coatIor; MaterialParam3f coatColor; MaterialParam1f coatThickness; MaterialParam1f coatRoughness; MaterialParam1f coatNormal; MaterialParam1f sheen; MaterialParam3f sheenColor; MaterialParam1f sheenTint; MaterialParam1f sheenRoughness; MaterialParam1f opacity; MaterialParam1f backlight; MaterialParam1f thickness; MaterialParam3f emissiveColor; }; inline bool Principled::isEmissive() const { return reduce_max(getSh()->emission) > 0.f; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Principled.ih000066400000000000000000000025761464752671100254170ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Principled_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f Principled_getTransparency( const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL void Principled_selectNextMedium( const uniform Material *uniform super, const DifferentialGeometry &dg, Medium ¤tMedium); SYCL_EXTERNAL BSDF_EvalRes Principled_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes Principled_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); SYCL_EXTERNAL vec3f Principled_getEmission(const Material *uniform super, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Principled.ispc000066400000000000000000001034631464752671100257520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Principled.ih" #include "Medium.ih" #include "common/Ray.ih" #include "render/Material.ih" #include "render/bsdfs/Conductor.ih" #include "render/bsdfs/Dielectric.ih" #include "render/bsdfs/DielectricLayer.ih" #include "render/bsdfs/Lambert.ih" #include "render/bsdfs/LambertTransmission.ih" #include "render/bsdfs/MicrofacetConductor.ih" #include "render/bsdfs/MicrofacetDielectric.ih" #include "render/bsdfs/MicrofacetDielectricLayer.ih" #include "render/bsdfs/MicrofacetSheenLayer.ih" #include "render/bsdfs/MultiBSDF.ih" #include "render/bsdfs/OrenNayar.ih" #include "render/bsdfs/PassthroughLayer.ih" #include "render/bsdfs/ThinDielectric.ih" #include "render/bsdfs/ThinMicrofacetDielectric.ih" #include "render/bsdfs/Transmission.ih" #include "texture/TextureParam.ih" // c++ shared #include "PrincipledShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE struct Principled_Diffuse_BSDF { DEFINE_MULTIBSDF(2); OrenNayar lambert; BSDF lambertTransmission; }; struct Principled_Plastic_BSDF { MicrofacetDielectricLayer dielectricLayer; Principled_Diffuse_BSDF diffuse; }; struct Principled_Glass_BSDF { int bsdfId; MicrofacetDielectric dielectric; ThinMicrofacetDielectric thinDielectric; BSDF transmission; }; struct Principled_Base_MultiBSDF { DEFINE_MULTIBSDF(3); MicrofacetConductor metal; Principled_Glass_BSDF glass; Principled_Plastic_BSDF plastic; }; struct Principled_ClearCoat_BSDF { MicrofacetDielectricLayer dielectricLayer; Principled_Base_MultiBSDF base; }; struct Principled_SheenLayer_BSDF { MicrofacetSheenLayer sheenLayer; Principled_ClearCoat_BSDF clearCoat; }; struct Principled_BSDF { DEFINE_MULTIBSDF(2); BSDF transmission; Principled_SheenLayer_BSDF sheen; }; SYCL_EXTERNAL const varying BSDF *uniform Principled_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium ¤tMedium, const uniform FeatureFlagsHandler &) { const uniform Principled *uniform self = (const uniform Principled *uniform)super; // Allocate memory and initialize material BSDF varying Principled_BSDF *uniform bsdf = (varying Principled_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(Principled_BSDF)); varying MultiBSDF *uniform multiRoot = (varying MultiBSDF * uniform) bsdf; MultiBSDF_Constructor(multiRoot, 2); bsdf->super.bsdfType = BSDF_TYPE_PRINCIPLED; // create the default shading frame varying linear3f *uniform frame = LinearSpace3f_create(ctx, makeShadingFrame(dg, self->normalMap, self->normalRot, self->normal)); const float rotation = clamp(self->rotation * get1f(self->rotationMap, dg, 1.f)); const float theta = 2.f * (float)pi * rotation; if (theta > 0.f) { frame->vx = rotate(frame->vx, frame->vz, theta); frame->vy = cross(frame->vz, frame->vx); } float opacity = clamp(self->opacity * get1f(self->opacityMap, dg, 1.f)); if (hasAlpha(self->baseColorMap)) { vec4f baseColorSample = get4f(self->baseColorMap, dg, make_vec4f(1.f)); opacity *= baseColorSample.w; } if (self->opacity > EPS) { varying linear3f *uniform baseFrame = frame; if (valid(self->baseNormalMap)) { baseFrame = LinearSpace3f_create(ctx, makeShadingFrame( dg, self->baseNormalMap, self->baseNormalRot, self->baseNormal)); if (theta > 0.f) { baseFrame->vx = rotate(baseFrame->vx, baseFrame->vz, theta); baseFrame->vy = cross(baseFrame->vz, baseFrame->vx); } } varying MultiBSDF *uniform multiBase = (varying MultiBSDF * uniform) & bsdf->sheen.clearCoat.base; MultiBSDF_Constructor(multiBase, 3); const vec3f baseColor = clamp(self->baseColor * get3f(self->baseColorMap, dg, make_vec3f(1.f)) * make_vec3f(dg.color)); const float specular = clamp(self->specular * get1f(self->specularMap, dg, 1.f)); const float metallic = clamp(self->metallic * get1f(self->metallicMap, dg, 1.f)); const float roughness = clamp(self->roughness * get1f(self->roughnessMap, dg, 1.f)); const float anisotropy = clamp(self->anisotropy * get1f(self->anisotropyMap, dg, 1.f)); const bool fromOutside = self->thin ? true : eq(currentMedium, self->outsideMedium); // dielectric base const float dielectric = (1.f - metallic); if (dielectric > EPS) { const float transmission = clamp(self->transmission * get1f(self->transmissionMap, dg, 1.f)); float ior = self->ior * get1f(self->iorMap, dg, 1.f); if (ior < 1.f) ior = rcp(ior); float eta = fromOutside ? self->outsideMedium.ior * rcp(ior) : ior * rcp(self->outsideMedium.ior); eta = clamp(eta, 1.f / 3.f, 3.f); // clamp to common range due to LUTs // plastic base const float plastic = dielectric * (1.f - transmission); if (plastic > EPS) { varying MultiBSDF *uniform multiDiffuse = (varying MultiBSDF * uniform) & bsdf->sheen.clearCoat.base.plastic.diffuse; MultiBSDF_Constructor(multiDiffuse, 2); varying Principled_Plastic_BSDF *uniform plasticBsdf = &bsdf->sheen.clearCoat.base.plastic; // diffuse const float diffuse = clamp(self->diffuse * get1f(self->diffuseMap, dg, 1.f)); const vec3f diffuseColor = baseColor * diffuse; const float backlight = self->thin ? clamp(self->backlight * get1f(self->backlightMap, dg, 1.f), 0.f, 2.f) : 0.f; const float diffuseTransmission = backlight * 0.5f; const float diffuseReflection = 1.f - diffuseTransmission; if (diffuseReflection > EPS) { if (self->roughness < EPS) Lambert_Constructor( &plasticBsdf->diffuse.lambert.super, baseFrame, diffuseColor); else OrenNayar_Constructor(&plasticBsdf->diffuse.lambert, baseFrame, diffuseColor, roughness); MultiBSDF_add(multiDiffuse, 0, &plasticBsdf->diffuse.lambert.super, diffuseReflection, diffuseReflection); } if (diffuseTransmission > EPS) { LambertTransmission_Constructor( &plasticBsdf->diffuse.lambertTransmission, baseFrame, diffuseColor); MultiBSDF_add(multiDiffuse, 1, &plasticBsdf->diffuse.lambertTransmission, diffuseTransmission, diffuseTransmission); } // specular if (self->specular > EPS) { if (self->roughness < EPS) { DielectricLayer_Constructor((varying DielectricLayer * uniform) & plasticBsdf->dielectricLayer, baseFrame, &plasticBsdf->diffuse.super, eta, make_vec3f(1.f), 1.f, specular); } else { MicrofacetDielectricLayer_Constructor(&plasticBsdf->dielectricLayer, super->microfacetAlbedoTables, baseFrame, &plasticBsdf->diffuse.super, eta, make_vec3f(1.f), 1.f, roughness, anisotropy, specular); } } else { PassthroughLayer_Constructor((varying PassthroughLayer * uniform) & plasticBsdf->dielectricLayer, &plasticBsdf->diffuse.super); } MultiBSDF_add(multiBase, 2, &plasticBsdf->dielectricLayer.super, plastic, plastic * max(diffuse, specular)); } // glass base const float glass = dielectric * transmission * specular; if (glass > EPS) { varying Principled_Glass_BSDF *uniform glassBsdf = &bsdf->sheen.clearCoat.base.glass; if (abs(eta - 1.f) > EPS) { if (!self->thin) { if (self->roughness < EPS) Dielectric_Constructor( (varying Dielectric * uniform) & glassBsdf->dielectric, baseFrame, eta); else MicrofacetDielectric_Constructor(&glassBsdf->dielectric, super->microfacetAlbedoTables, baseFrame, eta, roughness, anisotropy); glassBsdf->bsdfId = 1; MultiBSDF_add( multiBase, 1, &glassBsdf->dielectric.super, glass, glass); } else { // thin const vec3f transmissionColor = clamp(self->transmissionColor * get3f(self->transmissionColorMap, dg, make_vec3f(1.f))); const float transmissionDepth = max(self->transmissionDepth * get1f(self->transmissionDepthMap, dg, 1.f), EPS); const float thickness = max(self->thickness * get1f(self->thicknessMap, dg, 1.f), 0.f); const vec3f attenuation = logf(transmissionColor) / transmissionDepth * thickness; if (self->roughness < EPS) ThinDielectric_Constructor((varying ThinDielectric * uniform) & glassBsdf->thinDielectric, baseFrame, eta, attenuation); else ThinMicrofacetDielectric_Constructor(&glassBsdf->thinDielectric, super->microfacetAlbedoTables, baseFrame, eta, roughness, anisotropy, attenuation); glassBsdf->bsdfId = 2; MultiBSDF_add( multiBase, 1, &glassBsdf->thinDielectric.super, glass, glass); } } else { Transmission_Constructor( &glassBsdf->transmission, baseFrame, make_vec3f(1.f)); glassBsdf->bsdfId = 0; MultiBSDF_add(multiBase, 1, &glassBsdf->transmission, glass, glass); } } } // conductor base const float conductor = metallic * specular; if (conductor > EPS) { const vec3f edgeColor = clamp( self->edgeColor * get3f(self->edgeColorMap, dg, make_vec3f(1.f))); Fresnel *uniform fresnel = FresnelConductorArtistic_create(ctx, baseColor, edgeColor); varying MicrofacetConductor *uniform metalBsdf = &bsdf->sheen.clearCoat.base.metal; if (self->roughness < EPS) Conductor_Constructor( (varying Conductor * uniform) metalBsdf, baseFrame, fresnel); else MicrofacetConductor_Constructor(metalBsdf, super->microfacetAlbedoTables, baseFrame, fresnel, roughness, anisotropy); MultiBSDF_add(multiBase, 0, &metalBsdf->super, conductor, conductor); } // coatings varying linear3f *uniform coatFrame = frame; // clear coat if (self->coat > EPS) { const float coat = clamp(self->coat * get1f(self->coatMap, dg, 1.f)); float coatIor = self->coatIor * get1f(self->coatIorMap, dg, 1.f); if (coatIor < 1.f) coatIor = rcp(coatIor); float coatEta = fromOutside ? self->outsideMedium.ior * rcp(coatIor) : coatIor * rcp(self->outsideMedium.ior); coatEta = clamp(coatEta, 1.f / 3.f, 3.f); // clamp to common range due to LUTs const vec3f coatColor = clamp( self->coatColor * get3f(self->coatColorMap, dg, make_vec3f(1.f))); const float coatThickness = max( self->coatThickness * get1f(self->coatThicknessMap, dg, 1.f), 0.f); if (valid(self->coatNormalMap)) { coatFrame = LinearSpace3f_create(ctx, makeShadingFrame(dg, self->coatNormalMap, self->coatNormalRot, self->coatNormal)); } if (self->coatRoughness < EPS || abs(coatEta - 1.f) < EPS) { DielectricLayer_Constructor((varying DielectricLayer * uniform) & bsdf->sheen.clearCoat.dielectricLayer, coatFrame, &bsdf->sheen.clearCoat.base.super, coatEta, coatColor, coatThickness, coat); } else { const float coatRoughness = clamp(self->coatRoughness * get1f(self->coatRoughnessMap, dg, 1.f)); MicrofacetDielectricLayer_Constructor( &bsdf->sheen.clearCoat.dielectricLayer, super->microfacetAlbedoTables, coatFrame, &bsdf->sheen.clearCoat.base.super, coatEta, coatColor, coatThickness, coatRoughness, 0.f, coat); } } else { PassthroughLayer_Constructor((varying PassthroughLayer * uniform) & bsdf->sheen.clearCoat.dielectricLayer, &bsdf->sheen.clearCoat.base.super); } // sheen if (self->sheen > EPS) { const float sheen = clamp(self->sheen * get1f(self->sheenMap, dg, 1.f)); vec3f sheenColor = clamp( self->sheenColor * get3f(self->sheenColorMap, dg, make_vec3f(1.f))); const float sheenTint = clamp(self->sheenTint * get1f(self->sheenTintMap, dg, 1.f)); sheenColor = lerp(sheenTint, sheenColor, baseColor); const float sheenRoughness = clamp(self->sheenRoughness * get1f(self->sheenRoughnessMap, dg, 1.f)); MicrofacetSheenLayer_Constructor(&bsdf->sheen.sheenLayer, super->microfacetAlbedoTables, coatFrame, &bsdf->sheen.clearCoat.dielectricLayer.super, sheenColor, sheenRoughness, sheen); } else PassthroughLayer_Constructor( (varying PassthroughLayer * uniform) & bsdf->sheen.sheenLayer, &bsdf->sheen.clearCoat.dielectricLayer.super); MultiBSDF_add( multiRoot, 1, &bsdf->sheen.sheenLayer.super, opacity, opacity); } // cut-out transparency if (1.f - self->opacity > EPS || valid(self->opacityMap) || hasAlpha(self->baseColorMap)) { const float transparency = 1.f - opacity; Transmission_Constructor( &bsdf->transmission, frame, make_vec3f(transparency)); MultiBSDF_add(multiRoot, 0, &bsdf->transmission, 1.f, transparency); } return &bsdf->super; } SYCL_EXTERNAL vec3f Principled_getTransparency( const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &) { const uniform Principled *uniform self = (const uniform Principled *uniform)super; vec3f T = make_vec3f(0.f); float opacity = clamp(self->opacity * get1f(self->opacityMap, dg, 1.f)); if (hasAlpha(self->baseColorMap)) { vec4f baseColorSample = get4f(self->baseColorMap, dg, make_vec4f(1.f)); opacity *= baseColorSample.w; } const float transparency = 1.f - opacity; const float transmission = clamp(self->transmission * get1f(self->transmissionMap, dg, 1.f)); // early exit if (transparency <= EPS && transmission <= EPS) return T; // cut-out opacity if (self->opacity > EPS) { // glass base const float specular = clamp(self->specular * get1f(self->specularMap, dg, 1.f)); const float metallic = clamp(self->metallic * get1f(self->metallicMap, dg, 1.f)); const float dielectric = (1.f - metallic); const float glass = dielectric * transmission * specular; if (glass > EPS) { const bool fromOutside = self->thin ? true : eq(currentMedium, self->outsideMedium); float ior = self->ior * get1f(self->iorMap, dg, 1.f); if (ior < 1.f) ior = rcp(ior); float eta = fromOutside ? self->outsideMedium.ior * rcp(ior) : ior * rcp(self->outsideMedium.ior); eta = clamp(eta, 1.f / 3.f, 3.f); // clamp to common range due to LUTs const float cosThetaO = max(-dot(ray.dir, dg.Ns), 0.f); if (abs(eta - 1.f) > EPS) { if (!self->thin) { // solid // use microfacet if textured due to different // transparent shadow behavior if (self->roughness < EPS) T = Dielectric_getTransparency(cosThetaO, eta); } else { // thin const vec3f transmissionColor = clamp(self->transmissionColor * get3f(self->transmissionColorMap, dg, make_vec3f(1.f))); const float transmissionDepth = max(self->transmissionDepth * get1f(self->transmissionDepthMap, dg, 1.f), EPS); const float thickness = max(self->thickness * get1f(self->thicknessMap, dg, 1.f), 0.f); const vec3f attenuation = logf(transmissionColor) / transmissionDepth * thickness; if (self->roughness < EPS) { T = ThinDielectric_getTransparency(cosThetaO, eta, attenuation); } else { const float roughness = clamp(self->roughness * get1f(self->roughnessMap, dg, 1.f)); T = ThinMicrofacetDielectric_getTransparency( super->microfacetAlbedoTables, cosThetaO, eta, roughness, attenuation); } } } else { T = make_vec3f(1.f); } if (reduce_max(T) > 0.f) { // clear coat if (self->coat > EPS) { const float coat = clamp(self->coat * get1f(self->coatMap, dg, 1.f)); float coatIor = self->coatIor * get1f(self->coatIorMap, dg, 1.f); if (coatIor < 1.f) coatIor = rcp(coatIor); float coatEta = fromOutside ? self->outsideMedium.ior * rcp(coatIor) : coatIor * rcp(self->outsideMedium.ior); coatEta = clamp( coatEta, 1.f / 3.f, 3.f); // clamp to common range due to LUTs if (abs(coatEta - 1.f) > EPS) { const float coatEta = fromOutside ? self->outsideMedium.ior * rcp(coatIor) : coatIor * rcp(self->outsideMedium.ior); const vec3f coatColor = clamp(self->coatColor * get3f(self->coatColorMap, dg, make_vec3f(1.f))); const float coatThickness = max( self->coatThickness * get1f(self->coatThicknessMap, dg, 1.f), 0.f); if (self->coatRoughness < EPS) { T = T * DielectricLayer_getTransparency( cosThetaO, coatEta, coatColor, coatThickness, coat); } else { const float coatRoughness = clamp( self->coatRoughness * get1f(self->coatRoughnessMap, dg, 1.f)); T = T * MicrofacetDielectricLayer_getTransparency( super->microfacetAlbedoTables, cosThetaO, coatEta, coatColor, coatThickness, coatRoughness, 0.f, coat); } } } // sheen if (self->sheen > EPS) { const float sheen = clamp(self->sheen * get1f(self->sheenMap, dg, 1.f)); const float sheenRoughness = clamp( self->sheenRoughness * get1f(self->sheenRoughnessMap, dg, 1.f)); T = T * MicrofacetSheenLayer_getTransparency( super->microfacetAlbedoTables, cosThetaO, sheenRoughness, sheen); } T = T * glass; } } } // cut-out transparency T = T * opacity + transparency; return T; } SYCL_EXTERNAL void Principled_selectNextMedium( const uniform Material *uniform super, const DifferentialGeometry &dg, Medium ¤tMedium) { const uniform Principled *uniform self = (const uniform Principled *uniform)super; if (self->thin || self->transmission <= EPS) return; if (eq(currentMedium, self->outsideMedium)) { float ior = self->ior * get1f(self->iorMap, dg, 1.f); if (ior < 1.f) ior = rcp(ior); const vec3f transmissionColor = clamp(self->transmissionColor * get3f(self->transmissionColorMap, dg, make_vec3f(1.f))); const float transmissionDepth = max( self->transmissionDepth * get1f(self->transmissionDepthMap, dg, 1.f), EPS); currentMedium.ior = ior; currentMedium.attenuation = logf(transmissionColor) / transmissionDepth; } else { currentMedium = self->outsideMedium; } } // Lambert BSDF inline BSDF_EvalRes LambertBSDF_eval( const varying OrenNayar *uniform self, const vec3f &wo, const vec3f &wi) { if (self->super.bsdfType == BSDF_TYPE_OREN_NAYAR) return OrenNayar_eval(&self->super, wo, wi); else return Lambert_eval(&self->super, wo, wi); } inline BSDF_SampleRes LambertBSDF_sample(const varying OrenNayar *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->super.bsdfType == BSDF_TYPE_OREN_NAYAR) return OrenNayar_sample(&self->super, wo, s, ss); else return Lambert_sample(&self->super, wo, s, ss); } // Diffuse BSDF __noinline BSDF_EvalRes DiffuseBSDF_eval( const varying Principled_Diffuse_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { MULTIBSDF_EVAL_BEGIN(); MULTIBSDF_EVAL_CHILD(0, &self->lambert, LambertBSDF_eval); MULTIBSDF_EVAL_CHILD(1, &self->lambertTransmission, LambertTransmission_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } __noinline BSDF_SampleRes DiffuseBSDF_sample( const varying Principled_Diffuse_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, &self->lambert, LambertBSDF_sample); MULTIBSDF_SAMPLE_CHILD( 1, &self->lambertTransmission, LambertTransmission_sample); MULTIBSDF_SAMPLE_EVAL(); MULTIBSDF_EVAL_CHILD(0, &self->lambert, LambertBSDF_eval); MULTIBSDF_EVAL_CHILD(1, &self->lambertTransmission, LambertTransmission_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } // Plastic DielectricLayer BSDF inline BSDF_EvalRes Plastic_DielectricLayerBSDF_eval( const varying Principled_Plastic_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { DIELECTRICLAYER_EVAL(self->dielectricLayer, self->diffuse.super.scatteringType, &self->diffuse, DiffuseBSDF_eval); return DIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes Plastic_DielectricLayerBSDF_sample( const varying Principled_Plastic_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { DIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->diffuse.super.scatteringType, &self->diffuse, DiffuseBSDF_sample); return DIELECTRICLAYER_SAMPLE_GET(); } // Plastic MicrofacetDielectricLayer BSDF inline BSDF_EvalRes Plastic_MicrofacetDielectricLayerBSDF_eval( const varying Principled_Plastic_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { MICROFACETDIELECTRICLAYER_EVAL(self->dielectricLayer, self->diffuse.super.scatteringType, &self->diffuse, DiffuseBSDF_eval); return MICROFACETDIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes Plastic_MicrofacetDielectricLayerBSDF_sample( const varying Principled_Plastic_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { MICROFACETDIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->diffuse.super.scatteringType, &self->diffuse, DiffuseBSDF_eval, DiffuseBSDF_sample); return MICROFACETDIELECTRICLAYER_SAMPLE_GET(); } // Plastic BSDF __noinline BSDF_EvalRes PlasticBSDF_eval( const varying Principled_Plastic_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { // Skip dielectric layer if no specular if (self->dielectricLayer.weight < EPS) return DiffuseBSDF_eval(&self->diffuse, wo, wi); if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return Plastic_MicrofacetDielectricLayerBSDF_eval(self, wo, wi); else return Plastic_DielectricLayerBSDF_eval(self, wo, wi); } inline BSDF_SampleRes PlasticBSDF_sample( const varying Principled_Plastic_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { // Skip dielectric layer if no specular if (self->dielectricLayer.weight < EPS) return DiffuseBSDF_sample(&self->diffuse, wo, s, ss); if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return Plastic_MicrofacetDielectricLayerBSDF_sample(self, wo, s, ss); else return Plastic_DielectricLayerBSDF_sample(self, wo, s, ss); } // Glass Dielectric BSDF inline BSDF_EvalRes Glass_DielectricBSDF_eval( const varying MicrofacetDielectric *uniform self, const vec3f &wo, const vec3f &wi) { if (self->super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC) return MicrofacetDielectric_eval(&self->super, wo, wi); else return Dielectric_eval(&self->super, wo, wi); } inline BSDF_SampleRes Glass_DielectricBSDF_sample( const varying MicrofacetDielectric *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC) return MicrofacetDielectric_sample(&self->super, wo, s, ss); else return Dielectric_sample(&self->super, wo, s, ss); } // Glass ThinDielectric BSDF inline BSDF_EvalRes Glass_ThinDielectricBSDF_eval( const varying ThinMicrofacetDielectric *uniform self, const vec3f &wo, const vec3f &wi) { if (self->super.bsdfType == BSDF_TYPE_THIN_MICROFACET_DIELECTRIC) return ThinMicrofacetDielectric_eval(&self->super, wo, wi); else return ThinDielectric_eval(&self->super, wo, wi); } inline BSDF_SampleRes Glass_ThinDielectricBSDF_sample( const varying ThinMicrofacetDielectric *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->super.bsdfType == BSDF_TYPE_THIN_MICROFACET_DIELECTRIC) return ThinMicrofacetDielectric_sample(&self->super, wo, s, ss); else return ThinDielectric_sample(&self->super, wo, s, ss); } // Glass BSDF __noinline BSDF_EvalRes GlassBSDF_eval( const varying Principled_Glass_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { if (self->bsdfId == 1) return Glass_DielectricBSDF_eval(&self->dielectric, wo, wi); else if (self->bsdfId == 2) return Glass_ThinDielectricBSDF_eval(&self->thinDielectric, wo, wi); else return make_BSDF_EvalRes_zero(); } inline BSDF_SampleRes GlassBSDF_sample( const varying Principled_Glass_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->bsdfId == 1) return Glass_DielectricBSDF_sample(&self->dielectric, wo, s, ss); else if (self->bsdfId == 2) return Glass_ThinDielectricBSDF_sample(&self->thinDielectric, wo, s, ss); else return Transmission_sample(&self->transmission, wo, s, ss); } // Metal BSDF __noinline BSDF_EvalRes MetalBSDF_eval( const varying MicrofacetConductor *uniform self, const vec3f &wo, const vec3f &wi) { if (self->super.bsdfType == BSDF_TYPE_MICROFACET_CONDUCTOR) return MicrofacetConductor_eval(self, wo, wi); else return make_BSDF_EvalRes_zero(); } inline BSDF_SampleRes MetalBSDF_sample( const varying MicrofacetConductor *uniform self, const vec3f &wo, const vec2f &s, float ss) { if (self->super.bsdfType == BSDF_TYPE_MICROFACET_CONDUCTOR) return MicrofacetConductor_sample(self, wo, s, ss); else return Conductor_sample(&self->super, wo, s, ss); } // Base BSDF __noinline BSDF_EvalRes BaseBSDF_eval( const varying Principled_Base_MultiBSDF *uniform self, const vec3f &wo, const vec3f &wi) { MULTIBSDF_EVAL_BEGIN(); MULTIBSDF_EVAL_CHILD(0, &self->metal, MetalBSDF_eval); MULTIBSDF_EVAL_CHILD(1, &self->glass, GlassBSDF_eval); MULTIBSDF_EVAL_CHILD(2, &self->plastic, PlasticBSDF_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } __noinline BSDF_SampleRes BaseBSDF_sample( const varying Principled_Base_MultiBSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, &self->metal, MetalBSDF_sample); MULTIBSDF_SAMPLE_CHILD(1, &self->glass, GlassBSDF_sample); MULTIBSDF_SAMPLE_CHILD(2, &self->plastic, PlasticBSDF_sample); MULTIBSDF_SAMPLE_EVAL(); MULTIBSDF_EVAL_CHILD(0, &self->metal, MetalBSDF_eval); MULTIBSDF_EVAL_CHILD(1, &self->glass, GlassBSDF_eval); MULTIBSDF_EVAL_CHILD(2, &self->plastic, PlasticBSDF_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } // ClearCoat DielectricLayer BSDF inline BSDF_EvalRes ClearCoat_DielectricLayerBSDF_eval( const varying Principled_ClearCoat_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { DIELECTRICLAYER_EVAL(self->dielectricLayer, self->base.super.scatteringType, &self->base, BaseBSDF_eval); return DIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes ClearCoat_DielectricLayerBSDF_sample( const varying Principled_ClearCoat_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { DIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->base.super.scatteringType, &self->base, BaseBSDF_sample); return DIELECTRICLAYER_SAMPLE_GET(); } // ClearCoat MicrofacetDielectricLayer BSDF inline BSDF_EvalRes ClearCoat_MicrofacetDielectricLayerBSDF_eval( const varying Principled_ClearCoat_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { MICROFACETDIELECTRICLAYER_EVAL(self->dielectricLayer, self->base.super.scatteringType, &self->base, BaseBSDF_eval); return MICROFACETDIELECTRICLAYER_EVAL_GET(); } inline BSDF_SampleRes ClearCoat_MicrofacetDielectricLayerBSDF_sample( const varying Principled_ClearCoat_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { MICROFACETDIELECTRICLAYER_SAMPLE(self->dielectricLayer, self->base.super.scatteringType, &self->base, BaseBSDF_eval, BaseBSDF_sample); return MICROFACETDIELECTRICLAYER_SAMPLE_GET(); } // ClearCoat BSDF __noinline BSDF_EvalRes ClearCoatBSDF_eval( const varying Principled_ClearCoat_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { // Skip dielectric layer if no clear coat if (self->dielectricLayer.weight < EPS) return BaseBSDF_eval(&self->base, wo, wi); if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return ClearCoat_MicrofacetDielectricLayerBSDF_eval(self, wo, wi); else return ClearCoat_DielectricLayerBSDF_eval(self, wo, wi); } __noinline BSDF_SampleRes ClearCoatBSDF_sample( const varying Principled_ClearCoat_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { // Skip dielectric layer if no clear coat if (self->dielectricLayer.weight < EPS) return BaseBSDF_sample(&self->base, wo, s, ss); if (self->dielectricLayer.super.bsdfType == BSDF_TYPE_MICROFACET_DIELECTRIC_LAYER) return ClearCoat_MicrofacetDielectricLayerBSDF_sample(self, wo, s, ss); else return ClearCoat_DielectricLayerBSDF_sample(self, wo, s, ss); } // SheenLayer BSDF __noinline BSDF_EvalRes SheenLayerBSDF_eval( const varying Principled_SheenLayer_BSDF *uniform self, const vec3f &wo, const vec3f &wi) { // Skip sheen layer if does not exists if (self->sheenLayer.weight < EPS) return ClearCoatBSDF_eval(&self->clearCoat, wo, wi); MICROFACETSHEENLAYER_EVAL( self->sheenLayer, &self->clearCoat, ClearCoatBSDF_eval); return MICROFACETSHEENLAYER_EVAL_GET(); } inline BSDF_SampleRes SheenLayerBSDF_sample( const varying Principled_SheenLayer_BSDF *uniform self, const vec3f &wo, const vec2f &s, float ss) { // Skip sheen layer if does not exists if (self->sheenLayer.weight < EPS) return ClearCoatBSDF_sample(&self->clearCoat, wo, s, ss); MICROFACETSHEENLAYER_SAMPLE(self->sheenLayer, &self->clearCoat, ClearCoatBSDF_eval, ClearCoatBSDF_sample); return MICROFACETSHEENLAYER_SAMPLE_GET(); } // Principled BSDF SYCL_EXTERNAL BSDF_EvalRes Principled_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying Principled_BSDF *uniform self = (const varying Principled_BSDF *uniform)super; MULTIBSDF_EVAL_BEGIN(); // 0 - omitted, no evaluation needed for transmission BSDF MULTIBSDF_EVAL_CHILD(1, &self->sheen, SheenLayerBSDF_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } SYCL_EXTERNAL BSDF_SampleRes Principled_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying Principled_BSDF *uniform self = (const varying Principled_BSDF *uniform)super; MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, &self->transmission, Transmission_sample); MULTIBSDF_SAMPLE_CHILD(1, &self->sheen, SheenLayerBSDF_sample); MULTIBSDF_SAMPLE_EVAL(); // 0 - omitted, no evaluation needed for transmission BSDF MULTIBSDF_EVAL_CHILD(1, &self->sheen, SheenLayerBSDF_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } SYCL_EXTERNAL vec3f Principled_getEmission(const Material *uniform _self, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &) { const Principled *uniform self = (Principled * uniform) _self; return self->emission * get3f(self->emissionMap, dg, make_vec3f(1.f)); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Principled_getBSDF_addr() { return (void *uniform)Principled_getBSDF; } export void *uniform Principled_getTransparency_addr() { return (void *uniform)Principled_getTransparency; } export void *uniform Principled_selectNextMedium_addr() { return (void *uniform)Principled_selectNextMedium; } export void *uniform Principled_getEmission_addr() { return (void *uniform)Principled_getEmission; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/PrincipledShared.h000066400000000000000000000067041464752671100263720ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MediumShared.h" #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Principled { Material super; vec3f baseColor; TextureParam baseColorMap; // metallic reflectivity at grazing angle (90 deg) / edge tint vec3f edgeColor; TextureParam edgeColorMap; float metallic; TextureParam metallicMap; // diffuse weight in [0, 1] float diffuse; TextureParam diffuseMap; // specular weight in [0, 1] float specular; TextureParam specularMap; // index of refraction float ior; TextureParam iorMap; // specular transmission in [0, 1] float transmission; TextureParam transmissionMap; vec3f transmissionColor; TextureParam transmissionColorMap; float transmissionDepth; TextureParam transmissionDepthMap; // roughness in [0, 1]; 0 = ideally smooth (mirror) float roughness; TextureParam roughnessMap; // degree of anisotropy in [0, 1]; 0 = isotropic, 1 = maximally anisotropic float anisotropy; TextureParam anisotropyMap; // anisotropic rotation in [0, 1]; float rotation; TextureParam rotationMap; // default normal map for all layers float normal; // scale TextureParam normalMap; linear2f normalRot; // base normal map (overrides default normal) float baseNormal; // scale TextureParam baseNormalMap; linear2f baseNormalRot; // dielectric clear coat weight in [0, 1] float coat; TextureParam coatMap; // dielectric clear coat index of refraction float coatIor; TextureParam coatIorMap; vec3f coatColor; TextureParam coatColorMap; float coatThickness; TextureParam coatThicknessMap; float coatRoughness; TextureParam coatRoughnessMap; // clear coat normal map (overrides default normal) float coatNormal; // scale TextureParam coatNormalMap; linear2f coatNormalRot; // sheen weight in [0, 1] float sheen; TextureParam sheenMap; vec3f sheenColor; TextureParam sheenColorMap; // sheen tint in [0, 1] float sheenTint; TextureParam sheenTintMap; float sheenRoughness; TextureParam sheenRoughnessMap; // cut-out opacity in [0, 1] float opacity; TextureParam opacityMap; // solid or thin mode flag bool thin; // diffuse transmission in [0, 2] (thin only) float backlight; TextureParam backlightMap; // thickness (thin only) float thickness; TextureParam thicknessMap; Medium outsideMedium; vec3f emission; TextureParam emissionMap; #ifdef __cplusplus Principled() : baseColor(0.8f), edgeColor(1.f), metallic(0.f), diffuse(1.f), specular(1.f), ior(1.f), transmission(0.f), transmissionColor(1.f), transmissionDepth(1.f), roughness(0.f), anisotropy(0.f), rotation(0.f), normal(1.f), normalRot(one), baseNormal(1.f), baseNormalRot(one), coat(0.f), coatIor(1.5f), coatColor(1.f), coatThickness(1.f), coatRoughness(0.f), coatNormal(1.f), coatNormalRot(one), sheen(0.f), sheenColor(1.f), sheenTint(0.f), sheenRoughness(0.2f), opacity(1.f), thin(false), backlight(0.f), thickness(1.f), emission(0.f) { super.type = ispc::MATERIAL_TYPE_PRINCIPLED; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/ThinGlass.cpp000066400000000000000000000025701464752671100253760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ThinGlass.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/ThinGlass_ispc.h" #endif namespace ospray { namespace pathtracer { ThinGlass::ThinGlass(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_THINGLASS) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast( ispc::ThinGlass_getBSDF_addr()); getSh()->super.getTransparency = reinterpret_cast( ispc::ThinGlass_getTransparency_addr()); #endif } std::string ThinGlass::toString() const { return "ospray::pathtracer::ThinGlass"; } void ThinGlass::commit() { const float eta = getParam("eta", 1.5f); attenuationColor = getMaterialParam3f("attenuationColor", vec3f(1.f)); const float attenuationDistance = getParam("attenuationDistance", 1.f); const float thickness = getParam("thickness", 1.f); getSh()->eta = rcp(eta); getSh()->attenuationScale = thickness * rcp(std::max(attenuationDistance, EPS)); const vec3f &acf = attenuationColor.factor; getSh()->attenuation = vec3f(log(acf.x), log(acf.y), log(acf.z)) * getSh()->attenuationScale; getSh()->attenuationColorMap = attenuationColor.tex; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/ThinGlass.h000066400000000000000000000007461464752671100250460ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "ThinGlassShared.h" namespace ospray { namespace pathtracer { struct ThinGlass : public AddStructShared { ThinGlass(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; private: MaterialParam3f attenuationColor; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/ThinGlass.ih000066400000000000000000000016771464752671100252230ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform ThinGlass_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f ThinGlass_getTransparency( const uniform Material *uniform super, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_SampleRes ThinGlass_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/ThinGlass.ispc000066400000000000000000000045251464752671100255540ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ThinGlass.ih" #include "common/Ray.ih" #include "render/Material.ih" #include "render/bsdfs/RobustThinDielectric.ih" #include "texture/TextureParam.ih" // c++ shared #include "ThinGlassShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE static inline const vec3f getAttenuation( const ThinGlass *uniform self, const DifferentialGeometry &dg) { vec3f attenuation = self->attenuation + logf(make_vec3f(dg.color)) * self->attenuationScale; if (valid(self->attenuationColorMap)) { vec3f attenuationColor = get3f(self->attenuationColorMap, dg); attenuation = attenuation + logf(attenuationColor) * self->attenuationScale; } return attenuation; } SYCL_EXTERNAL const varying BSDF *uniform ThinGlass_getBSDF( const Material *uniform super, ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { const ThinGlass *uniform self = (const ThinGlass *uniform)super; varying linear3f *uniform shadingframe = LinearSpace3f_create(ctx, frame(dg.Ns)); varying BSDF *uniform bsdf = RobustThinDielectric_create( ctx, shadingframe, self->eta, getAttenuation(self, dg)); bsdf->bsdfType = BSDF_TYPE_THINGLASS; return bsdf; } SYCL_EXTERNAL vec3f ThinGlass_getTransparency(const Material *uniform material, const DifferentialGeometry &dg, const Ray &ray, const Medium &, const uniform FeatureFlagsHandler &) { const ThinGlass *uniform self = (const ThinGlass *uniform)material; float cosThetaO = max(-dot(ray.dir, dg.Ns), 0.0f); return RobustThinDielectric_getTransparency( cosThetaO, self->eta, getAttenuation(self, dg)); } SYCL_EXTERNAL BSDF_SampleRes ThinGlass_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { return RobustThinDielectric_sample(super, wo, s, ss); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform ThinGlass_getBSDF_addr() { return (void *uniform)ThinGlass_getBSDF; } export void *uniform ThinGlass_getTransparency_addr() { return (void *uniform)ThinGlass_getTransparency; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/ThinGlassShared.h000066400000000000000000000015261464752671100261720ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #include "texture/TextureParamShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct ThinGlass { Material super; float eta; // reciprocal refraction index of internal medium // assumed to be <=1 vec3f attenuation; // negative Napierian attenuation coefficient, // i.e. wrt. the natural base e float attenuationScale; // factor to scale attenuation from texture due to // thickness and attenuationDistance TextureParam attenuationColorMap; #ifdef __cplusplus ThinGlass() : eta(1.5f), attenuation(0.f), attenuationScale(1.f) { super.type = ispc::MATERIAL_TYPE_THINGLASS; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/materials/Velvet.cpp000066400000000000000000000022401464752671100247410ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Velvet.h" #ifndef OSPRAY_TARGET_SYCL // ispc #include "render/materials/Velvet_ispc.h" #endif namespace ospray { namespace pathtracer { Velvet::Velvet(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFO_MATERIAL_VELVET) { #ifndef OSPRAY_TARGET_SYCL getSh()->super.getBSDF = reinterpret_cast(ispc::Velvet_getBSDF_addr()); #endif } std::string Velvet::toString() const { return "ospray::pathtracer::Velvet"; } void Velvet::commit() { vec3f reflectance = getParam("reflectance", vec3f(.4f, 0.f, 0.f)); float backScattering = getParam("backScattering", .5f); vec3f horizonScatteringColor = getParam("horizonScatteringColor", vec3f(.75f, .1f, .1f)); float horizonScatteringFallOff = getParam("horizonScatteringFallOff", 10); getSh()->reflectance = reflectance; getSh()->backScattering = backScattering; getSh()->horizonScatteringColor = horizonScatteringColor; getSh()->horizonScatteringFallOff = horizonScatteringFallOff; } } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Velvet.h000066400000000000000000000006531464752671100244140ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/Material.h" // ispc shared #include "VelvetShared.h" namespace ospray { namespace pathtracer { struct Velvet : public AddStructShared { Velvet(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; }; } // namespace pathtracer } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/materials/Velvet.ih000066400000000000000000000015201464752671100245570ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/bsdfs/BSDF.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Material; struct ShadingContext; struct DifferentialGeometry; struct Ray; struct Medium; SYCL_EXTERNAL const varying BSDF *uniform Velvet_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &ray, const Medium ¤tMedium, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL BSDF_EvalRes Velvet_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi); SYCL_EXTERNAL BSDF_SampleRes Velvet_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/Velvet.ispc000066400000000000000000000056651464752671100251330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Velvet.ih" #include "render/Material.ih" #include "render/bsdfs/Minneart.ih" #include "render/bsdfs/MultiBSDF.ih" #include "render/bsdfs/Velvety.ih" // c++ shared #include "VelvetShared.h" /////////////////////////////////////////////////////////////////////////////// // Implementation OSPRAY_BEGIN_ISPC_NAMESPACE #define MULTIBSDF_SIZE 2 struct Velvet_BSDF { DEFINE_MULTIBSDF(MULTIBSDF_SIZE); Minneart minneart; Velvety velvety; }; SYCL_EXTERNAL const varying BSDF *uniform Velvet_getBSDF( const uniform Material *uniform super, uniform ShadingContext *uniform ctx, const DifferentialGeometry &dg, const Ray &, const Medium &, const uniform FeatureFlagsHandler &) { const uniform Velvet *uniform self = (const uniform Velvet *uniform)super; varying LinearSpace3f *uniform shadingFrame = LinearSpace3f_create(ctx, frame(dg.Ns)); // Allocate memory and initialize material BSDF varying Velvet_BSDF *uniform bsdf = (varying Velvet_BSDF * uniform) ShadingContext_alloc(ctx, sizeof(Velvet_BSDF)); varying MultiBSDF *uniform mbsdf = (varying MultiBSDF * uniform) bsdf; MultiBSDF_Constructor(mbsdf, MULTIBSDF_SIZE); bsdf->super.bsdfType = BSDF_TYPE_VELVET; Minneart_Constructor( &bsdf->minneart, shadingFrame, self->reflectance, self->backScattering); MultiBSDF_add( mbsdf, 0, &bsdf->minneart.super, 1.f, luminance(self->reflectance)); Velvety_Constructor(&bsdf->velvety, shadingFrame, self->horizonScatteringColor, self->horizonScatteringFallOff); MultiBSDF_add(mbsdf, 1, &bsdf->velvety.super, 1.f, luminance(self->horizonScatteringColor)); return &bsdf->super; } SYCL_EXTERNAL BSDF_EvalRes Velvet_BSDF_eval( const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi) { const varying Velvet_BSDF *uniform self = (const varying Velvet_BSDF *uniform)super; MULTIBSDF_EVAL_BEGIN(); MULTIBSDF_EVAL_CHILD(0, &self->minneart, Minneart_eval); MULTIBSDF_EVAL_CHILD(1, &self->velvety, Velvety_eval); MULTIBSDF_EVAL_END(); return MULTIBSDF_EVAL_GET(); } SYCL_EXTERNAL BSDF_SampleRes Velvet_BSDF_sample( const varying BSDF *uniform super, const vec3f &wo, const vec2f &s, float ss) { const varying Velvet_BSDF *uniform self = (const varying Velvet_BSDF *uniform)super; MULTIBSDF_SAMPLE_BEGIN(); MULTIBSDF_SAMPLE_CHILD(0, &self->minneart, Minneart_sample); MULTIBSDF_SAMPLE_CHILD(1, &self->velvety, Velvety_sample); MULTIBSDF_SAMPLE_EVAL(); MULTIBSDF_EVAL_CHILD(0, &self->minneart, Minneart_eval); MULTIBSDF_EVAL_CHILD(1, &self->velvety, Velvety_eval); MULTIBSDF_SAMPLE_END(); return MULTIBSDF_SAMPLE_GET(); } /////////////////////////////////////////////////////////////////////////////// // External API export void *uniform Velvet_getBSDF_addr() { return (void *uniform)Velvet_getBSDF; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/materials/VelvetShared.h000066400000000000000000000015751464752671100255470ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/MaterialShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Velvet { Material super; // Diffuse reflectance of the surface. The range is from 0 // (black) to 1 (white). vec3f reflectance; // Amount of back scattering. The range is from 0 (no back // scattering) to inf (maximum back scattering). float backScattering; // Color of horizon scattering. vec3f horizonScatteringColor; // Fall-off of horizon scattering. float horizonScatteringFallOff; #ifdef __cplusplus Velvet() : reflectance(.4f, 0.f, 0.f), backScattering(.5f), horizonScatteringColor(.75f, .1f, .1f), horizonScatteringFallOff(10) { super.type = ispc::MATERIAL_TYPE_VELVET; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/pathtracer/000077500000000000000000000000001464752671100231465ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/pathtracer/GeometryLight.ih000066400000000000000000000014311464752671100262520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PathContext; struct PathState; struct PathVertex; struct Ray; struct Light; struct Light_SampleRes; struct DifferentialGeometry; SYCL_EXTERNAL vec3f evaluateGeometryLights(const PathContext &pathContext, const PathState &pathState, const PathVertex &lastVertex, const PathVertex &pathVertex, const Ray &ray, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL Light_SampleRes GeometryLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float time, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/GeometryLight.ispc000066400000000000000000000106031464752671100266110ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/pathtracer/GeometryLight.ih" #include "render/pathtracer/PathStructs.ih" #include "render/pathtracer/PathTracerUtil.ih" #include "render/Material.ih" #include "render/MaterialDispatch.ih" #include "texture/Texture2D.ih" #include "texture/TextureParam.ih" #include "common/Instance.ih" #include "geometry/GeometricModel.ih" #include "math/Distribution1D.ih" #include "rkcommon/math/AffineSpace.ih" // c++ shared #include "GeometryLightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec3f evaluateGeometryLights(const PathContext &pathContext, const PathState &pathState, const PathVertex &lastVertex, const PathVertex &pathVertex, const Ray &ray, const uniform FeatureFlagsHandler &ffh) { vec3f L = make_vec3f(0.f); Material *material = pathVertex.dg.material; foreach_unique (m in material) { vec3f emission = Material_dispatch_getEmission(m, pathVertex.dg, ffh); if (m != NULL && reduce_max(emission) > 0.f) { float misWeight = 1.0f; if (pathContext.numGeoLights > 0 && lastVertex.numLightSamples > 0) { // at the moment we only support uniform light selection // therefore we can evaluate the selection PDF directly const float lightSelectionPDF = lastVertex.numLightSamples / (float)pathContext.numLights; // convert pdf wrt. area to pdf wrt. solid angle const float cosd = dot(pathVertex.dg.Ng, ray.dir); // lastVertex.dg.P can be different from ray.org (previously sampled a // Dirac transmission), thus we cannot just use ray.t as distance const vec3f vdis = lastVertex.dg.P - pathVertex.dg.P; const float lePdf = pathVertex.dg.areaPDF * dot(vdis, vdis) / abs(cosd); misWeight = misHeuristic( pathContext, lastVertex.pdf_w, lightSelectionPDF * lePdf); } L = L + pathState.throughput * emission * misWeight; } } return L; } // Implementation ///////////////////////////////////////////////////////////// SYCL_EXTERNAL Light_SampleRes GeometryLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float time, const uniform FeatureFlagsHandler &ffh) { const GeometryLight *uniform self = (GeometryLight * uniform) super; const GeometricModel *uniform model = self->model; const Geometry *uniform geo = model->geom; Light_SampleRes res; res.weight = make_vec3f(0.0f); // choose primitive const Sample1D sample = Distribution1D_sample(self->numPrimitives, self->distribution, 0, s.x); const int32 primID = self->primIDs[sample.idx]; Material *mat = GeometricModel_getMaterial(model, dg.renderer, primID); if (!mat) return res; const vec2f ns = make_vec2f(sample.frac, s.y); // reproject s.x // sample position on primitive // TODO maybe should already be done wrt. solid angle SampleAreaRes as; const Instance *uniform instance = self->super.instance; assert(instance); const uniform FeatureFlagsGeometry ffg = getFeatureFlagsGeometry(ffh); if (instance->motionBlur && (ffg & FFG_MOTION_BLUR)) { foreach_unique (utime in time) { const uniform affine3f xfm = Instance_getTransform(instance, utime); as = Geometry_dispatch_sampleArea( geo, primID, xfm, rcp(xfm), ns, time, ffh); } } else { as = Geometry_dispatch_sampleArea( geo, primID, instance->xfm, instance->rcp_xfm, ns, time, ffh); } // note that sample.pdf/primitives * sampleArea(worldspace).pdf == self->pdf // extant light vector from the hit point const vec3f dir = as.pos - dg.P; const float dist = length(dir); // normalized light vector res.dir = dir / dist; // convert to pdf wrt. solid angle const float rcosd = rcp(abs(dot(as.normal, res.dir))); res.pdf = self->pdf * sqr(dist) * rcosd; res.dist = dist - max(as.epsilon, calcEpsilon(as.pos, dist)) * rcosd; DifferentialGeometry texDg; initDgFromTexCoord(texDg, as.st); texDg.P = as.pos; texDg.Ns = as.normal; texDg.Ng = as.normal; vec3f radiance; foreach_unique (m in mat) radiance = Material_dispatch_getEmission(m, texDg, ffh); res.weight = radiance * rcp(res.pdf); return res; } // Exports (called from C++) ////////////////////////////////////////////////// export void *uniform GeometryLight_sample_addr() { return (void *uniform)GeometryLight_sample; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/GeometryLightShared.h000066400000000000000000000020521464752671100272300ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "lights/LightShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct GeometricModel; // The GeometryLight is a proxy object fulfilling the Light.ih API. // It is generated internally for each emitting geometry modelance to facilitate // explicit importance sampling (currently wrt. the surface area). struct GeometryLight { Light super; // inherited light fields const GeometricModel *model; // underlying geometry int32 numPrimitives; // number of emissive primitives int32 *primIDs; // IDs of emissive primitives to sample float *distribution; // pdf over prims proportional to (world-space) area float pdf; // probability density to sample point on surface := 1/area #ifdef __cplusplus GeometryLight() : model(nullptr), numPrimitives(0), primIDs(nullptr), distribution(nullptr), pdf(inf) { super.type = LIGHT_TYPE_GEOMETRY; } }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/pathtracer/NextEventEstimation.ih000066400000000000000000000007221464752671100274460ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PathContext; struct PathState; struct PathVertex; SYCL_EXTERNAL vec3f nextEventEstimation(const PathContext &pathContext, PathState &pathState, PathVertex &pathVertex, float rayConeWidth, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/NextEventEstimation.ispc000066400000000000000000000114211464752671100300020ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/pathtracer/NextEventEstimation.ih" #include "render/pathtracer/PathStructs.ih" #include "render/pathtracer/PathTracerDefines.ih" #include "render/pathtracer/PathTracerUtil.ih" #include "render/pathtracer/TransparentShadow.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "render/pathtracer/volumes/VolumeSampler.ih" #endif #include "common/RayCone.ih" #include "common/World.ih" #include "math/Distribution1D.ih" #include "math/random.ih" #include "math/sampling.ih" // c++ shared #include "lights/LightDispatch.ih" #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec3f nextEventEstimation(const PathContext &pathContext, PathState &pathState, PathVertex &pathVertex, float rayConeWidth, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); // direct lighting including shadows and MIS vec3f L = make_vec3f(0.f); const uint32 numLightSamples = pathState.firstBounceLight ? pathContext.numFirstBounceLightSamples : pathContext.numIndirectBounceLightSamples; // remember for MIS pathVertex.numLightSamples = numLightSamples; for (uniform uint32 i = 0; i < numLightSamples; i++) { // select a random light source from the list float ss; const vec2f s = LDSampler_get3LightSamples( pathState.ldSampler, i, numLightSamples > 1, ss); const Sample1D lSelectSample = Distribution1D_sample( pathContext.numLights, pathContext.lightsCDF, 0, ss); const float lightSelectionProb = lSelectSample.prob * numLightSamples; const Light *light = pathContext.lights[lSelectSample.idx]; // sample the contribution from the random light source Light_SampleRes ls; foreach_unique (l in light) ls = Light_dispatch_sample(l, pathVertex.dg, s, pathState.time, ffh); // adjust the contribution with the probabiltiy of selecting the light // source ls.weight = ls.weight / lightSelectionProb; ls.pdf *= lightSelectionProb; // skip when zero contribution from light if (reduce_max(ls.weight) <= 0.0f | ls.pdf <= PDF_CULLING) continue; // evaluate BSDF Scattering_EvalRes fe; if (ff.geometry && pathVertex.type == SURFACE) { foreach_unique (f in pathVertex.bsdf) if (f != NULL) fe = BSDF_dispatch_eval(f, pathVertex.wo, ls.dir, ffh); } else { #ifdef OSPRAY_ENABLE_VOLUMES if (ff.other & FFO_VOLUME_IN_SCENE) { foreach_unique (v in pathVertex.volume) if (v != NULL) fe = HenyeyGreenstein_eval(v->anisotropy, pathVertex.wo, ls.dir); } #endif } // skip when zero contribution from material if (reduce_max(fe.value) <= 0.0f) continue; // test for shadows with rayCones Ray shadowRay; vec3f org = pathVertex.dg.P; if (pathVertex.type != VOLUME) { if (dot(pathVertex.dg.Ng, ls.dir) < 0.f) org = org - (2.0f * pathVertex.dg.epsilon) * pathVertex.dg.Ng; } setRay(shadowRay, org, ls.dir, 0.f, ls.dist, pathState.time); // connect ray cone to point on light RayCone shadowCone; shadowCone.width = rayConeWidth; shadowCone.dwdt = -rayConeWidth * rcp(ls.dist); // Trace ray in clipping geometries scene, fill array with ray intervals RayIntervals rayIntervals; traceClippingRay(pathContext.world, shadowRay, rayIntervals, ffh); const vec3f throughput = pathState.throughput * fe.value; const vec3f unshadedLightContrib = throughput * ls.weight; const vec3f lightContrib = transparentShadow(pathContext.context, pathContext.world, unshadedLightContrib, shadowRay, shadowCone, rayIntervals, pathState.currentMedium, ffh); if (reduce_max(lightContrib) > 0) { #ifdef OSPRAY_ENABLE_VOLUMES if (ff.other & FFO_VOLUME_IN_SCENE) { const float T = volumeTransmittance(pathContext.world, shadowRay, rayIntervals, &pathState.randomSampler, ffh); if (reduce_max(T) > 0) { // we have to use an independent transmittance estimate for MIS to get // a correct result const float T_mis = #ifdef OSPRAY_PATHTRACER_DEBUG pathContext.disableFWD || pathContext.disableNEE ? 1.f : #endif volumeTransmittance(pathContext.world, shadowRay, rayIntervals, &pathState.randomSampler, ffh); L = L + T * lightContrib * misHeuristic(pathContext, ls.pdf, fe.pdf * T_mis); } } else #endif { L = L + lightContrib * misHeuristic(pathContext, ls.pdf, fe.pdf); } } } return L; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathSampler.ih000066400000000000000000000007741464752671100257200ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "common/OSPCommon.ih" #include "common/RayCone.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PathContext; struct PathState; struct Ray; struct ScreenSample; SYCL_EXTERNAL void samplePath(const PathContext &pathContext, PathState &pathState, Ray &ray, RayCone &rayCone, ScreenSample &sample, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathSampler.ispc000066400000000000000000000271051464752671100262530ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/pathtracer/GeometryLight.ih" #include "render/pathtracer/NextEventEstimation.ih" #include "render/pathtracer/PathSampler.ih" #include "render/pathtracer/PathStructs.ih" #include "render/pathtracer/PathTracerDefines.ih" #include "render/pathtracer/PathTracerUtil.ih" #include "render/pathtracer/ShadowCatcher.ih" #include "render/pathtracer/TransparentShadow.ih" #include "render/pathtracer/VirtualLight.ih" #include "common/Intersect.ih" #include "common/World.ih" #include "math/random.ih" #include "render/Material.ih" #include "render/MaterialDispatch.ih" #include "render/bsdfs/MicrofacetAlbedoTables.ih" #include "render/bsdfs/ShadingContext.ih" #include "render/materials/Medium.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "render/pathtracer/volumes/VolumeSampler.ih" #endif // c++ shared #include "PathTracerDataShared.h" #include "PathTracerShared.h" #include "common/RayCone.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline void postIntersect(const PathContext &pathContext, PathVertex &pathVertex, Ray &ray, RayCone &rayCone, const uniform FeatureFlagsHandler &ffh) { const PathTracer *uniform pt = pathContext.context; const uniform FeatureFlags ff = getFeatureFlags(ffh); if (ff.geometry && pathVertex.type == SURFACE) { postIntersect(pathContext.world, &pt->super, pathVertex.dg, ray, rayCone, DG_NS | DG_NG | DG_FACEFORWARD | DG_NORMALIZE | DG_TEXCOORD | DG_COLOR | DG_TANGENTS | DG_MOTIONBLUR, ffh); } #ifdef OSPRAY_ENABLE_VOLUMES if ((ff.other & FFO_VOLUME_IN_SCENE) && pathVertex.type == VOLUME) { pathVertex.dg.P = ray.org + ray.t * ray.dir; pathVertex.dg.renderer = &pt->super; pathVertex.dg.instID = ray.instID; foreach_unique (instID in ray.instID) { if (instID != RTC_INVALID_GEOMETRY_ID) { const World *uniform world = pathContext.world; const Instance *uniform instance = *(world->instances + instID); if (instance->userID != RTC_INVALID_GEOMETRY_ID) pathVertex.dg.instID = instance->userID; } } foreach_unique (volm in pathVertex.volume) VolumetricModel_postIntersect(volm, pathVertex.dg, ray, 0); } #endif } inline Scattering_SampleRes sampleDirection(const vec2f &s, const float ss, PathVertex &pathVertex, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); Scattering_SampleRes fs; fs.weight = make_vec3f(0.0f); if (ff.geometry && pathVertex.type == SURFACE) { foreach_unique (f in pathVertex.bsdf) { if (f != NULL) { fs = BSDF_dispatch_sample(f, pathVertex.wo, s, ss, ffh); pathVertex.wi = fs.wi; pathVertex.pdf_w = fs.pdf; } } // check consistent side of surface to prevent light leaks const bool sameSide = dot(fs.wi, pathVertex.dg.Ng) >= 0.f; const bool reflection = fs.type & SCATTERING_REFLECTION; if (sameSide != reflection) fs.weight = make_vec3f(0.0f); } #ifdef OSPRAY_ENABLE_VOLUMES if ((ff.other & FFO_VOLUME_IN_SCENE) && pathVertex.type == VOLUME) { foreach_unique (v in pathVertex.volume) { if (v != NULL) { fs = HenyeyGreenstein_sample(v->anisotropy, pathVertex.wo, s, ss); pathVertex.wi = fs.wi; pathVertex.pdf_w = fs.pdf; } } } #endif return fs; } SYCL_EXTERNAL void samplePath(const PathContext &pathContext, PathState &pathState, Ray &ray, RayCone &rayCone, ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { PathVertex lastVertex; lastVertex.type = CAMERA; #ifdef OSPRAY_ENABLE_VOLUMES lastVertex.volume = NULL; #endif lastVertex.pdf_w = inf; // probability density of previous sampled BSDF, for MIS lastVertex.dg.P = ray.org; // P and N also used by light eval lastVertex.dg.epsilon = calcEpsilon(ray.org, 0.f); lastVertex.dg.Ns = ray.dir; lastVertex.dg.Ng = ray.dir; lastVertex.numLightSamples = 0; uniform ShadingContext ctx; ShadingContext_Constructor(&ctx); const uniform FeatureFlags ff = getFeatureFlags(ffh); if (pathContext.context->shadowCatcher) { const Hit hit = intersectPlane( ray.org, ray.dir, pathContext.context->shadowCatcherPlane); if (hit.hit) pathState.shadowCatcherDist = hit.t; } do { if (pathState.shadowCatcherDist > ray.t0) // valid hit can hide other geometry ray.t = min(pathState.shadowCatcherDist, ray.t); // Trace ray in clipping geometries scene, fill array with ray intervals RayIntervals rayIntervals; traceClippingRay(pathContext.world, ray, rayIntervals, ffh); if (ff.geometry) { // Trace ray intervals in geometry traceGeometryRayIntervals(pathContext.world, ray, rayIntervals, ffh); } PathVertex pathVertex; pathVertex.bsdf = NULL; pathVertex.pdf_w = inf; #ifdef OSPRAY_ENABLE_VOLUMES pathVertex.volume = NULL; #endif pathVertex.type = noHit(ray) || !ff.geometry ? ENVIRONMENT : SURFACE; if (shadowCatcher(pathContext, pathState, pathVertex, ray, rayCone, ffh)) { pathVertex.type = ENVIRONMENT; } pathVertex.wo = neg(ray.dir); #ifdef OSPRAY_ENABLE_VOLUMES if (ff.other & FFO_VOLUME_IN_SCENE) { float extinctionCoefficient; float freePath = volumeSampleFreePath(pathContext.world, ray, rayIntervals, &pathState.randomSampler, &pathVertex.volume, extinctionCoefficient, pathVertex.albedo, ffh); if (freePath < inf) { pathVertex.type = VOLUME; pathState.throughput = pathState.throughput * pathVertex.albedo; } } #endif // record depth of primary rays if (pathState.depth == 0) sample.z = ray.t; // background handling if (pathVertex.type == ENVIRONMENT && (pathContext.context->backgroundRefraction ? pathState.specularTransmissionPath : pathState.straightPath)) { vec4f bg = Renderer_getBackground( &pathContext.context->super, pathContext.screen, ffh); pathState.contribution = pathState.contribution + pathState.throughput * make_vec3f(bg); sample.alpha = 1.0f - luminance(pathState.throughput); sample.alpha += (1.f - sample.alpha) * bg.w; } #ifdef OSPRAY_PATHTRACER_DEBUG if (!pathContext.disableFWD || pathState.depth == 0) #endif #ifdef OSPRAY_ENABLE_VOLUMES if (pathVertex.type != VOLUME) #endif { pathState.contribution = pathState.contribution + evaluateVirtualLights( pathContext, pathState, lastVertex, pathVertex, ray, ffh); } if (pathVertex.type == ENVIRONMENT) { break; } // terminate after evaluation of lights and before next shading to always // have both samples for MIS except if we have geometry lights (which we // still need to evaluate for MIS) if (pathState.depth >= pathContext.context->super.maxDepth && pathContext.numGeoLights == 0) { break; } postIntersect(pathContext, pathVertex, ray, rayCone, ffh); #ifdef OSPRAY_PATHTRACER_DEBUG if (!pathContext.disableFWD || pathState.depth == 0) #endif #ifdef OSPRAY_ENABLE_VOLUMES if (pathVertex.type != VOLUME) #endif { pathState.contribution = pathState.contribution + evaluateGeometryLights( pathContext, pathState, lastVertex, pathVertex, ray, ffh); } // record IDs of primary rays if (pathState.depth == 0) { sample.primID = pathVertex.dg.primID; sample.geomID = pathVertex.dg.objID; sample.instID = pathVertex.dg.instID; } // terminate after evaluation of lights and before next shading to always // have both samples for MIS if (pathState.depth >= pathContext.context->super.maxDepth || pathState.scatteringEvents >= pathContext.context->maxScatteringEvents) { break; } // shade surface ShadingContext_Constructor(&ctx); if (ff.geometry && pathVertex.type == SURFACE) { Material *material = (Material *)pathVertex.dg.material; foreach_unique (m in material) { if (m != NULL) { pathVertex.bsdf = Material_dispatch_getBSDF( m, &ctx, pathVertex.dg, ray, pathState.currentMedium, ffh); if (pathVertex.bsdf != NULL) { pathVertex.albedo = pathVertex.bsdf->albedo; } } } // terminate path when we don't have any BSDF if (pathVertex.bsdf == NULL) { break; } } // unconditionally advance sampler state to stay in lockstep across paths LDSampler_nextGroup(pathState.ldSampler); // next event estimation if (isSmooth(pathVertex)) { // record last vertex of a specular-only path if (pathState.scatteringEvents == 0) updateAuxilliaryData(pathState, pathVertex, sample); #ifdef OSPRAY_PATHTRACER_DEBUG if (!pathContext.disableNEE) #endif { pathState.contribution = pathState.contribution + nextEventEstimation( pathContext, pathState, pathVertex, sample.rayCone.width, ffh); pathState.firstBounceLight = false; } } float ss; uint32 uu3; const vec2f s = LDSampler_getNext4Samples(pathState.ldSampler, ss, uu3); Scattering_SampleRes fs = sampleDirection(s, ss, pathVertex, ffh); // terminate path when zero contribution from material if (reduce_max(fs.weight) <= 0.0f || fs.pdf <= PDF_CULLING) { break; } pathState.throughput = pathState.throughput * fs.weight; // Russian roulette if (pathState.depth >= pathContext.context->rouletteDepth) { const float rr = LDSampler_finalizeDim3(pathState.ldSampler, uu3); const float contProb = min(reduce_max(pathState.throughput), MAX_ROULETTE_CONT_PROB); if (rr > contProb) { break; } pathState.throughput = pathState.throughput * rcp(contProb); } // compute attenuation with Beer's law if (reduce_min(pathState.currentMedium.attenuation) < 0.f) pathState.throughput = pathState.throughput * expf(pathState.currentMedium.attenuation * ray.t); vec3f ray_org = pathVertex.dg.P; if (ff.geometry && pathVertex.type == SURFACE) { // update currentMedium if we hit a medium interface // TODO: support nested dielectrics if (fs.type & SCATTERING_TRANSMISSION) { ray_org = ray_org - (2.0f * pathVertex.dg.epsilon) * pathVertex.dg.Ng; Material *material = (Material *)pathVertex.dg.material; foreach_unique (m in material) { if (m != NULL) { Material_dispatch_selectNextMedium( m, pathVertex.dg, pathState.currentMedium, ffh); } } } } // keep lastBsdfPdf and lastDg when there was a specular transmission // to better combine MIS with transparent shadows if (fs.type & ~SCATTERING_SPECULAR_TRANSMISSION || pathVertex.type == VOLUME) { lastVertex = pathVertex; } // continue the path if (!eq(ray.dir, fs.wi)) pathState.straightPath = false; if (!(fs.type & SCATTERING_SPECULAR_TRANSMISSION)) pathState.specularTransmissionPath = false; setRay(ray, ray_org, fs.wi, pathState.time); pathState.depth++; if (fs.type & SCATTERING_SMOOTH) pathState.scatteringEvents++; } while (reduce_max(pathState.throughput) > pathContext.context->super.minContribution); sample.rgb = pathState.contribution; if (isnan(pathState.contribution.x) || isnan(pathState.contribution.y) || isnan(pathState.contribution.z)) { sample.rgb = make_vec3f(0.f); sample.alpha = 1.0f; } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathStructs.ih000066400000000000000000000041101464752671100257500ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/DifferentialGeometry.ih" #include "math/random.ih" #include "render/bsdfs/BSDF.ih" #include "render/materials/Medium.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/VolumetricModel.ih" #endif // c++ shared #include "PathTracerShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE struct World; struct Light; enum PathVertexType { SURFACE, VOLUME, CAMERA, LIGHT, ENVIRONMENT }; struct PathVertex { DifferentialGeometry dg; vec3f wi; vec3f wo; vec3f albedo; // only valid if path vertex is surface vertex const varying BSDF *bsdf; #ifdef OSPRAY_ENABLE_VOLUMES // only valid if path vertex is volume vertex const VolumetricModel *volume; #endif float pdf_w; // the pdf of sampling wo in solid angle measure PathVertexType type; uint32 numLightSamples; }; // constant, typically uniform struct PathContext { vec2f screen; // normalized coords, center of pixel, for backplate sampling const PathTracer *uniform context; const World *uniform world; uniform uint32 numLights; uniform uint32 numGeoLights; uniform uint32 numFirstBounceLightSamples; uniform uint32 numIndirectBounceLightSamples; Light **uniform lights; float *uniform lightsCDF; #ifdef OSPRAY_PATHTRACER_DEBUG uniform bool disableNEE; // turn off NEE contribution for debugging purposes uniform bool disableFWD; // turn off FWD contribution for debugging purposes bool debug; #endif }; // changing, typically varying struct PathState { vec3f throughput; vec3f contribution; float time; Medium currentMedium; float shadowCatcherDist; bool firstBounceLight; uint32 scatteringEvents; // counting diffuse and glossy bounces LDSampler ldSampler; RandomSampler randomSampler; bool straightPath; // path from camera did not change direction, for alpha and // backplate bool specularTransmissionPath; // path from camera only has specular // transmissions, for alpha and backplate uniform uint32 depth; }; OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracer.cpp000066400000000000000000000061761464752671100257210ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "PathTracer.h" #include "PathTracerData.h" #include "camera/Camera.h" #include "common/DeviceRT.h" #include "common/FeatureFlagsEnum.h" #include "common/World.h" #include "fb/FrameBuffer.h" #include "geometry/GeometricModel.h" #include "lights/Light.h" #include "render/Material.h" // Kernel launcher is defined in another compilation unit DECLARE_RENDERER_KERNEL_LAUNCHER(PathTracer_renderTaskLauncher); namespace ospray { PathTracer::PathTracer(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) {} std::string PathTracer::toString() const { return "ospray::PathTracer"; } void PathTracer::commit() { Renderer::commit(); getSh()->rouletteDepth = getParam("roulettePathLength", 5); getSh()->maxScatteringEvents = getParam("maxScatteringEvents", 20); getSh()->maxRadiance = getParam("maxContribution", inf); getSh()->numLightSamples = getParam("lightSamples", -1); getSh()->limitIndirectLightSamples = getParam("limitIndirectLightSamples", true); // Set shadow catcher plane const vec4f shadowCatcherPlane = getParam("shadowCatcherPlane", vec4f(0.f)); const vec3f normal = vec3f(shadowCatcherPlane); const float l = length(normal); getSh()->shadowCatcher = l > 0.f; const float rl = rcp(l); getSh()->shadowCatcherPlane = vec4f(normal * rl, shadowCatcherPlane.w * rl); scanForGeometryLights = getParam("geometryLights", true); getSh()->backgroundRefraction = getParam("backgroundRefraction", false); } void *PathTracer::beginFrame(FrameBuffer *, World *world) { if (!world) return nullptr; if (!world->pathtracerData || (scanForGeometryLights && !world->pathtracerData->scannedForGeometryLights)) { // Create PathTracerData object std::unique_ptr pathtracerData = rkcommon::make_unique( *world, scanForGeometryLights, *this); world->getSh()->pathtracerData = pathtracerData->getSh(); world->pathtracerData = std::move(pathtracerData); } return nullptr; } devicert::AsyncEvent PathTracer::renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *, const utility::ArrayView &taskIDs) const { // Gather feature flags from all components FeatureFlags ff = world->getFeatureFlags(); if (world->pathtracerData->getSh()->numGeoLights) ff.other |= FFO_LIGHT_GEOMETRY; ff |= featureFlags; ff |= fb->getFeatureFlags(); ff |= camera->getFeatureFlags(); // Prepare parameters for kernel launch auto *rendererSh = &getSh()->super; auto *fbSh = fb->getSh(); auto *cameraSh = camera->getSh(); auto *worldSh = world->getSh(); const size_t numTasks = taskIDs.size(); const vec2i taskSize = fb->getRenderTaskSize(); const vec3ui itemDims = vec3ui(taskSize.x, taskSize.y, numTasks); // Launch rendering kernel on the device return drtDevice.launchRendererKernel(itemDims, ispc::PathTracer_renderTaskLauncher, rendererSh, fbSh, cameraSh, worldSh, taskIDs.data(), ff); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracer.h000066400000000000000000000016401464752671100253550ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/Renderer.h" // ispc shared #include "PathTracerShared.h" namespace ispc { struct Light; } namespace ospray { struct PathTracer : public AddStructShared { PathTracer(api::ISPCDevice &device); virtual std::string toString() const override; virtual void commit() override; virtual void *beginFrame(FrameBuffer *, World *) override; virtual devicert::AsyncEvent renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *perFrameData, const utility::ArrayView &taskIDs) const override; private: bool scanForGeometryLights{true}; // if geometry lights are importance // sampled using NEE (requires scanning // the scene for geometric lights) }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracer.ispc000066400000000000000000000215231464752671100260660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "PathSampler.ih" #include "PathStructs.ih" #include "PathTracerDefines.ih" #include "PathTracerUtil.ih" #include "common/DeviceRT.ih" #include "common/FeatureFlagsEnum.h" #include "render/Renderer.ih" #include "render/bsdfs/BSDF.ih" #include "render/bsdfs/MicrofacetAlbedoTables.ih" #include "render/materials/Medium.ih" #include "render/util.ih" #include "volumes/VolumeSampler.ih" #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/World.ih" #include "fb/FrameBuffer.ih" #include "fb/FrameBufferDispatch.ih" #include "fb/RenderTaskDesc.ih" #include "math/Distribution1D.ih" #include "math/random.ih" #include "pf/PixelFilterDispatch.ih" // c++ shared #include "PathTracerDataShared.h" #include "PathTracerShared.h" #include "common/RayCone.ih" #include "render/MaterialShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #define MAX_LIGHT_SAMPLES 1024u static ScreenSample PathTraceIntegrator_Li(PathContext &pathContext, PathState &pathState, Ray &ray, RayCone &rayCone, const uniform FeatureFlagsHandler &ffh) { ScreenSample sample; sample.rgb = make_vec3f(0.f); sample.alpha = 1.f; sample.normal = make_vec3f(0.0f); sample.albedo = make_vec3f(0.0f); sample.primID = RTC_INVALID_GEOMETRY_ID; sample.geomID = RTC_INVALID_GEOMETRY_ID; sample.instID = RTC_INVALID_GEOMETRY_ID; pathState.straightPath = true; // path from camera did not change direction, // for alpha and backplate pathState.specularTransmissionPath = true; // path from camera only has specular transmissions, for alpha and // backplate pathState.depth = 0; pathState.scatteringEvents = 0; pathState.firstBounceLight = true; pathState.throughput = make_vec3f(1.f); pathState.contribution = make_vec3f(0.f); pathState.time = ray.time; pathState.currentMedium = make_Medium_vacuum(); pathState.shadowCatcherDist = -(float)inf; samplePath(pathContext, pathState, ray, rayCone, sample, ffh); return sample; } static inline uniform uint32 clz(uniform uint32 x) { #ifdef OSPRAY_TARGET_SYCL return sycl::clz(x); #else return count_leading_zeros(x); #endif } static ScreenSample PathTracer_renderPixel(PathTracer *uniform self, FrameBuffer *uniform fb, Camera *uniform camera, World *uniform world, const uint32 ix, const uint32 iy, const uniform uint32 accumID, const uniform FeatureFlagsHandler &ffh) { ScreenSample screenSample; screenSample.rgb = make_vec3f(0.f); screenSample.alpha = 0.f; screenSample.z = inf; screenSample.normal = make_vec3f(0.f); screenSample.albedo = make_vec3f(0.f); screenSample.sampleID.x = ix; screenSample.sampleID.y = iy; screenSample.primID = RTC_INVALID_GEOMETRY_ID; screenSample.geomID = RTC_INVALID_GEOMETRY_ID; screenSample.instID = RTC_INVALID_GEOMETRY_ID; PathContext pathContext; pathContext.context = self; pathContext.world = world; uniform PathTracerData *uniform ptData = world->pathtracerData; const uniform uint32 numLights = ptData->lights ? ptData->numLights : 0; const uniform uint32 numFirstBounceLightSamples = self->numLightSamples >= 0 && numLights > 0 ? self->numLightSamples : min(MAX_LIGHT_SAMPLES, numLights); const uniform uint32 numIndirectBounceLightSamples = self->limitIndirectLightSamples && numFirstBounceLightSamples >= 1 ? 1 : numFirstBounceLightSamples; pathContext.numLights = numLights; pathContext.numGeoLights = ptData->numGeoLights; pathContext.numFirstBounceLightSamples = numFirstBounceLightSamples; pathContext.numIndirectBounceLightSamples = numIndirectBounceLightSamples; pathContext.lights = ptData->lights; pathContext.lightsCDF = ptData->lightsCDF; #ifdef OSPRAY_PATHTRACER_DEBUG pathContext.disableNEE = numFirstBounceLightSamples == 0 && numIndirectBounceLightSamples == 0; pathContext.disableFWD = false; pathContext.debug = false; #endif PathState pathState; const uniform int spp = self->super.spp; uint32 sampleOffs; uint32 sampleOffsLight; uniform uint32 sampleBits; uniform uint32 sampleBitsLight; uint32 seed = 0x49c5f37e; // fixed seed with random bits if (fb->targetFrames) { // blue noise: negatively correlate pixels by // - using a single sequence (identical seed for all pixels) // - split across the frame (2D-shuffled space-filling curve to select // adjacent sub-sequences for neighboring pixels) const uniform uint32 targetSpp = fb->targetFrames * spp; // limit to 256x256 tiles, to have 16bits for 64k samples without overflow sampleOffs = OwenScramble4(interleaveZOrder16(ix, iy), seed) * targetSpp; // NEE splitting: further space sequence by max light samples sampleOffsLight = sampleOffs * numFirstBounceLightSamples; sampleBits = 16 + 32 - clz(targetSpp - 1); sampleBitsLight = 48 - clz(targetSpp * numFirstBounceLightSamples - 1); } else { // decorrelate pixels via different seed, whole sequence used for each pixel seed ^= fb->size.x * iy + ix; // avoid a zero for initializing the scramble sampleOffs = 0; sampleOffsLight = 0; sampleBits = 16; sampleBitsLight = 16; } for (uniform int s = 0; s < spp; s++) { const uint32 sampleID = accumID * spp + s; LDSampler_init(pathState.ldSampler, seed, sampleOffs + sampleID, sampleOffsLight + sampleID * numFirstBounceLightSamples, sampleBits, sampleBitsLight); RandomSampler_init(&pathState.randomSampler, seed, sampleOffs + sampleID); CameraSample cameraSample; cameraSample.pixel_center = (make_vec2f(ix, iy) + 0.5f) * fb->rcpSize; vec3ui ss234; const vec2f pixelSample = LDSampler_getNext5Samples(pathState.ldSampler, ss234); const PixelFilter *uniform pf = self->super.pixelFilter; const vec2f pfSample = pf ? PixelFilter_dispatch_sample(pf, pixelSample) : pixelSample - make_vec2f(0.5f); cameraSample.screen = cameraSample.pixel_center + pfSample * fb->rcpSize; if (camera->needLensSample) cameraSample.lens = LDSampler_finalizeDim23(pathState.ldSampler, ss234); else cameraSample.lens = make_vec2f(0.5f); if (camera->needTimeSample) cameraSample.time = LDSampler_finalizeDim4(pathState.ldSampler, ss234); else cameraSample.time = 0.5f; Camera_dispatch_initRay( camera, screenSample.ray, screenSample.rayCone, cameraSample, ffh); // take screen resolution (unnormalized coordinates), i.e., pixel size into // account screenSample.rayCone.dwdt *= fb->rcpSize.y; screenSample.rayCone.width *= fb->rcpSize.y; const float tMax = Renderer_getMaxDepth(&self->super, cameraSample.screen, ffh); screenSample.ray.t = min(screenSample.ray.t, tMax); pathContext.screen = cameraSample.pixel_center; ScreenSample sample = PathTraceIntegrator_Li( pathContext, pathState, screenSample.ray, screenSample.rayCone, ffh); screenSample.rgb = screenSample.rgb + min(sample.rgb, make_vec3f(self->maxRadiance)); screenSample.alpha = screenSample.alpha + sample.alpha; screenSample.normal = screenSample.normal + sample.normal; screenSample.albedo = screenSample.albedo + sample.albedo; if (sample.z < screenSample.z) { screenSample.z = sample.z; screenSample.primID = sample.primID; screenSample.geomID = sample.geomID; screenSample.instID = sample.instID; } } const float rspp = rcpf(spp); screenSample.rgb = screenSample.rgb * rspp; screenSample.alpha = screenSample.alpha * rspp; screenSample.normal = screenSample.normal * rspp; screenSample.albedo = screenSample.albedo * rspp; return screenSample; } inline void PathTracer_renderTask(const uniform vec3ui itemIndex, Renderer *uniform _self, FrameBuffer *uniform fb, Camera *uniform camera, World *uniform world, const uint32 *uniform taskIDs, const uniform FeatureFlagsHandler &ffh) { PathTracer *uniform self = (PathTracer * uniform) _self; uniform RenderTaskDesc taskDesc = FrameBuffer_dispatch_getRenderTaskDesc(fb, taskIDs[itemIndex.z], ffh); if (fb->cancelRender || isEmpty(taskDesc.region)) { return; } #ifndef ISPC { int32 y = taskDesc.region.lower.y + itemIndex.y; int32 x = taskDesc.region.lower.x + itemIndex.x; #else foreach_tiled (y = taskDesc.region.lower.y... taskDesc.region.upper.y, x = taskDesc.region.lower.x... taskDesc.region.upper.x) { #endif ScreenSample screenSample = PathTracer_renderPixel(self, fb, camera, world, x, y, fb->frameID, ffh); FrameBuffer_dispatch_accumulateSample(fb, screenSample, taskDesc, ffh); } FrameBuffer_dispatch_completeTask(fb, taskDesc, ffh); } // Exports (called from C++) ////////////////////////////////////////////////// DEFINE_RENDERER_KERNEL_LAUNCHER(PathTracer_renderTask); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracerData.cpp000066400000000000000000000120011464752671100264730ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "PathTracerData.h" // ospray #include "common/Instance.h" #include "common/World.h" #include "geometry/GeometricModel.h" #include "lights/Light.h" #include "render/Material.h" #include "render/Renderer.h" #ifndef OSPRAY_TARGET_SYCL // ispc exports #include "geometry/GeometricModel_ispc.h" #include "render/pathtracer/GeometryLight_ispc.h" #else namespace ispc { float Distribution1D_create(const int size, float *cdf); int GeometricModel_gatherEmissivePrimIDs(void *_model, void *_renderer, void *_instance, int *primIDs, float *distribution, float &pdf); } // namespace ispc #endif // ispc shared #include "GeometryLightShared.h" namespace ospray { PathTracerData::PathTracerData( const World &world, bool scanForGeometryLights, const Renderer &renderer) : AddStructShared(world.getISPCDevice().getDRTDevice()) { std::vector lightShs; size_t geometryLights{0}; if (scanForGeometryLights) { generateGeometryLights(world, renderer, lightShs); scannedForGeometryLights = true; geometryLights = lightShs.size(); } if (world.lights) { for (auto &&obj : *world.lights) { for (uint32_t id = 0; id < obj->getShCount(); id++) lightShs.push_back(obj->createSh(id)); } } // 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) { for (uint32_t id = 0; id < obj->getShCount(); id++) lightShs.push_back(obj->createSh(id, inst->getSh())); } } } // Prepare light cumulative distribution function std::vector lightsCDF(lightShs.size(), 1.f); if (lightsCDF.size()) { ispc::Distribution1D_create(lightsCDF.size(), lightsCDF.data()); } // Then create shared buffer from the temporary std::vector devicert::Device &device = world.getISPCDevice().getDRTDevice(); lightArray = devicert::make_buffer_shared_unique(device, lightShs); lightCDFArray = devicert::make_buffer_shared_unique(device, lightsCDF); getSh()->lights = lightArray->sharedPtr(); getSh()->lightsCDF = lightCDFArray->sharedPtr(); getSh()->numLights = lightArray->size(); getSh()->numGeoLights = geometryLights; } PathTracerData::~PathTracerData() { // Delete all lights structures devicert::Device &device = lightArray->getDevice(); for (ispc::Light *lptr : *lightArray) device.free(lptr); } ispc::Light *PathTracerData::createGeometryLight(const Instance *instance, const GeometricModel *model, const int32 numPrimIDs, const std::vector &primIDs, const std::vector &distribution, float pdf) { devicert::Device &device = instance->getISPCDevice().getDRTDevice(); ispc::GeometryLight *sh = StructSharedCreate(device); sh->super.instance = instance->getSh(); #ifndef OSPRAY_TARGET_SYCL sh->super.sample = reinterpret_cast( ispc::GeometryLight_sample_addr()); #endif sh->super.eval = nullptr; // geometry lights are hit and explicitly handled sh->model = model->getSh(); sh->numPrimitives = numPrimIDs; sh->pdf = pdf; geoLightPrimIDArray.emplace_back(device, primIDs); sh->primIDs = geoLightPrimIDArray.back().sharedPtr(); geoLightDistrArray.emplace_back(device, distribution); sh->distribution = geoLightDistrArray.back().sharedPtr(); return &sh->super; } void PathTracerData::generateGeometryLights(const World &world, const Renderer &renderer, std::vector &lightShs) { if (!world.instances) return; for (auto &&instance : *world.instances) { auto geometries = instance->group->geometricModels.ptr; if (!geometries) return; for (auto &&model : *geometries) { if (model->hasEmissiveMaterials(renderer.materialData)) { if (model->geometry().supportAreaLighting()) { std::vector primIDs(model->geometry().numPrimitives()); std::vector distribution(model->geometry().numPrimitives()); float pdf = 0.f; int32 numPrimIDs = ispc::GeometricModel_gatherEmissivePrimIDs(model->getSh(), renderer.getSh(), instance->getSh(), primIDs.data(), distribution.data(), pdf); // check whether the geometry has any emissive primitives if (numPrimIDs) { lightShs.push_back(createGeometryLight( instance, model, numPrimIDs, primIDs, distribution, pdf)); } } else { postStatusMsg(OSP_LOG_WARNING) << "#osp:pt Geometry " << model->toString() << " does not implement area sampling! " << "Cannot use importance sampling for that " << "geometry with emissive material!"; } } } } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracerData.h000066400000000000000000000022331464752671100261460ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/StructShared.h" #include "render/RendererData.h" // ispc shared #include "PathTracerDataShared.h" namespace ospray { struct World; struct Instance; struct GeometricModel; struct Renderer; struct PathTracerData : public AddStructShared { PathTracerData(const World &world, bool importanceSampleGeometryLights, const Renderer &renderer); ~PathTracerData() override; bool scannedForGeometryLights{false}; private: ispc::Light *createGeometryLight(const Instance *instance, const GeometricModel *model, const int32 numPrimIDs, const std::vector &primIDs, const std::vector &distribution, float pdf); void generateGeometryLights(const World &world, const Renderer &renderer, std::vector &lightShs); BufferSharedUq lightArray; BufferSharedUq lightCDFArray; std::vector> geoLightPrimIDArray; std::vector> geoLightDistrArray; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracerDataShared.h000066400000000000000000000012641464752671100273000ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Light; struct PathTracerData { // array containing the scene light sources // the lights are sorted: first geometric, then virtual lights Light **lights; uint32 numLights; // total number of light sources (geometric + virtual) uint32 numGeoLights; // number of geometric light sources float *lightsCDF; // CDF used by NEE for randomly picking lights #ifdef __cplusplus PathTracerData() : lights(nullptr), numLights(0), numGeoLights(0), lightsCDF(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracerDefines.ih000066400000000000000000000002301464752671100270160ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define MAX_ROULETTE_CONT_PROB 0.95f #define PDF_CULLING 0.0f RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracerShared.h000066400000000000000000000017571464752671100265150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/RendererShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct PathTracer { Renderer super; uint32 rouletteDepth; // path depth from which on RR is used uint32 maxScatteringEvents; float maxRadiance; // coefficients of plane equation defining geometry to catch shadows for // compositing; disabled if normal is zero-length vec4f shadowCatcherPlane; bool shadowCatcher; // preprocessed bool backgroundRefraction; bool limitIndirectLightSamples; int32 numLightSamples; // number of light samples used for NEE #ifdef __cplusplus PathTracer() : rouletteDepth(5), maxScatteringEvents(20), maxRadiance(inf), shadowCatcherPlane(0.f), shadowCatcher(false), backgroundRefraction(false), limitIndirectLightSamples(true), numLightSamples(-1) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/pathtracer/PathTracerUtil.ih000066400000000000000000000031451464752671100263660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/Renderer.ih" #include "render/ScreenSample.ih" #include "render/pathtracer/PathStructs.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "render/pathtracer/volumes/VolumeSampler.ih" #endif OSPRAY_BEGIN_ISPC_NAMESPACE inline bool isSmooth(const PathVertex &pathVertex) { if (pathVertex.type == SURFACE && pathVertex.bsdf && pathVertex.bsdf->scatteringType & SCATTERING_SMOOTH) return true; #ifdef OSPRAY_ENABLE_VOLUMES if (pathVertex.type == VOLUME && pathVertex.volume && isSmoothVolumeVertex(pathVertex)) return true; #endif return false; } inline float misHeuristic( const PathContext &pathContext, float pdf1, float pdf2) { #ifdef OSPRAY_PATHTRACER_DEBUG if (pathContext.disableNEE || pathContext.disableFWD) return 1.f; #else (void)pathContext; #endif // power heuristic with beta=2 const float p = sqr(pdf1) * rcp(sqr(pdf1) + sqr(pdf2)); // guard against high pdf (including Dirac delta) // using the limit when pdf1 approaches inf // compare with bit less than sqrt(float_max) (when sqr starts to overflow) return pdf1 > 1e17f ? 1.0f : p; } inline void updateAuxilliaryData( PathState &pathState, const PathVertex &pathVertex, ScreenSample &sample) { sample.albedo = pathState.throughput * pathVertex.albedo; if (pathVertex.type == SURFACE) { vec3f Ns = pathVertex.dg.Ns; foreach_unique (f in pathVertex.bsdf) { if (f != NULL && f->frame != NULL) Ns = getN(f); } sample.normal = pathState.throughput * Ns; } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/Scattering.ih000066400000000000000000000054631464752671100256030ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" #define SCATTERING_SPECULAR_REFLECTION \ (1 << 0) /*!< perfect specular reflection */ #define SCATTERING_GLOSSY_REFLECTION \ (1 << 1) /*!< glossy reflection */ #define SCATTERING_DIFFUSE_REFLECTION \ (1 << 2) /*!< diffuse reflection */ #define SCATTERING_SPECULAR_TRANSMISSION \ (1 << 3) /*!< perfect specular transmission */ #define SCATTERING_GLOSSY_TRANSMISSION \ (1 << 4) /*!< glossy transmission */ #define SCATTERING_DIFFUSE_TRANSMISSION \ (1 << 5) /*!< diffuse transmission */ /*! diffuse reflections and transmissions */ #define SCATTERING_DIFFUSE \ (SCATTERING_DIFFUSE_REFLECTION | SCATTERING_DIFFUSE_TRANSMISSION) /*! glossy reflections and transmissions */ #define SCATTERING_GLOSSY \ (SCATTERING_GLOSSY_REFLECTION | SCATTERING_GLOSSY_TRANSMISSION) /*! perfect specular reflections and transmissions */ #define SCATTERING_SPECULAR \ (SCATTERING_SPECULAR_REFLECTION | SCATTERING_SPECULAR_TRANSMISSION) /*! all possible reflections */ #define SCATTERING_REFLECTION \ (SCATTERING_DIFFUSE_REFLECTION | SCATTERING_GLOSSY_REFLECTION \ | SCATTERING_SPECULAR_REFLECTION) /*! all possible transmissions */ #define SCATTERING_TRANSMISSION \ (SCATTERING_DIFFUSE_TRANSMISSION | SCATTERING_GLOSSY_TRANSMISSION \ | SCATTERING_SPECULAR_TRANSMISSION) /*! all non-dirac types */ #define SCATTERING_SMOOTH (SCATTERING_DIFFUSE | SCATTERING_GLOSSY) /*! no component set */ #define SCATTERING_NONE 0 /*! all components set */ #define SCATTERING_ALL (SCATTERING_REFLECTION | SCATTERING_TRANSMISSION) OSPRAY_BEGIN_ISPC_NAMESPACE typedef uint32 Scattering_Type; struct Scattering_EvalRes { vec3f value; //!< radiance (multiplied by foreshortening factor for BSDFs) float pdf; }; // Note: the pdf of Dirac delta distributions is represented with inf. This is // possible, because in weight we already cancel the Dirac delta (but still // account for a changed pdf by e.g. discrete events such as component // selection). struct Scattering_SampleRes { vec3f weight; //!< radiance divided by pdf and multiplied by foreshortening //!< factor for BSDFs vec3f wi; float pdf; Scattering_Type type; }; OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/ShadowCatcher.ih000066400000000000000000000007641464752671100262160ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PathContext; struct PathState; struct PathVertex; struct Ray; struct RayCone; struct ScreenSample; SYCL_EXTERNAL bool shadowCatcher(const PathContext &pathContext, PathState &pathState, PathVertex &pathVertex, const Ray &ray, const RayCone &rayCone, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/ShadowCatcher.ispc000066400000000000000000000102711464752671100265460ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/pathtracer/PathStructs.ih" #include "render/pathtracer/PathTracerDefines.ih" #include "render/pathtracer/ShadowCatcher.ih" #include "render/pathtracer/TransparentShadow.ih" #include "render/Renderer.ih" #include "common/Ray.ih" #include "common/World.ih" #include "math/random.ih" // c++ shared #include "PathTracerDataShared.h" #include "lights/LightDispatch.ih" #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL bool shadowCatcher(const PathContext &pathContext, PathState &pathState, PathVertex &pathVertex, const Ray &ray, const RayCone &rayCone, const uniform FeatureFlagsHandler &ffh) { if (!(pathContext.context->backgroundRefraction ? pathState.specularTransmissionPath : pathState.straightPath)) return false; // TODO use MIS as well // consider real (flagged) geometries with material and move into light loop // (will also handle MIS) if (pathState.shadowCatcherDist <= ray.t && pathState.shadowCatcherDist > ray.t0) { // "postIntersect" of shadowCatcher plane pathVertex.dg.Ns = pathVertex.dg.Ng = make_vec3f(pathContext.context->shadowCatcherPlane); if (dot(ray.dir, pathVertex.dg.Ng) >= 0.f) pathVertex.dg.Ns = pathVertex.dg.Ng = neg(pathVertex.dg.Ng); pathVertex.dg.renderer = &pathContext.context->super; pathVertex.dg.P = ray.org + pathState.shadowCatcherDist * ray.dir; const float rayConeWidth = rayCone.width + rayCone.dwdt * pathState.shadowCatcherDist; // propagate to hit const float eps = calcEpsilon(pathVertex.dg.P, ray.dir, pathState.shadowCatcherDist); pathVertex.dg.P = pathVertex.dg.P + eps * pathVertex.dg.Ng; vec3f unshaded = make_vec3f(0.f); // illumination without occluders vec3f shaded = make_vec3f(0.f); // illumination including shadows const World *uniform world = pathContext.world; const uniform PathTracerData &pathtracerData = *((const uniform PathTracerData *)world->pathtracerData); // TODO use lightsSamples for (uniform uint32 i = 0; i < pathContext.numLights; i++) { const Light *uniform light = pathtracerData.lights[i]; float dummy; const vec2f s = LDSampler_get3LightSamples(pathState.ldSampler, i, true, dummy); Light_SampleRes ls = Light_dispatch_sample(light, pathVertex.dg, s, pathState.time, ffh); // skip when zero contribution from light if (reduce_max(ls.weight) <= 0.0f | ls.pdf <= PDF_CULLING) continue; // evaluate a white diffuse BRDF const float brdf = clamp(dot(ls.dir, pathVertex.dg.Ns)); // * one_over_pi cancels anyway // skip when zero contribution from material if (brdf <= 0.0f) continue; // test for shadows Ray shadowRay; setRay(shadowRay, pathVertex.dg.P, ls.dir, 0.0f, ls.dist, pathState.time); // connect ray cone to point on light RayCone shadowCone; shadowCone.width = rayConeWidth; shadowCone.dwdt = -rayConeWidth * rcp(ls.dist); // Trace ray in clipping geometries scene, fill array with ray intervals RayIntervals rayIntervals; traceClippingRay(pathContext.world, shadowRay, rayIntervals, ffh); const vec3f unshadedLightContrib = pathState.throughput * ls.weight * brdf; // * misHeuristic(pathContext, ls.pdf, brdf); unshaded = unshaded + unshadedLightContrib; shaded = shaded + transparentShadow(pathContext.context, pathContext.world, unshadedLightContrib, shadowRay, shadowCone, rayIntervals, pathState.currentMedium, ffh); } // order of args important to filter NaNs (in case unshaded.X is zero) const vec3f ratio = min( pathState.throughput * shaded * rcp(unshaded), pathState.throughput); // alpha blend-in black shadow pathState.throughput = ratio; pathState.contribution = make_vec3f(0.f); return true; } // update dist for potential next intersection (if transparent) pathState.shadowCatcherDist -= ray.t; return false; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/TransparentShadow.ih000066400000000000000000000012201464752671100271320ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "common/OSPCommon.ih" #include "render/materials/Medium.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PathTracer; struct World; struct Ray; struct RayCone; struct RayIntervals; SYCL_EXTERNAL __noinline vec3f transparentShadow( const uniform PathTracer *uniform self, const World *uniform world, vec3f lightContrib, Ray &shadowRay, RayCone &shadowCone, RayIntervals &rayIntervals, Medium medium, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/TransparentShadow.ispc000066400000000000000000000044111464752671100274750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/pathtracer/TransparentShadow.ih" #include "render/Material.ih" #include "render/MaterialDispatch.ih" #include "render/materials/Medium.ih" #include "common/Ray.ih" #include "common/World.ih" // c++ shared #include "PathTracerShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL __noinline vec3f transparentShadow( const uniform PathTracer *uniform self, const World *uniform world, vec3f lightContrib, Ray &shadowRay, RayCone &shadowCone, RayIntervals &rayIntervals, Medium medium, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); // It's not possible to have transparent shadows if we don't have any geometry if (!ff.geometry) { return lightContrib; } uniform uint32 maxDepth = self->super.maxDepth; const float tOriginal = shadowRay.t; const float widthOriginal = shadowCone.width; while (1) { traceGeometryRayIntervals(world, shadowRay, rayIntervals, ffh); if (noHit(shadowRay)) return lightContrib; DifferentialGeometry dg; postIntersect(world, &self->super, dg, shadowRay, shadowCone, DG_NS | DG_NG | DG_FACEFORWARD | DG_NORMALIZE | DG_TEXCOORD | DG_COLOR | DG_MOTIONBLUR, ffh); uniform Material *material = (uniform Material *)dg.material; vec3f transparency; foreach_unique (m in material) { if (m != NULL) { transparency = Material_dispatch_getTransparency(m, dg, shadowRay, medium, ffh); } } lightContrib = lightContrib * transparency; // compute attenuation with Beer's law if (ne(medium.attenuation, 0.f)) lightContrib = lightContrib * expf(medium.attenuation * (shadowRay.t - shadowRay.t0)); if (reduce_max(lightContrib) <= self->super.minContribution || --maxDepth <= 0) return make_vec3f(0.f); // Tracking medium if we hit a medium interface. foreach_unique (m in material) { if (m != NULL) { Material_dispatch_selectNextMedium(m, dg, medium, ffh); } } setRay(shadowRay, shadowRay.t + dg.epsilon, tOriginal); shadowCone.width = widthOriginal; } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/VirtualLight.ih000066400000000000000000000007341464752671100261120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct PathContext; struct PathState; struct PathVertex; struct Ray; SYCL_EXTERNAL vec3f evaluateVirtualLights(const PathContext &pathContext, PathState &pathState, const PathVertex &lastVertex, const PathVertex &pathVertex, Ray &ray, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/VirtualLight.ispc000066400000000000000000000070661464752671100264550ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/World.ih" #include "render/pathtracer/PathStructs.ih" #include "render/pathtracer/PathTracerUtil.ih" #include "render/pathtracer/VirtualLight.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "render/pathtracer/volumes/VolumeSampler.ih" #endif // c++ shared #include "lights/LightDispatch.ih" #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline box1f getMinMaxDistForVirtualLights( const PathVertex &lastVertex, const PathVertex &pathVertex, const Ray &ray) { box1f interval; // minimal distance is not always zero (when previously sampled a Dirac // transmission) interval.lower = distance(lastVertex.dg.P, ray.org); // virtual lights are occluded by hit geometry // because lastVertex.dg.P can be different from ray.org (when previously // sampled a Dirac transmission) we cannot just use ray.t as maximum distance interval.upper = distance(lastVertex.dg.P, ray.org + ray.t * ray.dir); if (pathVertex.type == ENVIRONMENT) interval.upper = inf; return interval; } // add light from *virtual* lights by intersecting them SYCL_EXTERNAL vec3f evaluateVirtualLights(const PathContext &pathContext, PathState &pathState, const PathVertex &lastVertex, const PathVertex &pathVertex, Ray &ray, const uniform FeatureFlagsHandler &ffh) { vec3f L = make_vec3f(0.f); if (pathContext.numLights <= pathContext.numGeoLights) return L; // return if no virtual lights at all box1f intervalLightDist = getMinMaxDistForVirtualLights(lastVertex, pathVertex, ray); // at the moment we only support uniform light selection // therefore we can evaluate the selection PDF directly const float selectionPDF = lastVertex.numLightSamples / (float)pathContext.numLights; for (uniform uint32 i = pathContext.numGeoLights; i < pathContext.numLights; i++) { const Light *uniform light = pathContext.lights[i]; if (!pathState.straightPath || light->isVisible) { // to correctly handle MIS through transparencies the light pdf needs to // be calculated wrt. lastVertex.dg // however, we only have a valid intersection with the light in // [minLightDist, maxLightDist], otherwise light could be added twice Light_EvalRes le = Light_dispatch_eval(light, lastVertex.dg, ray.dir, intervalLightDist.lower, intervalLightDist.upper, pathState.time, ffh); if (reduce_max(le.radiance) > 0.0f) { float misWeight = 1.0f; if (selectionPDF) { float T = 1.f; #ifdef OSPRAY_ENABLE_VOLUMES Ray shadowRay; setRay(shadowRay, lastVertex.dg.P, ray.dir, intervalLightDist.lower, intervalLightDist.upper, ray.time); // Trace ray in clipping geometries scene, fill array with ray // intervals RayIntervals rayIntervals; traceClippingRay(pathContext.world, shadowRay, rayIntervals, ffh); const uniform FeatureFlags ff = getFeatureFlags(ffh); if (ff.other & FFO_VOLUME_IN_SCENE) { T = volumeTransmittance(pathContext.world, shadowRay, rayIntervals, &pathState.randomSampler, ffh); } #endif misWeight = misHeuristic( pathContext, lastVertex.pdf_w * T, selectionPDF * le.pdf); } L = L + pathState.throughput * le.radiance * misWeight; } } } return L; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/pathtracer/volumes/000077500000000000000000000000001464752671100246405ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/pathtracer/volumes/HenyeyGreenstein.ih000066400000000000000000000036741464752671100304610ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "render/pathtracer/Scattering.ih" #include "math/sampling.ih" #include "rkcommon/math/LinearSpace.ih" OSPRAY_BEGIN_ISPC_NAMESPACE inline float hg(float cosTheta, float g) { float denom = 1.f + g * g - 2.f * g * cosTheta; return rcp(4.f * (float)pi) * (1.f - g * g) * rcp(denom * sqrt(denom)); } inline bool HenyeyGreenstein_isSmooth(float anisotropy) { if (abs(anisotropy) > 1.f - 1e-3f) { return false; } return true; } inline Scattering_EvalRes HenyeyGreenstein_eval( float anisotropy, const vec3f &wo, const vec3f &wi) { Scattering_EvalRes res; if (!HenyeyGreenstein_isSmooth(anisotropy)) { res.pdf = 0.f; res.value = make_vec3f(res.pdf); } res.pdf = hg(dot(neg(wo), wi), anisotropy); res.value = make_vec3f(res.pdf); return res; } inline Scattering_SampleRes HenyeyGreenstein_sample( float anisotropy, const vec3f wo, const vec2f s, float) { Scattering_SampleRes res; res.weight = make_vec3f(1.f); const float g = anisotropy; float cosTheta; if (!HenyeyGreenstein_isSmooth(anisotropy)) { // special case for delta function res.wi = g > 0 ? neg(wo) : wo; res.pdf = inf; res.type = g > 0 ? SCATTERING_SPECULAR_TRANSMISSION : SCATTERING_SPECULAR_REFLECTION; return res; } else if (abs(g) < 1e-3f) { // special case for isotropic scattering cosTheta = 1.f - 2.f * s.x; } else { // general case float sqrTerm = (1.f - g * g) * rcp(1.f - g + 2.f * g * s.x); cosTheta = (1.f + g * g - sqrTerm * sqrTerm) * rcp(2.f * g); } res.type = SCATTERING_SMOOTH; float sinTheta = sqrt(max(0.f, 1.f - cosTheta * cosTheta)); float phi = 2.f * M_PI * s.y; const vec3f localDir = cartesian(phi, sinTheta, cosTheta); res.wi = frame(neg(wo)) * localDir; res.pdf = hg(cosTheta, g); return res; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/pathtracer/volumes/VolumeSampler.ih000066400000000000000000000021451464752671100277570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "common/FeatureFlagsEnum.h" #include "render/pathtracer/PathStructs.ih" #include "render/pathtracer/volumes/HenyeyGreenstein.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct World; struct LDSampler; struct RandomSampler; struct Ray; struct RayIntervals; SYCL_EXTERNAL float volumeSampleFreePath(const World *uniform world, Ray &ray, RayIntervals &rayIntervals, varying RandomSampler *uniform randomSampler, const VolumetricModel *varying *uniform sampledInstance, float &sampledExtinctionCoefficient, vec3f &sampledAlbedo, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL float volumeTransmittance(const World *uniform world, Ray &ray, RayIntervals &rayIntervals, varying RandomSampler *uniform randomSampler, const uniform FeatureFlagsHandler &ffh); inline bool isSmoothVolumeVertex(const PathVertex &pathVertex) { return HenyeyGreenstein_isSmooth(pathVertex.volume->anisotropy); } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/pathtracer/volumes/VolumeSampler.ispc000066400000000000000000000202501464752671100303120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "common/FeatureFlagsEnum.h" #include "common/World.ih" #include "math/random.ih" #include "render/pathtracer/volumes/VolumeSampler.ih" #include "volume/transferFunction/TransferFunctionDispatch.ih" OSPRAY_BEGIN_ISPC_NAMESPACE float delta_tracking(const VolumetricModel *uniform vModel, const range1f &rInterval, varying RandomSampler *uniform randomSampler, const vec3f &o, const vec3f &w, const float &time, float &mu_t, // sampled extinction coefficint vec3f &albedo, const uniform FeatureFlagsHandler &ffh) // sampled albedo (color) { const uniform FeatureFlags ff = getFeatureFlags(ffh); #ifdef OSPRAY_TARGET_SYCL // No alloca on GPU, need to be conservative for now and use the // VKL_MAX_INTERVAL_ITERATOR_SIZE uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; #else void *uniform intervalIteratorBuffer = alloca(vklGetIntervalIteratorSizeV(&vModel->vklIntervalContext)); #endif VKLIntervalIterator intervalIterator = vklInitIntervalIteratorV(&vModel->vklIntervalContext, (varying vkl_vec3f *)&o, (varying vkl_vec3f *)&w, (varying vkl_range1f *)&rInterval, #ifndef OSPRAY_TARGET_SYCL & #endif time, intervalIteratorBuffer #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ); float t = 0.f; VKLInterval interval; while (vklIterateIntervalV(intervalIterator, &interval #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif )) { t = interval.tRange.lower; const float maxOpacity = TransferFunction_dispatch_getMaxOpacity(vModel->transferFunction, *((varying range1f * uniform) & interval.valueRange)); const float mu_max = vModel->densityScale * maxOpacity; if (mu_max <= 0.f) continue; while (true) { float xi = RandomSampler_getFloat(randomSampler); const float dt = -log(1.f - xi) / mu_max; t += dt; if (t > interval.tRange.upper) break; xi = RandomSampler_getFloat(randomSampler); const vec3f p = o + t * w; const float sample = vklComputeSampleV(&vModel->volume->vklSampler, (const varying vkl_vec3f *uniform) & p #ifdef OSPRAY_TARGET_SYCL , 0, time, ff.volume #endif ); if (isnan(sample)) continue; const vec4f color = TransferFunction_dispatch_get(vModel->transferFunction, sample); mu_t = vModel->densityScale * color.w; if (xi < mu_t / mu_max) { albedo = make_vec3f(color); return t; } } } return inf; } SYCL_EXTERNAL float volumeSampleFreePath(const World *uniform world, Ray &ray, RayIntervals &rayIntervals, varying RandomSampler *uniform randomSampler, const VolumetricModel *varying *uniform sampledInstance, float &sampledExtinctionCoefficient, vec3f &sampledAlbedo, const uniform FeatureFlagsHandler &ffh) { #ifdef OSPRAY_TARGET_SYCL // We only support a single volume interval on the GPU VolumeInterval vInterval; VolumeIntervals volumeIntervals; volumeIntervals.numVolumeIntervals = 0; volumeIntervals.numAllocated = 1; volumeIntervals.intervals = &vInterval; #else VolumeIntervals volumeIntervals; allocVolumeIntervals(volumeIntervals); #endif // Get volume intervals Ray volumeRay = ray; traceVolumeRay(world, volumeRay, volumeIntervals); // Iterate through volume intervals float min_dist = inf; unmasked { *sampledInstance = NULL; } for (uniform uint32 i = 0; i < reduce_max(volumeIntervals.numVolumeIntervals); i++) { if (i >= volumeIntervals.numVolumeIntervals) break; range1f vInterval = volumeIntervals.intervals[i].interval; vInterval.lower = max(0.f, vInterval.lower); vInterval.upper = noHit(ray) ? vInterval.upper : min(vInterval.upper, ray.t); if (isEmpty(vInterval)) continue; AffineSpace3f xfm; foreach_unique (inst in volumeIntervals.intervals[i].instance) xfm = Instance_getTransform(inst, volumeRay.time); Ray transformedVolumeRay = volumeRay; transformRay(transformedVolumeRay, rcp(xfm)); VolumetricModel *varying instance = volumeIntervals.intervals[i].volumetricModel; foreach_unique (inst in instance) { for (uint32 j = 0; j < rayIntervals.count; j++) { range1f rInterval = rayIntervals.intervals[j]; // Skip ray intervals outside of the volume range if (vInterval.upper < rInterval.lower || rInterval.upper < vInterval.lower) { continue; } // Clip ray interval to the volume range rInterval.lower = max(rInterval.lower, vInterval.lower); rInterval.upper = min(rInterval.upper, vInterval.upper); float extinctionCoefficient; vec3f albedo; const float dist = delta_tracking(inst, rInterval, randomSampler, transformedVolumeRay.org, transformedVolumeRay.dir, transformedVolumeRay.time, extinctionCoefficient, albedo, ffh); if (dist < inf) { if (dist < min_dist) { min_dist = dist; *sampledInstance = inst; sampledExtinctionCoefficient = extinctionCoefficient; sampledAlbedo = albedo; ray.t = dist; ray.primID = 0; ray.geomID = volumeIntervals.intervals[i].geomID; ray.instID = volumeIntervals.intervals[i].instID; } break; } } } } #ifndef OSPRAY_TARGET_SYCL freeVolumeIntervals(volumeIntervals); #endif return min_dist; } SYCL_EXTERNAL float volumeTransmittance(const World *uniform world, Ray &ray, RayIntervals &rayIntervals, varying RandomSampler *uniform randomSampler, const uniform FeatureFlagsHandler &ffh) { #ifdef OSPRAY_TARGET_SYCL // We only support a single volume interval on the GPU VolumeInterval vInterval; VolumeIntervals volumeIntervals; volumeIntervals.numVolumeIntervals = 0; volumeIntervals.numAllocated = 1; volumeIntervals.intervals = &vInterval; #else VolumeIntervals volumeIntervals; allocVolumeIntervals(volumeIntervals); #endif // Get volume intervals Ray volumeRay = ray; traceVolumeRay(world, volumeRay, volumeIntervals); // Iterate through volume intervals float transmittance = 1.f; for (uint32 i = 0; i < volumeIntervals.numVolumeIntervals && transmittance > 0.f; i++) { range1f vInterval = volumeIntervals.intervals[i].interval; vInterval.lower = max(ray.t0, vInterval.lower); vInterval.upper = noHit(ray) ? vInterval.upper : min(vInterval.upper, ray.t); if (isEmpty(vInterval)) continue; AffineSpace3f xfm; foreach_unique (inst in volumeIntervals.intervals[i].instance) xfm = Instance_getTransform(inst, volumeRay.time); Ray transformedVolumeRay = volumeRay; transformRay(transformedVolumeRay, rcp(xfm)); VolumetricModel *varying instance = volumeIntervals.intervals[i].volumetricModel; foreach_unique (inst in instance) { for (uint32 j = 0; j < rayIntervals.count && transmittance > 0.f; j++) { range1f rInterval = rayIntervals.intervals[j]; // Skip ray intervals outside of the volume range if (vInterval.upper < rInterval.lower || rInterval.upper < vInterval.lower) { continue; } // Clip ray interval to the volume range rInterval.lower = max(rInterval.lower, vInterval.lower); rInterval.upper = min(rInterval.upper, vInterval.upper); float extinctionCoefficient; vec3f albedo; const float dist = delta_tracking(inst, rInterval, randomSampler, transformedVolumeRay.org, transformedVolumeRay.dir, transformedVolumeRay.time, extinctionCoefficient, albedo, ffh); transmittance = transmittance * ((dist < rInterval.upper) ? 0.f : 1.f); } } } #ifndef OSPRAY_TARGET_SYCL freeVolumeIntervals(volumeIntervals); #endif return transmittance; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/registration.cpp000066400000000000000000000031571464752671100242350ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ao/AORenderer.h" #include "debug/DebugRenderer.h" #include "pathtracer/PathTracer.h" #include "scivis/SciVis.h" #include "materials/Alloy.h" #include "materials/CarPaint.h" #include "materials/Glass.h" #include "materials/Luminous.h" #include "materials/Metal.h" #include "materials/MetallicPaint.h" #include "materials/Mix.h" #include "materials/OBJ.h" #include "materials/Plastic.h" #include "materials/Principled.h" #include "materials/ThinGlass.h" #include "materials/Velvet.h" using namespace ospray::pathtracer; namespace ospray { void registerAllRenderers() { Renderer::registerType("debug"); Renderer::registerType("pathtracer"); Renderer::registerType("scivis"); Renderer::registerType("ao"); } void registerAllMaterials() { Material::registerType("alloy"); Material::registerType("carPaint"); Material::registerType("glass"); Material::registerType("luminous"); Material::registerType("metal"); Material::registerType("metallicPaint"); #ifndef OSPRAY_TARGET_SYCL // Mix material isn't going to work on the GPU b/c we can't have // recursive calls and it may nest MultiBSDFs. Needs some special treatment Material::registerType("mix"); #endif Material::registerType("obj"); Material::registerType("plastic"); Material::registerType("principled"); Material::registerType("thinGlass"); Material::registerType("velvet"); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/registration.h000066400000000000000000000002611464752671100236730ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllRenderers(); void registerAllMaterials(); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/scivis/000077500000000000000000000000001464752671100223115ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVis.cpp000066400000000000000000000043501464752671100242170ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "SciVis.h" #include "SciVisData.h" #include "camera/Camera.h" #include "common/DeviceRT.h" #include "common/FeatureFlagsEnum.h" #include "common/World.h" #include "fb/FrameBuffer.h" // Kernel launcher is defined in another compilation unit DECLARE_RENDERER_KERNEL_LAUNCHER(SciVis_renderTaskLauncher); namespace ospray { SciVis::SciVis(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) {} std::string SciVis::toString() const { return "ospray::render::SciVis"; } void SciVis::commit() { Renderer::commit(); getSh()->shadowsEnabled = getParam("shadows", false); getSh()->visibleLights = getParam("visibleLights", false); getSh()->aoSamples = getParam("aoSamples", 0); getSh()->aoRadius = getParam("aoDistance", 1e20f); getSh()->volumeSamplingRate = getParam("volumeSamplingRate", 1.f); } void *SciVis::beginFrame(FrameBuffer *, World *world) { if (!world) return nullptr; if (world->scivisData.get()) return nullptr; // Create SciVisData object std::unique_ptr scivisData = rkcommon::make_unique(*world); world->getSh()->scivisData = scivisData->getSh(); world->scivisData = std::move(scivisData); return nullptr; } devicert::AsyncEvent SciVis::renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *, const utility::ArrayView &taskIDs) const { // Gather feature flags from all components FeatureFlags ff = world->getFeatureFlags(); ff |= featureFlags; ff |= fb->getFeatureFlags(); ff |= camera->getFeatureFlags(); // Prepare parameters for kernel launch auto *rendererSh = &getSh()->super; auto *fbSh = fb->getSh(); auto *cameraSh = camera->getSh(); auto *worldSh = world->getSh(); const size_t numTasks = taskIDs.size(); const vec2i taskSize = fb->getRenderTaskSize(); const vec3ui itemDims = vec3ui(taskSize.x, taskSize.y, numTasks); // Launch rendering kernel on the device return drtDevice.launchRendererKernel(itemDims, ispc::SciVis_renderTaskLauncher, rendererSh, fbSh, cameraSh, worldSh, taskIDs.data(), ff); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVis.h000066400000000000000000000011531464752671100236620ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "render/Renderer.h" // ispc shared #include "SciVisShared.h" namespace ospray { struct SciVis : public AddStructShared { SciVis(api::ISPCDevice &device); std::string toString() const override; void commit() override; void *beginFrame(FrameBuffer *, World *) override; virtual devicert::AsyncEvent renderTasks(FrameBuffer *fb, Camera *camera, World *world, void *perFrameData, const utility::ArrayView &taskIDs) const override; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVis.ih000066400000000000000000000022271464752671100240360ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/FeatureFlags.ih" #include "render/ScreenSample.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Renderer; struct SciVis; struct FrameBuffer; struct ScreenSample; struct World; struct RandomSampler; struct DifferentialGeometry; struct SciVisRenderContext { const SciVis *uniform renderer; const FrameBuffer *uniform fb; const World *uniform world; ScreenSample sample; varying RandomSampler *uniform randomSampler; }; SYCL_EXTERNAL vec3f lightAlpha(const uniform SciVis *uniform self, Ray &ray, RayCone &shadowCone, const World *uniform world, RandomSampler &randomSampler, vec3f weight, uniform float quality, const uniform FeatureFlagsHandler &ffh); SYCL_EXTERNAL vec3f SciVis_computeAO(const uniform SciVis *uniform self, const World *uniform world, RandomSampler &randomSampler, const varying DifferentialGeometry &dg, const float coneWidth, const uniform int sampleCnt, const uniform float aoRadius, const varying vec3i &sampleID, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVis.ispc000066400000000000000000000231721464752671100243760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "SciVis.ih" #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/DeviceRT.ih" #include "common/FeatureFlagsEnum.h" #include "common/World.ih" #include "fb/FrameBuffer.ih" #include "fb/FrameBufferDispatch.ih" #include "fb/RenderTaskDesc.ih" #include "math/random.ih" #include "math/sampling.ih" #include "pf/PixelFilterDispatch.ih" #include "surfaces.ih" #include "volume/VolumetricModel.ih" #include "volumes.ih" // c++ shared #include "SciVisShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE static void SciVis_renderSample(Renderer *uniform _self, FrameBuffer *uniform fb, World *uniform world, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { uniform SciVis *uniform self = (uniform SciVis * uniform) _self; const uniform FeatureFlags ff = getFeatureFlags(ffh); RandomSampler randomSampler; RandomSampler_init(&randomSampler, sample.sampleID.x + fb->size.x * sample.sampleID.y, sample.sampleID.z); uniform bool firstHit = true; bool allHitsFullyTransmissive = true; const float originalRayTFar = sample.ray.t; #ifdef OSPRAY_ENABLE_VOLUMES #ifdef OSPRAY_TARGET_SYCL // We only support a single volume interval on the GPU VolumeInterval vInterval; VolumeIntervals volumeIntervals; volumeIntervals.numVolumeIntervals = 0; volumeIntervals.numAllocated = 1; volumeIntervals.intervals = &vInterval; #else // Allocate memory for volume intervals VolumeIntervals volumeIntervals; allocVolumeIntervals(volumeIntervals); #endif #endif // This is our main ray Ray &ray = sample.ray; RayCone &rayCone = sample.rayCone; // First trace the ray across clipping scene to calculate ray intervals, // this step should keep ray structure unchanged RayIntervals rayIntervals; traceClippingRay(world, ray, rayIntervals, ffh); // Iterate over all translucent geometry till we are fully opaque vec3f outColor = make_vec3f(0.f); vec3f outTransmission = make_vec3f(1.f); while (true) { if (ff.geometry) { // Then trace normal geometry using calculated ray intervals, // if hit ray.t will be updated traceGeometryRayIntervals(world, ray, rayIntervals, ffh); } #ifdef OSPRAY_ENABLE_VOLUMES Ray volumeRay = ray; if (ff.other & FFO_VOLUME_IN_SCENE) { // Determine volume intervals by tracing ray in the volume scene traceVolumeRay(world, volumeRay, volumeIntervals); // Sample volumes across volume intervals (in front of geometry hit) if (volumeIntervals.numVolumeIntervals > 0) { SciVisRenderContext rc; rc.renderer = self; rc.fb = fb; rc.world = world; rc.sample = sample; rc.randomSampler = &randomSampler; volumeRay.geomID = RTC_INVALID_GEOMETRY_ID; vec4f volumeColor = integrateVolumeIntervalsGradient(rc, volumeIntervals, rayIntervals, volumeRay, randomSampler, self->volumeSamplingRate, ffh); // Blend volume outColor = outColor + outTransmission * make_vec3f(volumeColor); outTransmission = outTransmission * volumeColor.w; if (hadHit(volumeRay) && sample.geomID == RTC_INVALID_GEOMETRY_ID) { sample.primID = 0; foreach_unique (instID in volumeRay.instID) { if (instID != RTC_INVALID_GEOMETRY_ID) { const Instance *uniform instance = *(world->instances + instID); sample.instID = (instance->userID == RTC_INVALID_GEOMETRY_ID) ? instID : instance->userID; const VolumetricModel *volms = *(instance->group->volumetricModels + volumeRay.geomID); foreach_unique (volm in volms) { sample.geomID = (volm->userID == RTC_INVALID_GEOMETRY_ID) ? volumeRay.geomID : volm->userID; } } } } } } #endif // Add contribution from visible lights, P is used by light // evaluation DifferentialGeometry dg; if (self->visibleLights) { dg.P = ray.org; outColor = outColor + outTransmission * evaluateLights(world, dg, ray, ffh); } // If any geometry has been hit const bool rayHadHit = hadHit(ray); if (ff.geometry && rayHadHit) { // Prepare differential geometry structure postIntersect(world, &self->super, dg, ray, rayCone, DG_NG | DG_NS | DG_NORMALIZE | DG_FACEFORWARD | DG_COLOR | DG_TANGENTS | DG_TEXCOORD, ffh); // Shade geometry SSI surfaceShading; surfaceShading = SciVis_computeShading( self, world, dg, sample, randomSampler, ray.dir, rayCone.width, ffh); // Initialize other per sample data with first hit values // In addition to considering the first hit, all previous, fully // transmissive hits will lead the normal/albedo to be replaced by the // current hit if (firstHit || allHitsFullyTransmissive) { #ifdef OSPRAY_ENABLE_VOLUMES sample.z = min(ray.t, volumeRay.t); #endif sample.albedo = surfaceShading.albedo; sample.normal = dg.Ns; if (sample.geomID == RTC_INVALID_GEOMETRY_ID) { sample.instID = dg.instID; sample.geomID = dg.objID; sample.primID = ray.primID; } firstHit = false; } // A sequence of hits is considered fully transparent if it's total // normalized transmission is close to 1.0f and all previous hits were // fully transmissive allHitsFullyTransmissive = allHitsFullyTransmissive && surfaceShading.opacity < self->super.minContribution; // Blend with output final color outColor = outColor + outTransmission * surfaceShading.shadedColor; outTransmission = outTransmission * surfaceShading.transmission; // Early exit if remaining transmission is below min contribution // threshold if (luminance(outTransmission) < self->super.minContribution) { outTransmission = make_vec3f(0.f); break; } // Prepare ray for next loop iteration, // start from the last geometry hit all over to initial Tfar setRay(ray, ray.t + dg.epsilon, originalRayTFar); } else { // Blend background with output final color vec4f backgroundColor = Renderer_getBackground(&self->super, sample.pos, ffh); outColor = outColor + outTransmission * make_vec3f(backgroundColor); outTransmission = outTransmission * (1.f - backgroundColor.w); // Initialize other per sample data with first hit values // If the ray hits the background and comes from a fully transmissive // path, we overwrite normals/albedo by background values if (firstHit || allHitsFullyTransmissive) { #ifdef OSPRAY_ENABLE_VOLUMES sample.z = min(ray.t, volumeRay.t); #endif sample.albedo = make_vec3f(backgroundColor); // TODO volume albedo sample.normal = make_vec3f(0.f); } // No more intersections break; } } #if defined(OSPRAY_ENABLE_VOLUMES) && !defined(OSPRAY_TARGET_SYCL) // Only a single interval is supported on the GPU, we don't allocate // dynamically freeVolumeIntervals(volumeIntervals); #endif sample.rgb = outColor; sample.alpha = 1.f - luminance(outTransmission); } SYCL_EXTERNAL vec3f SciVis_computeAO(const uniform SciVis *uniform self, const World *uniform world, RandomSampler &randomSampler, const varying DifferentialGeometry &dg, const float coneWidth, const uniform int sampleCnt, const uniform float aoRadius, const varying vec3i &sampleID, const uniform FeatureFlagsHandler &ffh) { const uniform int accumID = reduce_max(sampleID.z) * sampleCnt; // init TEA RNG // RandomTEA rng_state; varying RandomTEA *const uniform rng = &rng_state; RandomTEA_Constructor(rng, sampleID.x, sampleID.y); const vec2f rot = RandomTEA_getFloats(rng); vec3f hits = make_vec3f(0.f); const linear3f localToWorld = frame(dg.Ns); for (uniform int i = 0; i < sampleCnt; i++) { // Use base-5 and base-7 Halton to avoid correlation with sample position const vec2f halton = make_vec2f( PermHalton_sample5(accumID + i), PermHalton_sample7(accumID + i)); const vec2f r = CranleyPattersonRotation(halton, rot); const vec3f local_ao_dir = cosineSampleHemisphere(r); const vec3f ao_dir = localToWorld * local_ao_dir; if (dot(ao_dir, dg.Ns) < 0.01f) { // check below surface hits = hits + 1.f; continue; } Ray ao_ray; setRay(ao_ray, dg.P, ao_dir, dg.epsilon, aoRadius); RayCone shadowCone; shadowCone.width = coneWidth; shadowCone.dwdt = 0.0f; // constant for AO hits = hits + (1.f - lightAlpha(self, ao_ray, shadowCone, world, randomSampler, make_vec3f(1.f), 0.1f, ffh)); } // the cosTheta of cosineSampleHemispherePDF and dot(shadingNormal, ao_dir) // cancel return 1.0f - (hits / (float)sampleCnt); } #define renderSampleFn SciVis_renderSample #include "render/RendererRenderTaskFn.inl" #undef renderSampleFn inline void SciVis_renderTask(const uniform vec3ui itemIndex, Renderer *uniform self, FrameBuffer *uniform fb, Camera *uniform camera, World *uniform world, const uint32 *uniform taskIDs, const uniform FeatureFlagsHandler &ffh) { Renderer_default_renderTask(itemIndex, self, fb, camera, world, taskIDs, ffh); } DEFINE_RENDERER_KERNEL_LAUNCHER(SciVis_renderTask); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVisData.cpp000066400000000000000000000062521464752671100250140ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "SciVisData.h" #include "common/Instance.h" #include "common/World.h" #include "lights/AmbientLight.h" #include "lights/HDRILight.h" #include "lights/SunSkyLight.h" // ispc shared #include "lights/LightShared.h" namespace ospray { namespace { void addVisibleOnlyToArray(std::vector &lightShs, uint32_t &visibleOnly, ispc::Light *lightSh) { if (visibleOnly == lightShs.size()) lightShs.push_back(lightSh); else { // insert light at the visibleOnly index lightShs.push_back(lightShs[visibleOnly]); lightShs[visibleOnly] = lightSh; } visibleOnly++; } vec3f addLightsToArray(std::vector &lightShs, uint32_t &visibleOnly, Ref> lights, const ispc::Instance *instanceSh) { vec3f aoColor = vec3f(0.f); for (auto &&light : *lights) { // just extract color from ambient lights const auto ambient = dynamic_cast(light); if (ambient) { addVisibleOnlyToArray( lightShs, visibleOnly, light->createSh(0, instanceSh)); aoColor += ambient->radiance; continue; } // no illumination from HDRI lights const auto hdri = dynamic_cast(light); if (hdri) { addVisibleOnlyToArray( lightShs, visibleOnly, light->createSh(0, instanceSh)); continue; } // sun-sky: only sun illuminates const auto sunsky = dynamic_cast(light); if (sunsky) { addVisibleOnlyToArray(lightShs, visibleOnly, light->createSh(0, instanceSh)); // sky visible only lightShs.push_back(light->createSh(1, instanceSh)); // sun continue; } // handle the remaining types of lights for (uint32_t id = 0; id < light->getShCount(); id++) lightShs.push_back(light->createSh(id, instanceSh)); } return aoColor; } } // namespace SciVisData::SciVisData(const World &world) : AddStructShared(world.getISPCDevice().getDRTDevice()) { std::vector lightShs; vec3f aoColor = vec3f(0.f); uint32_t visibleOnly = 0; // Add lights not assigned to any instance if (world.lights) aoColor += addLightsToArray(lightShs, 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; // Add instance lights to array aoColor += addLightsToArray( lightShs, visibleOnly, inst->group->lights, inst->getSh()); } } // Then create shared buffer from the temporary std::vector lightArray = devicert::make_buffer_shared_unique( world.getISPCDevice().getDRTDevice(), lightShs); getSh()->lights = lightArray->sharedPtr(); getSh()->numLights = lightArray->size(); getSh()->numLightsVisibleOnly = visibleOnly; getSh()->aoColorPi = aoColor * float(pi); } SciVisData::~SciVisData() { // Delete all lights structures devicert::Device &device = lightArray->getDevice(); for (ispc::Light *lptr : *lightArray) device.free(lptr); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVisData.h000066400000000000000000000007071464752671100244600ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/StructShared.h" #include "render/RendererData.h" // ispc shared #include "SciVisDataShared.h" namespace ospray { struct World; struct SciVisData : public AddStructShared { SciVisData(const World &world); ~SciVisData() override; private: BufferSharedUq lightArray; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVisDataShared.h000066400000000000000000000013471464752671100256100ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus 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; #ifdef __cplusplus SciVisData() : lights(nullptr), numLights(0), numLightsVisibleOnly(0), aoColorPi(0.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/scivis/SciVisShared.h000066400000000000000000000010551464752671100250120ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/RendererShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct SciVis { Renderer super; bool shadowsEnabled; bool visibleLights; int aoSamples; float aoRadius; float volumeSamplingRate; #ifdef __cplusplus SciVis() : shadowsEnabled(false), visibleLights(false), aoSamples(0), aoRadius(1e20f), volumeSamplingRate(1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/render/scivis/lightAlpha.ispc000066400000000000000000000067031464752671100252540ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #include "math/random.ih" #include "math/sampling.ih" #include "render/util.ih" // SciVis renderer #include "surfaces.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "render/ao/volumes.ih" #endif // c++ shared #include "SciVisShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // Lighting functions // SYCL_EXTERNAL vec3f lightAlpha(const uniform SciVis *uniform self, Ray &ray, RayCone &shadowCone, const World *uniform world, RandomSampler &randomSampler, vec3f weight, uniform float quality, const uniform FeatureFlagsHandler &ffh) { vec3f alpha = make_vec3f(1.f); const float org_t_max = ray.t; const float org_width = shadowCone.width; #ifdef OSPRAY_ENABLE_VOLUMES const uniform FeatureFlags ff = getFeatureFlags(ffh); #ifdef OSPRAY_TARGET_SYCL // We only support a single volume interval on the GPU VolumeInterval vInterval; VolumeIntervals volumeIntervals; volumeIntervals.numVolumeIntervals = 0; volumeIntervals.numAllocated = 1; volumeIntervals.intervals = &vInterval; #else // Allocate memory for volume intervals VolumeIntervals volumeIntervals; allocVolumeIntervals(volumeIntervals); #endif #endif // First trace the ray across clipping scene to calculate ray intervals, // this step should keep ray structure unchanged RayIntervals rayIntervals; traceClippingRay(world, ray, rayIntervals, ffh); while (true) { // Then trace normal geometry using calculated ray intervals, // if hit ray.t will be updated // WA for https://jira.devtools.intel.com/browse/XDEPS-4875 #ifndef OSPRAY_TARGET_SYCL traceGeometryRayIntervals(world, ray, rayIntervals, ffh); #else traceGeometryRay(world, ray, ffh); #endif #ifdef OSPRAY_ENABLE_VOLUMES if (ff.other & FFO_VOLUME_IN_SCENE) { // Determine volume intervals by tracing ray in the volume scene Ray volumeRay = ray; traceVolumeRay(world, volumeRay, volumeIntervals); // Sample volumes across volume intervals (in front of geometry hit) if (volumeIntervals.numVolumeIntervals > 0) { vec4f volumeColor = integrateVolumeIntervals(volumeIntervals, rayIntervals, volumeRay, randomSampler, self->volumeSamplingRate * quality, ffh); alpha = alpha * make_vec3f(1.f - volumeColor.w); } } #else (void)randomSampler; (void)quality; #endif // If any geometry has been hit const bool rayHadHit = hadHit(ray); if (rayHadHit) { // Prepare differential geometry structure DifferentialGeometry dg; postIntersect(world, &self->super, dg, ray, shadowCone, DG_COLOR | DG_TEXCOORD, ffh); const SciVisBSDF bsdf = evalMaterial(dg, ffh); alpha = alpha * bsdf.transmission; // Prepare ray for next loop iteration, // start from the last geometry hit all over to initial Tfar setRay(ray, ray.t + dg.epsilon, org_t_max); shadowCone.width = org_width; } else { break; } // Check if there is enough contribution from this light if (luminance(alpha * weight) < self->super.minContribution) { alpha = make_vec3f(0.f); break; } } #if defined(OSPRAY_ENABLE_VOLUMES) && !defined(OSPRAY_TARGET_SYCL) // No dynamic allocation on GPU freeVolumeIntervals(volumeIntervals); #endif return alpha; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/scivis/surfaces.ih000066400000000000000000000050141464752671100244460ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "SciVis.ih" #include "common/FeatureFlagsEnum.h" #include "render/Material.ih" #include "render/materials/OBJ.ih" // c++ shared #include "render/materials/OBJShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE struct SurfaceShadingInfo { vec3f shadedColor; vec3f transmission; vec3f albedo; float opacity; }; typedef SurfaceShadingInfo SSI; SYCL_EXTERNAL __noinline SSI SciVis_computeShading(const SciVis *uniform self, const World *uniform world, const DifferentialGeometry &dg, ScreenSample &sample, RandomSampler &randomSampler, const varying vec3f &inDir, const float coneWidth, const uniform FeatureFlagsHandler &ff); SYCL_EXTERNAL vec3f evaluateLights(const World *uniform world, const DifferentialGeometry &dg, const Ray &ray, const uniform FeatureFlagsHandler &ffh); struct SciVisBSDF { vec3f diffuse; vec3f specular; float shininess; vec3f transmission; vec3f albedo; float opacity; }; inline SciVisBSDF evalMaterial( const DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlagsOther ffo = getFeatureFlagsOther(ffh); const OBJ *mat = (const OBJ *)dg.material; // defaults SciVisBSDF res; res.diffuse = make_vec3f(dg.color); res.specular = make_vec3f(0.0f); res.shininess = 10.0f; res.transmission = make_vec3f(1.f - dg.color.w); res.opacity = dg.color.w; foreach_unique (m in mat) { if (m != NULL && m->super.type == MATERIAL_TYPE_OBJ) { float d = m->d * get1f_ff(m->dMap, dg, 1.f, ffh) * dg.color.w; res.diffuse = res.diffuse * m->Kd; if (valid(m->KdMap) && (ffo & FFO_TEXTURE_IN_MATERIAL)) { vec4f Kd_from_map = get4f(m->KdMap, dg); res.diffuse = res.diffuse * make_vec3f(Kd_from_map); d *= Kd_from_map.w; } res.diffuse = res.diffuse * d; res.specular = d * m->Ks * get3f_ff(m->KsMap, dg, make_vec3f(1.f), ffh); res.shininess = m->Ns * get1f_ff(m->NsMap, dg, 1.f, ffh); res.transmission = m->Tf * d + make_vec3f(1.f - d); res.opacity = d; } } res.albedo = res.diffuse + res.specular; // before normalization! // convert from Phong exponent to Blinn res.shininess *= 4.0f; // BRDF normalization res.diffuse = res.diffuse * (float)one_over_pi; res.specular = res.specular * ((res.shininess + 2.f) * (float)one_over_four_pi * rcp(2.f - exp(res.shininess * -(float)lntwo_over_two))); return res; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/scivis/surfaces.ispc000066400000000000000000000105551464752671100250120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #include "lights/LightDispatch.ih" #include "math/random.ih" #include "math/sampling.ih" #include "render/util.ih" #include "surfaces.ih" // c++ shared #include "SciVisDataShared.h" #include "SciVisShared.h" #include "lights/LightShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE vec3f directIllumination(const uniform SciVis *uniform self, const World *uniform world, const varying DifferentialGeometry &dg, ScreenSample &sample, RandomSampler &randomSampler, const varying SciVisBSDF &bsdf, const varying vec3f &inDir, const float coneWidth, const uniform FeatureFlagsHandler &ffh) { vec3f color = make_vec3f(0.f); const uniform SciVisData &scivisData = *((const uniform SciVisData *)world->scivisData); if (!scivisData.lights) return color; // calculate shading for all lights for (uniform uint32 i = scivisData.numLightsVisibleOnly; i < scivisData.numLights; i++) { const Light *uniform l = scivisData.lights[i]; const vec2f s = make_vec2f(0.0f); // sample center of area lights const Light_SampleRes light = Light_dispatch_sample(l, dg, s, sample.ray.time, ffh); if (reduce_max(light.weight) > 0.f) { // any potential contribution? const float cosNL = dot(light.dir, dg.Ns); if (cosNL < 0.0f) continue; const vec3f H = normalize(light.dir - inDir); const float cosNH = dot(H, dg.Ns); const vec3f specular = bsdf.specular * powf(cosNH, bsdf.shininess); const vec3f diffuse = bsdf.diffuse * cosNL; const vec3f light_contrib = (diffuse + specular) * light.weight; if (self->shadowsEnabled) { if (luminance(light_contrib) > self->super.minContribution) { vec3f P = dg.P; if (dot(dg.Ng, light.dir) < 0.0f) P = P - (2.f * dg.epsilon) * dg.Ng; Ray shadowRay; setRay(shadowRay, P, light.dir, 0.0f, light.dist); RayCone shadowCone; // connect ray cone to point on light shadowCone.width = coneWidth; shadowCone.dwdt = -coneWidth * rcp(light.dist); vec3f light_alpha = lightAlpha(self, shadowRay, shadowCone, world, randomSampler, light_contrib, 0.25f, ffh); color = color + light_alpha * light_contrib; } } else { color = color + light_contrib; } } } return color; } SYCL_EXTERNAL __noinline SSI SciVis_computeShading(const SciVis *uniform self, const World *uniform world, const DifferentialGeometry &dg, ScreenSample &sample, RandomSampler &randomSampler, const varying vec3f &inDir, const float coneWidth, const uniform FeatureFlagsHandler &ffh) { SSI retval; const SciVisBSDF bsdf = evalMaterial(dg, ffh); retval.albedo = bsdf.albedo; vec3f color = directIllumination( self, world, dg, sample, randomSampler, bsdf, inDir, coneWidth, ffh); vec3f ao = make_vec3f(1.f); const uniform SciVisData &scivisData = *((const uniform SciVisData *)world->scivisData); if (self->aoSamples > 0 && luminance(scivisData.aoColorPi) > self->super.minContribution) ao = SciVis_computeAO(self, world, randomSampler, dg, coneWidth, self->aoSamples, self->aoRadius, sample.sampleID, ffh); color = color + bsdf.diffuse * ao * scivisData.aoColorPi; retval.shadedColor = color; retval.transmission = bsdf.transmission; retval.opacity = bsdf.opacity; return retval; } SYCL_EXTERNAL vec3f evaluateLights(const World *uniform world, const DifferentialGeometry &dg, const Ray &ray, const uniform FeatureFlagsHandler &ffh) { // Iterate through all lights vec3f color = make_vec3f(0.f); const uniform SciVisData &scivisData = *((const uniform SciVisData *)world->scivisData); for (uniform uint32 i = 0; i < scivisData.numLights; i++) { // Skip lights with disabled visibility via parameter const Light *uniform l = scivisData.lights[i]; if (!l->isVisible) continue; // Evaluate light contribution const Light_EvalRes le = Light_dispatch_eval(l, dg, ray.dir, ray.t0, ray.t, ray.time, ffh); color = color + le.radiance; } return color; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/scivis/volumes.ih000066400000000000000000000011551464752671100243270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "common/Clipping.ih" #include "common/FeatureFlagsEnum.h" #include "common/Ray.ih" #include "common/VolumeIntervals.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct RandomSampler; SYCL_EXTERNAL vec4f integrateVolumeIntervalsGradient(SciVisRenderContext &rc, const VolumeIntervals &intervals, const RayIntervals &rayIntervals, Ray &ray, RandomSampler &randomSampler, const uniform float samplingRate, const uniform FeatureFlagsHandler &ffh); OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/scivis/volumes.ispc000066400000000000000000000344161464752671100246730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "math/random.ih" #include "math/sampling.ih" #include "render/util.ih" #include "surfaces.ih" #include "volume/VolumetricModel.ih" #include "volume/transferFunction/TransferFunctionDispatch.ih" #include "volumes.ih" // c++ shared #include "SciVisShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifndef OSPRAY_TARGET_SYCL struct VolumeContext { uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; VKLIntervalIterator intervalIterator; VKLInterval interval; vec3f org; vec3f dir; float iuLength; // VKL interval length in sampling steps as an unit float iuDistance; // sampling distance within VKL interval in sampling steps // as an unit float distance; // last sampling distance from 'vc.org' vec4f sample; uint32 ready; // 1 if sample is ready to be used }; static void sampleVolume(SciVisRenderContext &rc, VolumeContext &vc, const VolumetricModel *uniform m, Ray &ray, const VolumeInterval &vi, const uniform float samplingRate) { // We have to iterate till we get a valid sample value float dt = 0.f; float sampleVal = nan; vec3f p; // in volume local coords while (isnan(sampleVal)) { // Iterate till sampling position is within interval float emptySpace = 0.f; while (vc.iuDistance > vc.iuLength) { // Get next VKL interval const float prevUpper = vc.interval.tRange.upper; if (vklIterateIntervalV(vc.intervalIterator, &vc.interval)) { // Intervals may not be contiguous, accumulate empty space emptySpace += max(vc.interval.tRange.lower - prevUpper, 0.f); // Make it local for the next interval vc.iuDistance -= vc.iuLength; // Calculate how many steps can be made within this interval const float samplingStep = vc.interval.nominalDeltaT / samplingRate; vc.iuLength = (vc.interval.tRange.upper - vc.interval.tRange.lower) / samplingStep; // Initialize distance if necessary vc.distance = (vc.distance == inf) ? vc.interval.tRange.lower : vc.distance; } else { // The end of the volume has been reached vc.distance = inf; return; } } // Calculate sampling distance const float samplingStep = vc.interval.nominalDeltaT / samplingRate; const float newDistance = vc.interval.tRange.lower + vc.iuDistance * samplingStep; // Prepare sampling position p = vc.org + newDistance * vc.dir; // Sample volume value in given point sampleVal = vklComputeSampleV( &m->volume->vklSampler, (const varying vkl_vec3f *uniform) & p); // Go to the next sub-interval vc.iuDistance += 1.f; dt = newDistance - vc.distance - emptySpace; vc.distance = newDistance; } // Apply transfer function to get color with alpha TransferFunction *uniform tf = m->transferFunction; vc.sample = TransferFunction_dispatch_get(tf, sampleVal); // compute gradient shading lighting if (m->gradientShadingScale > 0.0f && vc.sample.w > 0.0f) { uniform FeatureFlagsHandler ffh; vec3f ns = Volume_getGradient(m->volume, p, ffh); if (dot(ns, ns) > 1e-6f) { // assume that opacity directly correlates to volume scalar field, i.e. // that "outside" has lower values; because the gradient point towards // increasing values we need to flip it ns = neg(ns); // use scivis shading function // Prepare differential geometry structure DifferentialGeometry dg; dg.color = vc.sample; dg.material = NULL; dg.epsilon = dt / 2.f; // transform to world coords dg.Ns = dg.Ng = normalize(xfmVector(transposed(vi.instance->rcp_xfm.l), ns)); dg.P = ray.org + vc.distance * ray.dir; SSI shading = SciVis_computeShading(rc.renderer, rc.world, dg, rc.sample, *rc.randomSampler, ray.dir, 0.f, // no coneWidth used ffh); vec4f shadedColor = make_vec4f( shading.shadedColor, 1.f - luminance(shading.transmission)); vc.sample = lerp(m->gradientShadingScale, vc.sample, shadedColor); } } // Weight the opacity with deltaT using Beer law vc.sample.w = exp(-vc.sample.w * dt * m->densityScale); } static float sampleAllVolumes(SciVisRenderContext &rc, const VolumeIntervals &volumeIntervals, varying VolumeContext *uniform volumeContexts, Ray &ray, const uniform float samplingRate, vec4f &sampledColor) { // Look for the closest sample across all volumes float minDist = inf; int usedSampleId = -1; for (uniform uint32 i = 0; i < reduce_max(volumeIntervals.numVolumeIntervals); i++) { if (i >= volumeIntervals.numVolumeIntervals) break; // If the sample has been used already regenerate a new one VolumeContext &vc = volumeContexts[i]; if (vc.ready == 0) { const VolumeInterval &vi = volumeIntervals.intervals[i]; foreach_unique (m in vi.volumetricModel) sampleVolume(rc, vc, m, ray, vi, samplingRate); vc.ready = 1; } // Take the sample if closer if (vc.distance < minDist) { minDist = vc.distance; sampledColor = vc.sample; usedSampleId = i; const SciVis *scivis = rc.renderer; if (minDist < ray.t && sampledColor.w < 1.0f - scivis->super.minContribution) { ray.t = minDist; ray.geomID = volumeIntervals.intervals[i].geomID; ray.instID = volumeIntervals.intervals[i].instID; } } } // Mark used samples as not ready if (usedSampleId != -1) { volumeContexts[usedSampleId].ready = 0; } // Return distance for sampled color return minDist; } SYCL_EXTERNAL vec4f integrateVolumeIntervalsGradient(SciVisRenderContext &rc, const VolumeIntervals &volumeIntervals, const RayIntervals &rayIntervals, Ray &ray, RandomSampler &randomSampler, const uniform float samplingRate, const uniform FeatureFlagsHandler &) { // Array of volume contexts varying VolumeContext *uniform volumeContexts = (varying VolumeContext * uniform) pushTLS(reduce_max(volumeIntervals.numVolumeIntervals) * sizeof(varying VolumeContext)); // Sampling position jitter const float jitter = RandomSampler_getFloat(&randomSampler); // Iterate through all volumes and initialize its contexts with data that // do not change across ray intervals for (uniform uint32 i = 0; i < reduce_max(volumeIntervals.numVolumeIntervals); i++) { if (i >= volumeIntervals.numVolumeIntervals) break; // Transform ray into the volume local space const VolumeInterval &vi = volumeIntervals.intervals[i]; Ray transformedRay = ray; AffineSpace3f instanceRcpXfm = vi.instance->rcp_xfm; transformRay(transformedRay, instanceRcpXfm); // Set volume context initial values VolumeContext &vc = volumeContexts[i]; vc.org = transformedRay.org; vc.dir = transformedRay.dir; } // Define initial color and transmission vec3f color = make_vec3f(0.f); float transmission = 1.f; // Iterate through all ray intervals const SciVis *uniform scivis = rc.renderer; for (uniform uint32 i = 0; i < reduce_max(rayIntervals.count) && (transmission > scivis->super.minContribution); i++) { if (i >= rayIntervals.count) break; // Iterate through all volumes for (uniform uint32 j = 0; j < reduce_max(volumeIntervals.numVolumeIntervals); j++) { if (j >= volumeIntervals.numVolumeIntervals) break; // Calculate volume and ray intervals union const VolumeInterval &vi = volumeIntervals.intervals[j]; range1f rInterval = rayIntervals.intervals[i]; rInterval.lower = max(rInterval.lower, vi.interval.lower); rInterval.upper = min(rInterval.upper, vi.interval.upper); // Reset distance to sample VolumeContext &vc = volumeContexts[j]; vc.distance = inf; // Check if volume and ray intervals overlap if (rInterval.upper <= rInterval.lower) { // Skip this volume if not vc.ready = 1; continue; } // We will sample across this volume so initialize members used during // sampling vc.iuDistance = jitter; vc.iuLength = 0.f; vc.ready = 0; vc.interval.tRange.upper = inf; // There might be different volumetric models used across vector lanes // so we must iterate over them float time = 0.5f; VolumetricModel *varying model = vi.volumetricModel; // Create volume interval iterator foreach_unique (m in model) vc.intervalIterator = vklInitIntervalIteratorV(&m->vklIntervalContext, (varying vkl_vec3f *)&vc.org, (varying vkl_vec3f *)&vc.dir, (varying vkl_range1f *)&rInterval, &time, vc.intervalIteratorBuffer); } // Propagate ray across all volumes till opaque while (transmission > scivis->super.minContribution) { // Sample across all volumes vec4f sampledColor; float dist = sampleAllVolumes( rc, volumeIntervals, volumeContexts, ray, samplingRate, sampledColor); // Exit loop if nothing sampled if (dist == inf) break; // Blend sampled color color = color + transmission * (1.f - sampledColor.w) * make_vec3f(sampledColor); transmission *= sampledColor.w; } } popTLS(volumeContexts); // Return final color return make_vec4f(color, transmission); } #else // GPU version SYCL_EXTERNAL vec4f integrateVolumeIntervalsGradient(SciVisRenderContext &rc, const VolumeIntervals &volumeIntervals, const RayIntervals &, Ray &ray, RandomSampler &randomSampler, const uniform float samplingRate, const uniform FeatureFlagsHandler &ffh) { const VolumeInterval &vi = volumeIntervals.intervals[0]; Ray tRay = ray; AffineSpace3f instanceRcpXfm = vi.instance->rcp_xfm; transformRay(tRay, instanceRcpXfm); // Define initial color with alpha vec3f color = make_vec3f(0.f); float transmission = 1.f; const uniform FeatureFlags ff = getFeatureFlags(ffh); uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; VolumetricModel *varying m = vi.volumetricModel; VKLIntervalIterator intervalIterator = vklInitIntervalIteratorV(&m->vklIntervalContext, (varying vkl_vec3f *)&tRay.org, (varying vkl_vec3f *)&tRay.dir, (varying vkl_range1f *)&vi.interval, .5f, intervalIteratorBuffer, ff.volume); // Sampling position jitter const float jitter = RandomSampler_getFloat(&randomSampler); // Propagate ray across all volumes till opaque const SciVis *uniform scivis = rc.renderer; float distance = inf; float iuDistance = jitter; float iuLength = 0.f; VKLInterval interval; interval.tRange.upper = inf; float samplingStep = 0.f; while (transmission > scivis->super.minContribution) { // Iterate till sampling position is within interval float emptySpace = 0.f; while (iuDistance > iuLength) { // Get next VKL interval const float prevUpper = interval.tRange.upper; if (vklIterateIntervalV(intervalIterator, &interval, ff.volume)) { // Intervals may not be contiguous, accumulate empty space emptySpace += max(interval.tRange.lower - prevUpper, 0.f); // Make it local for the next interval iuDistance -= iuLength; // Calculate how many steps can be made within this interval samplingStep = interval.nominalDeltaT / samplingRate; iuLength = (interval.tRange.upper - interval.tRange.lower) / samplingStep; // Initialize distance if necessary distance = (distance == inf) ? interval.tRange.lower : distance; } else { // The end of the volume has been reached return make_vec4f(color, transmission); } } // Calculate sampling distance const float newDistance = interval.tRange.lower + iuDistance * samplingStep; // Prepare sampling position const vec3f p = tRay.org + newDistance * tRay.dir; // Sample volume value in given point float sampleVal = vklComputeSampleV(&m->volume->vklSampler, (const varying vkl_vec3f *uniform) & p, 0, .5f, ff.volume); if (!isnan(sampleVal)) { // Apply transfer function to get color with alpha vec4f sampledColor = TransferFunction_dispatch_get(m->transferFunction, sampleVal); // compute gradient shading lighting float dt = newDistance - distance - emptySpace; if ((ff.other & FFO_VOLUME_SCIVIS_SHADING) && (sampledColor.w > 0.0f)) { vec3f ns = Volume_getGradient(m->volume, p, ffh); if (dot(ns, ns) > 1e-6f) { // assume that opacity directly correlates to volume scalar field, // i.e. that "outside" has lower values; because the gradient // point towards increasing values we need to flip it ns = neg(ns); // use scivis shading function // Prepare differential geometry structure DifferentialGeometry dg; dg.color = sampledColor; dg.material = NULL; dg.epsilon = dt / 2.f; // transform to world coords dg.Ns = dg.Ng = normalize(xfmVector(transposed(vi.instance->rcp_xfm.l), ns)); dg.P = p; SSI shading = SciVis_computeShading(rc.renderer, rc.world, dg, rc.sample, *rc.randomSampler, ray.dir, 0.f, // no coneWidth used ffh); vec4f shadedColor = make_vec4f( shading.shadedColor, 1.f - luminance(shading.transmission)); sampledColor = lerp(m->gradientShadingScale, sampledColor, shadedColor); } } // Weight the opacity with deltaT using Beer law sampledColor.w = exp(-sampledColor.w * dt * m->densityScale); // Alpha blend sampled color color = color + transmission * (1.f - sampledColor.w) * make_vec3f(sampledColor); transmission *= sampledColor.w; } // Go to the next sub-interval iuDistance += 1.f; distance = newDistance; } // Return final color return make_vec4f(color, transmission); } #endif OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/render/shaders/000077500000000000000000000000001464752671100224425ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/render/shaders/Flakes.ih000066400000000000000000000033651464752671100242000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Noise.ih" #include "render/bsdfs/BeckmannDistribution.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Flakes { float scale; float density; float spread; float jitter; }; inline vec3f Flakes_eval(const Flakes &self, vec3f P, int &mask) { vec3f N = make_vec3f(0.f, 0.f, 1.f); mask = 0; if (self.density <= 0.f || self.spread <= 0.f) return N; const BeckmannDistribution flakeDistribution = make_BeckmannDistribution(roughnessToAlpha(self.spread)); P = P * self.scale; // Simple Worley cellular noise with jittered feature points // [Apodaca and Gritz, 1999, "Advanced RenderMan: Creating CGI for Motion // Pictures", pp. 255-261] const vec3f thisCell = floor(P) + 0.5f; float f1 = 1000.f; unsigned int cellRnd; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { const vec3f testCell = thisCell + make_vec3f(i, j, k); // generate a random ID for the test cell unsigned int rnd = cellNoise1ui(testCell); // generate the position of the feature point in the test cell const vec3f pos = testCell + self.jitter * (LCG_getFloat3(rnd) - 0.5f); // distance test const vec3f offset = pos - P; const float dist = dot(offset, offset); // actually dist^2 if (dist < f1) { f1 = dist; cellRnd = rnd; } } } } // test whether the flake exists if (LCG_getFloat(cellRnd) <= self.density) { // generate a random normal for the flake float pdf; N = sample(flakeDistribution, pdf, LCG_getFloat2(cellRnd)); mask = 1; } return normalize(N); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/shaders/Noise.ih000066400000000000000000000017651464752671100240520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "math/random.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // Hash function used in noise functions inline unsigned int noiseHash(const vec3ui &v, unsigned int seed) { unsigned int hash = seed; hash = MurmurHash3_mix(hash, v.x); hash = MurmurHash3_mix(hash, v.y); hash = MurmurHash3_mix(hash, v.z); hash ^= 3 * 4; hash = MurmurHash3_finalize(hash); return hash; } inline unsigned int cellNoise1ui(const vec3f &v) { const vec3ui key = intbits(floor(v)); return noiseHash(key, 0x537e6612); } inline float cellNoise1f(const vec3f &v) { const vec3ui key = intbits(floor(v)); return to_float_unorm(noiseHash(key, 0x537e6612)); } inline vec3f cellNoise3f(const vec3f &v) { const vec3ui key = intbits(floor(v)); return make_vec3f(to_float_unorm(noiseHash(key, 0xf7acd0ce)), to_float_unorm(noiseHash(key, 0x6e2bf582)), to_float_unorm(noiseHash(key, 0xc6ae6d0d))); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/util.h000066400000000000000000000017451464752671100221460ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once /*! \file render/util.h Defines some utility functions shared by different * shading codes */ #include "common/OSPCommon.h" namespace ospray { // TODO: Could use pdep/pext inline uint32_t partitionZOrder(uint32_t n) { n &= 0x0000FFFF; n = (n | (n << 8)) & 0x00FF00FF; n = (n | (n << 4)) & 0x0F0F0F0F; n = (n | (n << 2)) & 0x33333333; n = (n | (n << 1)) & 0x55555555; return n; } inline uint32_t unpartitionZOrder(uint32_t n) { n &= 0x55555555; n = (n ^ (n >> 1)) & 0x33333333; n = (n ^ (n >> 2)) & 0x0F0F0F0F; n = (n ^ (n >> 4)) & 0x00FF00FF; n = (n ^ (n >> 8)) & 0x0000FFFF; return n; } inline uint32_t interleaveZOrder(uint32_t x, uint32_t y) { return partitionZOrder(x) | (partitionZOrder(y) << 1); } inline void deinterleaveZOrder(uint32_t z, uint32_t &x, uint32_t &y) { x = y = 0; x = unpartitionZOrder(z); y = unpartitionZOrder(z >> 1); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/render/util.ih000066400000000000000000000032461464752671100223150ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "OSPConfig.h" #include "common/FeatureFlagsEnum.h" #include "common/World.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL float computeAO(const Renderer *uniform, const World *uniform, const varying DifferentialGeometry &, const uniform int sampleCnt, const uniform float aoRadius, const varying vec3i &sampleID, const uniform FeatureFlagsHandler &ff); // TODO should use PDEP inline uniform uint32 partitionZOrder(uniform uint32 n) { n &= 0x0000FFFF; n = (n | (n << 8)) & 0x00FF00FF; n = (n | (n << 4)) & 0x0F0F0F0F; n = (n | (n << 2)) & 0x33333333; n = (n | (n << 1)) & 0x55555555; return n; } inline uint32 partitionZOrder8(uint32 n) { n &= 0x000000FF; n = (n | (n << 4)) & 0x0F0F0F0F; n = (n | (n << 2)) & 0x33333333; n = (n | (n << 1)) & 0x55555555; return n; } // TODO should use PEXT inline uniform uint32 unpartitionZOrder(uniform uint32 n) { n &= 0x55555555; n = (n ^ (n >> 1)) & 0x33333333; n = (n ^ (n >> 2)) & 0x0F0F0F0F; n = (n ^ (n >> 4)) & 0x00FF00FF; n = (n ^ (n >> 8)) & 0x0000FFFF; return n; } inline uniform uint32 interleaveZOrder(uniform uint32 x, uniform uint32 y) { return partitionZOrder(x) | (partitionZOrder(y) << 1); } inline uint32 interleaveZOrder16(uint32 x, uint32 y) { return partitionZOrder8(x) | (partitionZOrder8(y) << 1); } inline void deinterleaveZOrder( uniform uint32 z, uniform uint32 *uniform x, uniform uint32 *uniform y) { assert(x); assert(y); *x = *y = 0; *x = unpartitionZOrder(z); *y = unpartitionZOrder(z >> 1); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/render/util.ispc000066400000000000000000000031731464752671100226520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/FeatureFlagsEnum.h" #include "common/World.ih" #include "math/random.ih" #include "math/sampling.ih" #include "render/util.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL float computeAO(const Renderer *uniform, const World *uniform world, const varying DifferentialGeometry &dg, const uniform int sampleCnt, const uniform float aoRadius, const varying vec3i &sampleID, const uniform FeatureFlagsHandler &ffh) { const uniform int accumID = reduce_max(sampleID.z) * sampleCnt; // init TEA RNG // RandomTEA rng_state; varying RandomTEA *const uniform rng = &rng_state; RandomTEA_Constructor(rng, sampleID.x, sampleID.y); const vec2f rot = RandomTEA_getFloats(rng); int hits = 0; const linear3f localToWorld = frame(dg.Ns); for (uniform int i = 0; i < sampleCnt; i++) { // Use base-5 and base-7 Halton to avoid correlation with sample position const vec2f halton = make_vec2f( PermHalton_sample5(accumID + i), PermHalton_sample7(accumID + i)); const vec2f r = CranleyPattersonRotation(halton, rot); const vec3f local_ao_dir = cosineSampleHemisphere(r); const vec3f ao_dir = localToWorld * local_ao_dir; if (dot(ao_dir, dg.Ns) < 0.01f) { // check below surface hits++; continue; } Ray ao_ray; setRay(ao_ray, dg.P, ao_dir, dg.epsilon, aoRadius); if (isOccluded(world, ao_ray, ffh)) hits++; } // the cosTheta of cosineSampleHemispherePDF and dot(shadingNormal, ao_dir) // cancel return 1.0f - (hits / (float)sampleCnt); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/000077500000000000000000000000001464752671100212325ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/texture/MipMapCache.h000066400000000000000000000016601464752671100235150ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include namespace ospray { struct MipMapCache { using BufferPtr = std::shared_ptr>; // Find appropriate MIP map pyramid for given texture data inline BufferPtr find(char *rootLevel); // Manage cache entries inline void add(char *rootLevel, BufferPtr mipMaps); inline void remove(char *rootLevel); private: // Hash map containing MIP map buffers std::unordered_map map; }; MipMapCache::BufferPtr MipMapCache::find(char *rootLevel) { auto it = map.find(rootLevel); return it != map.end() ? it->second : BufferPtr(); } void MipMapCache::add(char *rootLevel, MipMapCache::BufferPtr mipMaps) { map.insert(std::make_pair(rootLevel, mipMaps)); } void MipMapCache::remove(char *rootLevel) { map.erase(rootLevel); } } // namespace osprayRenderKit-ospray-85af292/modules/cpu/texture/MipMapGeneration.ispc000066400000000000000000000103471464752671100253160ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Texture2DUtil.ih" #include "ospray/OSPEnums.h" #define __define_tex_filterkernel_case(FMT) \ case OSP_TEXTURE_##FMT: \ foreach (x = 0 ... dstSize.x) { \ const float tx = x * r.x; \ const int sx = 2 * x; \ const vec4f v0 = (h.x - tx) * getTexel_##FMT(src, srcy + sx) \ + h.x * getTexel_##FMT(src, srcy + sx + 1) \ + (r.x + tx) * getTexel_##FMT(src, srcy + sx + ofs2.x); \ const vec4f v1 = (h.x - tx) * getTexel_##FMT(src, srcy + srcSize.x + sx) \ + h.x * getTexel_##FMT(src, srcy + srcSize.x + sx + 1) \ + (r.x + tx) * getTexel_##FMT(src, srcy + srcSize.x + sx + ofs2.x); \ const vec4f v2 = (h.x - tx) * getTexel_##FMT(src, ofs2.y + sx) \ + h.x * getTexel_##FMT(src, ofs2.y + sx + 1) \ + (r.x + tx) * getTexel_##FMT(src, ofs2.y + sx + ofs2.x); \ val = wy0 * v0 + h.y * v1 + wy2 * v2; \ setTexel_##FMT(dst, dsty + x, val); \ } \ break; task unmasked void MipMap_generateRows(const void *uniform const src, const uniform vec2i &srcSize, void *uniform const dst, const uniform vec2i &dstSize, const uniform uint32 format) { const uniform int y = taskIndex; vec4f val; const uniform int dsty = y * dstSize.x; const uniform int srcy = 2 * y * srcSize.x; uniform vec2f r = rcp(make_vec2f(srcSize.x, srcSize.y)); uniform vec2f h = make_vec2f(dstSize.x, dstSize.y) * r; uniform vec2i ofs2 = make_vec2i(2, srcy + 2 * srcSize.x); if ((srcSize.x & 1) == 0) { h.x = 0.5f; r.x = 0.f; ofs2.x = 0; } if ((srcSize.y & 1) == 0) { h.y = 0.5f; r.y = 0.f; ofs2.y = srcy; } const uniform float wy0 = h.y - y * r.y; const uniform float wy2 = r.y + y * r.y; switch (format) { __foreach_fetcher(__define_tex_filterkernel_case); default: break; } } #undef __define_tex_filterkernel_case #define __define_tex_filterkernel_case1D(FMT) \ case OSP_TEXTURE_##FMT: \ foreach (x = 0 ... dstSize) { \ const float tx = x * r; \ const float sx = 2 * x; \ val = (h - tx) * getTexel_##FMT(src, sx) \ + h * getTexel_##FMT(src, sx + 1) \ + (r + tx) * getTexel_##FMT(src, sx + ofs2); \ setTexel_##FMT(dst, x, val); \ } \ break; void MipMap_generateRow(const void *uniform const src, const uniform int &srcSize, void *uniform const dst, const uniform int &dstSize, const uniform uint32 format) { vec4f val; uniform float r = rcp((float)srcSize); uniform float h = (float)dstSize * r; uniform int ofs2 = 2; if ((srcSize & 1) == 0) { h = 0.5f; r = 0.f; ofs2 = 0; } switch (format) { __foreach_fetcher(__define_tex_filterkernel_case1D); default: break; } } #undef __define_tex_filterkernel_case1D export void MipMap_generate(const void *uniform const src, const uniform vec2i &srcSize, void *uniform const dst, const uniform vec2i &dstSize, const uniform uint32 format) { if (srcSize.x > 1 && srcSize.y > 1) { launch[dstSize.y] MipMap_generateRows(src, srcSize, dst, dstSize, format); sync; } else if (srcSize.x > 1 || srcSize.y > 1) { const uniform int srcSize = max(srcSize.x, srcSize.y); const uniform int dstSize = max(dstSize.x, dstSize.y); MipMap_generateRow(src, srcSize, dst, dstSize, format); } } RenderKit-ospray-85af292/modules/cpu/texture/Texture.cpp000066400000000000000000000007161464752671100234020ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Texture.h" namespace ospray { // Texture definitions //////////////////////////////////////////////////////// Texture::Texture(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { managedObjectType = OSP_TEXTURE; } std::string Texture::toString() const { return "ospray::Texture"; } OSPTYPEFOR_DEFINITION(Texture *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/texture/Texture.h000066400000000000000000000011341464752671100230420ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDeviceObject.h" #include "common/ObjectFactory.h" #include "common/StructShared.h" // ispc shared #include "TextureShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Texture : AddStructShared, public ObjectFactory { Texture(api::ISPCDevice &device); virtual ~Texture() override = default; virtual std::string toString() const override; }; OSPTYPEFOR_SPECIALIZATION(Texture *, OSP_TEXTURE); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/texture/Texture.ih000066400000000000000000000057271464752671100232270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../common/DifferentialGeometry.ih" #include "rkcommon/math/vec.ih" #include "texture/TextureDispatch.ih" // c++ shared #include "TextureShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline uniform bool hasAlpha(const uniform Texture *uniform self) { return (self == NULL) ? false : self->hasAlpha; } /*! helper function that returns the sampled value for the first channel of the given texture Right now, this function always asks the texture for all four channels, and then discards all but one; later implementations may have specialized 'get1f' methods with the texture \note self may NOT be NULL! */ inline float get1f( const uniform Texture *uniform self, const varying DifferentialGeometry &dg) { vec4f ret = Texture_dispatch_get(self, dg); return ret.x; } /*! helper function that returns the sampled value for the first three channels of the given texture Right now, this function always asks the texture for all four channels, and then discards all but one; later implementations may have specialized 'get3f' methods with the texture \note self may NOT be NULL! */ inline vec3f get3f( const uniform Texture *uniform self, const varying DifferentialGeometry &dg) { vec4f ret = Texture_dispatch_get(self, dg); return make_vec3f(ret); } /*! helper function that returns the sampled value of the four channels of the given texture. Note that it's up to the texture to define clearly what happens if we ask for four channels even if the texture has less physical channels. \note self may NOT be NULL! */ inline vec4f get4f( const uniform Texture *uniform self, const varying DifferentialGeometry &dg) { return Texture_dispatch_get(self, dg); } /*! helper function that returns the sampled values interpreted as a normal */ inline vec3f getNormal( const uniform Texture *uniform self, const varying DifferentialGeometry &dg) { if (self == NULL) return make_vec3f(0.f, 0.f, 1.f); else return Texture_dispatch_getNormal(self, dg); } /*! helper function: get1f() with a default value if the texture is NULL */ inline float get1f(const uniform Texture *uniform self, const varying DifferentialGeometry &dg, const varying float defaultValue) { if (self == NULL) return defaultValue; else return get1f(self, dg); } /*! helper function: get3f() with a default value if the texture is NULL */ inline vec3f get3f(const uniform Texture *uniform self, const varying DifferentialGeometry &dg, const varying vec3f defaultValue) { if (self == NULL) return defaultValue; else return get3f(self, dg); } /*! helper function: get4f() with a default value if the texture is NULL */ inline vec4f get4f(const uniform Texture *uniform self, const varying DifferentialGeometry &dg, const varying vec4f defaultValue) { if (self == NULL) return defaultValue; else return get4f(self, dg); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/Texture2D.cpp000066400000000000000000000112121464752671100235610ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Texture2D.h" #ifndef OSPRAY_TARGET_SYCL #include "texture/Texture2D_ispc.h" #endif #include "texture/MipMapGeneration_ispc.h" namespace ispc { void Texture2D::set(const rkcommon::math::vec2i &aSize, void **aData, int aMaxLevel, OSPTextureFormat aFormat, OSPTextureFilter aFilter, const rkcommon::math::vec2ui &aWrapMode) { size = aSize; maxLevel = aMaxLevel; format = aFormat; filter = aFilter; wrapMode = aWrapMode; for (int l = 0; l <= aMaxLevel; l++) data[l] = aData[l]; super.hasAlpha = aFormat == OSP_TEXTURE_RGBA8 || aFormat == OSP_TEXTURE_SRGBA || aFormat == OSP_TEXTURE_RA8 || aFormat == OSP_TEXTURE_LA8 || aFormat == OSP_TEXTURE_RGBA32F || aFormat == OSP_TEXTURE_RGBA16 || aFormat == OSP_TEXTURE_RA16 || aFormat == OSP_TEXTURE_RA16F || aFormat == OSP_TEXTURE_RA32F || aFormat == OSP_TEXTURE_RGBA16F; #ifndef OSPRAY_TARGET_SYCL super.get = reinterpret_cast(ispc::Texture2D_get_addr(aFormat)); super.getNormal = reinterpret_cast(ispc::Texture2D_getN_addr(aFormat)); #endif } } // namespace ispc namespace ospray { Texture2D::~Texture2D() { // If no one else is referencing the MIP map buffer (just this object and the // cache map), we need to remove it from the MIP map cache so the buffer will // be deleted as well if (mipMapData && mipMapData.use_count() == 2) getISPCDevice().getMipMapCache().remove(texData->data()); } std::string Texture2D::toString() const { return "ospray::Texture2D"; } void Texture2D::commit() { texData = getParamObject("data"); if (!texData || texData->numItems.z > 1) { throw std::runtime_error(toString() + " must have 2D 'data' array using the first two dimensions."); } if (texData->size() > std::numeric_limits::max()) throw std::runtime_error(toString() + " too large (over 4B texels, indexing is limited to 32bit"); const vec2i size = vec2i(texData->numItems.x, texData->numItems.y); if (!texData->compact()) { postStatusMsg(OSP_LOG_INFO) << toString() << " does currently not support strides, copying texture data."; auto data = new Data(getISPCDevice(), texData->type, texData->numItems); data->copy(*texData, vec3ui(0)); texData = data; data->refDec(); } format = static_cast( getParam("format", OSP_TEXTURE_FORMAT_INVALID)); filter = static_cast( getParam("filter", OSP_TEXTURE_FILTER_LINEAR)); wrapMode = getParam("wrapMode", vec2ui(getParam("wrapMode", OSP_TEXTURE_WRAP_REPEAT))); if (format == OSP_TEXTURE_FORMAT_INVALID) throw std::runtime_error(toString() + ": invalid 'format'"); if (sizeOf(format) != sizeOf(texData->type)) throw std::runtime_error(toString() + ": 'format'='" + stringFor(format) + "' does not match type of 'data'='" + stringFor(texData->type) + "'!"); std::vector dataPtr; dataPtr.push_back(texData->data()); if (getISPCDevice().disableMipMapGeneration) mipMapData = nullptr; else { // Check if MIP maps were generated already bool generateMipMaps = false; MipMapCache &mmc = getISPCDevice().getMipMapCache(); mipMapData = mmc.find(texData->data()); if (!mipMapData) { // conservatively estimate needed space for MIP maps and allocate const auto maxMipTexels = (size.product() + 2) / 3 // for square textures + (size.x + size.y - 1) / std::min(size.x, size.y); // remaining 1D case mipMapData = std::make_shared>( getISPCDevice().getDRTDevice(), maxMipTexels * sizeOf(format)); // Add generated MIP maps to the cache mmc.add(texData->data(), mipMapData); generateMipMaps = true; } // generate MIP map levels vec2i srcSize = size; void *srcData = texData->data(); char *dstData = (char *)mipMapData->data(); while (srcSize != vec2i(1)) { assert(dataPtr.size() <= MAX_MIPMAP_LEVEL); // max tex size is 2^32 vec2i dstSize(max(srcSize / 2, vec2i(1))); if (generateMipMaps) ispc::MipMap_generate(srcData, (ispc::vec2i &)srcSize, dstData, (ispc::vec2i &)dstSize, format); dataPtr.push_back(dstData); srcSize = dstSize; srcData = dstData; dstData += dstSize.product() * ospray::sizeOf(format); } } // Initialize ispc shared structure getSh()->set( size, dataPtr.data(), dataPtr.size() - 1, format, filter, wrapMode); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/texture/Texture2D.h000066400000000000000000000014611464752671100232330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Texture.h" #include "common/Data.h" #include "texture/MipMapCache.h" // ispc shared #include "Texture2DShared.h" namespace ospray { // A Texture defined through a 2D Image struct OSPRAY_SDK_INTERFACE Texture2D : public AddStructShared { Texture2D(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) {} ~Texture2D() override; std::string toString() const override; void commit() override; OSPTextureFormat format{OSP_TEXTURE_FORMAT_INVALID}; OSPTextureFilter filter{OSP_TEXTURE_FILTER_LINEAR}; vec2ui wrapMode{OSP_TEXTURE_WRAP_REPEAT}; protected: Ref texData; MipMapCache::BufferPtr mipMapData; }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/texture/Texture2D.ih000066400000000000000000000042441464752671100234060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Texture.ih" #include "Texture2DShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f Texture2D_get( const uniform Texture *uniform self, const DifferentialGeometry &dg); SYCL_EXTERNAL vec3f Texture2D_getNormal( const uniform Texture *uniform self, const DifferentialGeometry &dg); // XXX won't work with MIPmapping: clean implementation with clamping on integer // coords needed then inline vec2f clamp2edge(const uniform Texture2D *uniform self, const vec2f p) { const vec2f halfTexel = rcp(make_vec2f(self->size.x, self->size.y)) * 0.5f; return clamp(p, halfTexel, 1.0f - halfTexel); } inline float get1f(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg) { return get1f(&self->super, dg); } inline vec3f get3f(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg) { return get3f(&self->super, dg); } inline vec4f get4f(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg) { return get4f(&self->super, dg); } inline vec3f getNormal(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg) { return getNormal(&self->super, dg); } inline float get1f(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg, const varying float defaultValue) { return get1f(&self->super, dg, defaultValue); } inline vec3f get3f(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg, const varying vec3f defaultValue) { return get3f(&self->super, dg, defaultValue); } inline vec4f get4f(const uniform Texture2D *uniform self, const varying DifferentialGeometry &dg, const varying vec4f defaultValue) { return get4f(&self->super, dg, defaultValue); } #if 0 // crashes ISPC! inline DifferentialGeometry dgFromTexCoord(const varying vec2f &c) { DifferentialGeometry dg; dg.primID = -1; dg.st = c; return dg; } #else inline void initDgFromTexCoord(DifferentialGeometry &dg, const varying vec2f &c) { dg.primID = -1; dg.st = c; dg.pixelFootprint = flt_min; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/Texture2D.ispc000066400000000000000000000352651464752671100237530ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Texture2D.ih" #include "Texture2DUtil.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // TODO tiling // Texture coordinate utilities ////////////////////////////////////////////////////////////////////////////// inline float wrap_coord( const uniform uint32 wrapMode, const float halfTexel, const float p) { float tc = 0.f; switch (wrapMode) { case OSP_TEXTURE_WRAP_REPEAT: tc = frac(p - halfTexel) + halfTexel; tc = max(tc, 0.f); // filter out inf/NaN break; case OSP_TEXTURE_WRAP_MIRRORED_REPEAT: { tc = 2.f * frac(p * 0.5f); if (tc >= 1.f) tc = 2.f - tc; tc = clamp(tc, halfTexel, 1.f - halfTexel); break; } case OSP_TEXTURE_WRAP_CLAMP_TO_EDGE: tc = clamp(p, halfTexel, 1.f - halfTexel); } return tc; } inline vec2i nearest_coords( const vec2f p, const uniform vec2ui wrapMode, const vec2i size) { vec2f tc; tc.x = wrap_coord(wrapMode.x, 0.f, p.x); tc.y = wrap_coord(wrapMode.y, 0.f, p.y); // scale by texture size and clamp const vec2i tci = min(make_vec2i(tc * make_vec2f(size.x, size.y)), size - 1); return tci; } struct BilinCoords { vec2i st0; vec2i st1; vec2f frac; }; inline BilinCoords bilinear_coords( const vec2f p, const uniform vec2ui wrapMode, const vec2i size) { BilinCoords coords; vec2f tc; const vec2f sizef = make_vec2f(size.x, size.y); const vec2f halfTexel = rcp(sizef) * 0.5f; tc.x = wrap_coord(wrapMode.x, halfTexel.x, p.x); tc.y = wrap_coord(wrapMode.y, halfTexel.y, p.y); tc = tc - halfTexel; // lower sample shifted by half a texel tc = tc * sizef; coords.frac = frac(tc); coords.st0 = min(make_vec2i(tc), size - 1); coords.st1 = coords.st0 + 1; // handle border cases as REPEAT if (coords.st1.x >= size.x) coords.st1.x = 0; if (coords.st1.y >= size.y) coords.st1.y = 0; return coords; } inline vec4f bilerp(const vec2f frac, const vec4f c00, const vec4f c01, const vec4f c10, const vec4f c11) { return lerp(frac.y, lerp(frac.x, c00, c01), lerp(frac.x, c10, c11)); } inline vec2i sizeAtLevel(const vec2i size, const int level) { return make_vec2i(max(size.x >> level, 1), max(size.y >> level, 1)); } #define __define_tex_get(FMT) \ \ static vec4f Texture2D_nearest_l_##FMT(const Texture2D *uniform self, \ const DifferentialGeometry &dg, \ const int level) \ { \ const vec2i size = sizeAtLevel(self->size, level); \ const vec2i i = nearest_coords(dg.st, self->wrapMode, size); \ const uint32 idx = i.y * size.x + i.x; \ return getTexel_##FMT(self->data[level], idx); \ } \ \ static vec4f Texture2D_bilinear_l_##FMT(const Texture2D *uniform self, \ const DifferentialGeometry &dg, \ const int level) \ { \ const vec2i size = sizeAtLevel(self->size, level); \ const BilinCoords cs = bilinear_coords(dg.st, self->wrapMode, size); \ const void *data = self->data[level]; \ \ const vec4f c00 = getTexel_##FMT(data, cs.st0.y * size.x + cs.st0.x); \ const vec4f c01 = getTexel_##FMT(data, cs.st0.y * size.x + cs.st1.x); \ const vec4f c10 = getTexel_##FMT(data, cs.st1.y * size.x + cs.st0.x); \ const vec4f c11 = getTexel_##FMT(data, cs.st1.y * size.x + cs.st1.x); \ \ return bilerp(cs.frac, c00, c01, c10, c11); \ } \ \ static vec4f Texture2D_##FMT(const Texture2D *uniform self, \ const DifferentialGeometry &dg, \ const int level, \ const float frac, \ const bool filter_nearest) \ { \ vec4f t0 = filter_nearest ? Texture2D_nearest_l_##FMT(self, dg, level) \ : Texture2D_bilinear_l_##FMT(self, dg, level); \ if (frac == 0.f) \ return t0; \ \ vec4f t1 = filter_nearest \ ? Texture2D_nearest_l_##FMT(self, dg, level + 1) \ : Texture2D_bilinear_l_##FMT(self, dg, level + 1); \ return lerp(frac, t0, t1); \ } \ struct swallow_semicolon __foreach_fetcher(__define_tex_get); #define __define_tex_getN(FMT, C) \ static vec3f Texture2D_N_##FMT(const Texture2D *uniform self, \ const DifferentialGeometry &dg, \ const int level, \ const float frac, \ const bool filter_nearest) \ { \ return make_vec3f(Texture2D_##FMT(self, dg, level, frac, filter_nearest)) \ * C \ - 1.f; \ } \ struct swallow_semicolon #define __define_tex_case(NAME, FMT) \ case OSP_TEXTURE_##FMT: \ return (void *uniform) & NAME##_##FMT #define __define_tex_call_tex_case(FMT) __define_call_tex_case(Texture2D, FMT) #define __define_tex_callN_tex_case(FMT) \ __define_call_tex_case(Texture2D_N, FMT) #define __define_tex_get_case(FMT) __define_tex_case(Texture2D, FMT) #define __define_tex_getN_case(FMT) __define_tex_case(Texture2D_N, FMT) #define __define_call_tex_case(NAME, FMT) \ case OSP_TEXTURE_##FMT: \ return NAME##_##FMT(self, dg, mipLevel, frac, filter_nearest) export void *uniform Texture2D_get_addr(const uniform uint32 type) { switch (type) { __foreach_fetcher(__define_tex_get_case); default: break; } return NULL; }; inline float calcLambda(const float pixelFootprint, const vec2i size, const uniform bool filter_nearest) { float t0 = pixelFootprint * max(size.x, size.y); if (!filter_nearest) t0 *= 0.5f; // bilinear filtering increases filter width by 2: compensate return log(t0) / log(2.f); } SYCL_EXTERNAL vec4f Texture2D_get( const Texture *uniform _self, const DifferentialGeometry &dg) { const Texture2D *uniform self = (const Texture2D *uniform)_self; int mipLevel = 0; float frac = 0.f; const uniform bool filter_nearest = self->filter & OSP_TEXTURE_FILTER_NEAREST; if (self->maxLevel) { const float lambda = max(0.f, calcLambda(dg.pixelFootprint, self->size, filter_nearest)); mipLevel = min((int)lambda, self->maxLevel - 1); frac = min(lambda - mipLevel, 1.f); } switch (self->format) { __foreach_fetcher(__define_tex_call_tex_case); default: break; } return make_vec4f(0.f, 0.f, 0.f, 1.f); } static vec3f Texture2D_Normal_neutral( const Texture2D *uniform, const DifferentialGeometry &) { return make_vec3f(0.f, 0.f, 1.f); } __define_tex_getN(RGB8, (255.f / 127.f)); __define_tex_getN(RGBA8, (255.f / 127.f)); __define_tex_getN(RGB32F, 2.f); __define_tex_getN(RGBA32F, 2.f); __define_tex_getN(RGB16F, 2.f); __define_tex_getN(RGBA16F, 2.f); __define_tex_getN(RGB16, (65535.f / 32767.f)); __define_tex_getN(RGBA16, (65535.f / 32767.f)); export void *uniform Texture2D_getN_addr(const uniform uint32 type) { switch (type) { case OSP_TEXTURE_SRGBA: /* fallthrough, sRGB ignored for normals */ __define_tex_getN_case(RGBA8); case OSP_TEXTURE_SRGB: /* fallthrough, sRGB ignored for normals */ __define_tex_getN_case(RGB8); __define_tex_getN_case(RGBA32F); __define_tex_getN_case(RGB32F); __define_tex_getN_case(RGBA16F); __define_tex_getN_case(RGB16F); __define_tex_getN_case(RGBA16); __define_tex_getN_case(RGB16); default: break; } return (void *uniform) & Texture2D_Normal_neutral; }; SYCL_EXTERNAL vec3f Texture2D_getNormal( const Texture *uniform _self, const DifferentialGeometry &dg) { const Texture2D *uniform self = (const Texture2D *uniform)_self; int mipLevel = 0; float frac = 0.f; const uniform bool filter_nearest = self->filter & OSP_TEXTURE_FILTER_NEAREST; if (self->maxLevel) { const float lambda = max(0.f, calcLambda(dg.pixelFootprint, self->size, filter_nearest)); mipLevel = min((int)lambda, self->maxLevel - 1); frac = min(lambda - mipLevel, 1.f); } switch (self->format) { case OSP_TEXTURE_SRGBA: /* fallthrough, sRGB ignored for normals */ __define_tex_callN_tex_case(RGBA8); case OSP_TEXTURE_SRGB: /* fallthrough, sRGB ignored for normals */ __define_tex_callN_tex_case(RGB8); __define_tex_callN_tex_case(RGBA32F); __define_tex_callN_tex_case(RGB32F); __define_tex_callN_tex_case(RGBA16F); __define_tex_callN_tex_case(RGB16F); __define_tex_callN_tex_case(RGBA16); __define_tex_callN_tex_case(RGB16); default: break; } return Texture2D_Normal_neutral(self, dg); } // Poor mans unit tests ////////////////////////////////////////////////////////////////////////////// #ifdef OSPRAY_UNITTEST uniform size_t channels(OSPTextureFormat format) { switch (format) { case OSP_TEXTURE_RGBA8: case OSP_TEXTURE_SRGBA: case OSP_TEXTURE_RGBA32F: case OSP_TEXTURE_RGBA16: case OSP_TEXTURE_RGBA16F: return 4; case OSP_TEXTURE_RGB8: case OSP_TEXTURE_SRGB: case OSP_TEXTURE_RGB32F: case OSP_TEXTURE_RGB16: case OSP_TEXTURE_RGB16F: return 3; case OSP_TEXTURE_RA32F: case OSP_TEXTURE_RA8: case OSP_TEXTURE_LA8: case OSP_TEXTURE_RA16: case OSP_TEXTURE_RA16F: return 2; case OSP_TEXTURE_R8: case OSP_TEXTURE_L8: case OSP_TEXTURE_R32F: case OSP_TEXTURE_R16: case OSP_TEXTURE_R16F: return 1; default: return 0; } } uniform bool hdr(OSPTextureFormat format) { switch (format) { case OSP_TEXTURE_RGBA32F: case OSP_TEXTURE_RGBA16F: case OSP_TEXTURE_RGB32F: case OSP_TEXTURE_RGB16F: case OSP_TEXTURE_RA32F: case OSP_TEXTURE_RA16F: case OSP_TEXTURE_R32F: case OSP_TEXTURE_R16F: return true; default: return false; } } #define define_texAccessor_consistency(FMT) \ { \ setTexel_##FMT(&data, programIndex, testIn); \ const vec4f testOut = getTexel_##FMT(&data, programIndex); \ const uniform int ch = channels(OSP_TEXTURE_##FMT); \ const uniform bool alpha = ch == 2 || ch == 4; \ const uniform bool hd = hdr(OSP_TEXTURE_##FMT); \ const uniform bool lm = OSP_TEXTURE_##FMT == OSP_TEXTURE_LA8 \ || OSP_TEXTURE_##FMT == OSP_TEXTURE_L8; \ if (ch == 0) \ print("Invalid format " #FMT "\n"); \ if (abs(testIn.x - testOut.x) > 1e-2f && (hd || testOut.x != 1.0f)) { \ print("Failed ch 1 and format " #FMT " % %\n", testIn.x, testOut.x); \ success = false; \ } \ if (abs(testIn.y - testOut.y) > 1e-2f && (hd || testOut.y != 1.0f) \ && (ch > 2 || testOut.y != 0.0f) && (!lm || testOut.y != testOut.x)) { \ print("Failed ch 2 and format " #FMT " % %\n", testIn.y, testOut.y); \ success = false; \ } \ if (abs(testIn.z - testOut.z) > 1e-2f && (hd || testOut.z != 1.0f) \ && (ch > 2 || testOut.z != 0.0f) && (!lm || testOut.z != testOut.x)) { \ print("Failed ch 3 and format " #FMT " % %\n", testIn.z, testOut.z); \ success = false; \ } \ if (abs(testIn.w - testOut.w) > 1e-2f \ && (hd && alpha || testOut.w != 1.0f)) { \ print("Failed ch 4 and format " #FMT " % %\n", testIn.w, testOut.w); \ success = false; \ } \ } \ struct swallow_semicolon bool checkTexAcc(const vec4f testIn) { bool success = true; vec4f data; // largest format __foreach_fetcher(define_texAccessor_consistency); return success; } export uniform bool checkTextureAccessorConsistency() { bool success = true; success &= checkTexAcc(make_vec4f(programIndex * 0.15f)); success &= checkTexAcc(make_vec4f(0.4f + programIndex * 0.027f)); success &= checkTexAcc(make_vec4f(0.01f, 0.91f, 0.37f, 0.5f)); return all(success); } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/Texture2DShared.h000066400000000000000000000016031464752671100243600ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "TextureShared.h" #include "ospray/OSPEnums.h" #define MAX_MIPMAP_LEVEL 32 #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Texture2D { Texture super; vec2i size; void *data[MAX_MIPMAP_LEVEL]; int maxLevel; OSPTextureFormat format; OSPTextureFilter filter; vec2ui wrapMode; #ifdef __cplusplus Texture2D() : size(0), data{nullptr}, maxLevel(0), format(OSP_TEXTURE_FORMAT_INVALID), filter(OSP_TEXTURE_FILTER_LINEAR), wrapMode(vec2ui(OSP_TEXTURE_WRAP_REPEAT)) { super.type = TEXTURE_TYPE_2D; } void set(const vec2i &aSize, void **aData, int maxLevel, OSPTextureFormat format, OSPTextureFilter flags, const vec2ui &wrapMode); }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/texture/Texture2DUtil.ih000066400000000000000000000276301464752671100242500ustar00rootroot00000000000000// Copyright 2023 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/OSPCommon.ih" #include "rkcommon/math/vec.ih" OSPRAY_BEGIN_ISPC_NAMESPACE // helpers ////////////////////////////////////////////////////////////////////////////// #define __foreach_fetcher(FCT) \ FCT(RGBA8); \ FCT(SRGBA); \ FCT(RGBA32F); \ FCT(RGB8); \ FCT(SRGB); \ FCT(LA8); \ FCT(RA8); \ FCT(RGB32F); \ FCT(RA32F); \ FCT(R8); \ FCT(L8); \ FCT(R32F); \ FCT(RGBA16); \ FCT(RGB16); \ FCT(RA16); \ FCT(R16); \ FCT(RGBA16F); \ FCT(RGB16F); \ FCT(RA16F); \ FCT(R16F) #define BYTE2FLOAT (1.f / 255.f) #define SHORT2FLOAT (1.f / 65535.f) #ifdef OSPRAY_TARGET_SYCL using half = sycl::half; inline float half_to_float(int16 x) { return *reinterpret_cast(&x); } #else typedef int16 half; // Low-level texel accessors: setters ////////////////////////////////////////////////////////////////////////////// inline void setTexel_RGBA8( void *uniform data, const uint32 idx, const vec4f value) { ((uint32 * uniform) data)[idx] = cvt_uint32(value); } inline void setTexel_RGBA16( void *uniform data, const uint32 idx, const vec4f value) { const uint32 texelOfs = idx * 2; // write as 2x 32bit const uint32 r = cvt_uint16(value.x); const uint32 g = cvt_uint16(value.y); ((uint32 * uniform) data)[texelOfs] = r | (g << 16); const uint32 b = cvt_uint16(value.z); const uint32 a = cvt_uint16(value.w); ((uint32 * uniform) data)[texelOfs + 1] = b | (a << 16); } inline void setTexel_RGB8( void *uniform data, const uint32 idx, const vec4f value) { uint8 *uniform texel = (uint8 * uniform) data; const uint32 texelOfs = 3 * idx; texel[texelOfs] = cvt_uint32(value.x); texel[texelOfs + 1] = cvt_uint32(value.y); texel[texelOfs + 2] = cvt_uint32(value.z); } inline void setTexel_RGB16( void *uniform data, const uint32 idx, const vec4f value) { uint16 *uniform texel = (uint16 * uniform) data; const uint32 texelOfs = 3 * idx; texel[texelOfs] = cvt_uint16(value.x); texel[texelOfs + 1] = cvt_uint16(value.y); texel[texelOfs + 2] = cvt_uint16(value.z); } inline void setTexel_RA8( void *uniform data, const uint32 idx, const vec4f value) { const uint32 r = cvt_uint32(value.x); const uint32 a = cvt_uint32(value.w); uint32 c = r | (a << 8); ((uint16 * uniform) data)[idx] = c; } inline void setTexel_RA16( void *uniform data, const uint32 idx, const vec4f value) { const uint32 r = cvt_uint16(value.x); const uint32 a = cvt_uint16(value.w); uint32 c = r | (a << 16); ((uint32 * uniform) data)[idx] = c; } inline void setTexel_R8(void *uniform data, const uint32 idx, const vec4f value) { ((uint8 * uniform) data)[idx] = cvt_uint32(value.x); } inline void setTexel_R16( void *uniform data, const uint32 idx, const vec4f value) { ((uint16 * uniform) data)[idx] = cvt_uint16(value.x); } // luminance (basically gamma-corrected grayscale) with alpha inline void setTexel_LA8( void *uniform data, const uint32 idx, const vec4f value) { const uint32 l = cvt_uint32(linear_to_srgb(value.x)); const uint32 a = cvt_uint32(value.w); uint32 c = l | a << 8; ((uint16 * uniform) data)[idx] = c; } // luminance (basically gamma-corrected grayscale) inline void setTexel_L8(void *uniform data, const uint32 idx, const vec4f value) { ((uint8 * uniform) data)[idx] = cvt_uint32(linear_to_srgb(value.x)); } inline void setTexel_SRGBA( void *uniform data, const uint32 idx, const vec4f value) { ((uint32 * uniform) data)[idx] = linear_to_srgba8(value); } inline void setTexel_SRGB( void *uniform data, const uint32 idx, const vec4f value) { uint8 *uniform texel = (uint8 * uniform) data; const uint32 texelOfs = 3 * idx; const vec4f v = linear_to_srgba(value); texel[texelOfs] = cvt_uint32(v.x); texel[texelOfs + 1] = cvt_uint32(v.y); texel[texelOfs + 2] = cvt_uint32(v.z); } inline void setTexel_RGBA32F( void *uniform data, const uint32 idx, const vec4f value) { ((vec4f * uniform) data)[idx] = value; } inline void setTexel_RGB32F( void *uniform data, const uint32 idx, const vec4f value) { ((vec3f * uniform) data)[idx] = make_vec3f(value.x, value.y, value.z); } inline void setTexel_RA32F( void *uniform data, const uint32 idx, const vec4f value) { ((vec2f * uniform) data)[idx] = make_vec2f(value.x, value.w); } inline void setTexel_R32F( void *uniform data, const uint32 idx, const vec4f value) { ((float *uniform)data)[idx] = value.x; } inline vec4f setTexel_RGBA16F( void *uniform data, const uint32 idx, const vec4f value) { const uint32 texelOfs = idx * 2; // write as 2x 32bit const uint32 r = float_to_half(value.x); const uint32 g = float_to_half(value.y); ((uint32 * uniform) data)[texelOfs] = r | (g << 16); const uint32 b = float_to_half(value.z); const uint32 a = float_to_half(value.w); ((uint32 * uniform) data)[texelOfs + 1] = b | (a << 16); } inline vec4f setTexel_RGB16F( void *uniform data, const uint32 idx, const vec4f value) { half *uniform texel = (half * uniform) data; const uint32 texelOfs = 3 * idx; texel[texelOfs] = float_to_half(value.x); texel[texelOfs + 1] = float_to_half(value.y); texel[texelOfs + 2] = float_to_half(value.z); } inline vec4f setTexel_RA16F( void *uniform data, const uint32 idx, const vec4f value) { const uint32 r = float_to_half(value.x); const uint32 a = float_to_half(value.w); ((uint32 * uniform) data)[idx] = r | (a << 16); } inline vec4f setTexel_R16F( void *uniform data, const uint32 idx, const vec4f value) { ((half * uniform) data)[idx] = float_to_half(value.x); } #endif // Low-level texel accessors: getters ////////////////////////////////////////////////////////////////////////////// inline vec4f getTexel_RGBA8(const void *data, const uint32 idx) { assert(data); const uint32 c = ((const uint32 *)data)[idx]; const uint32 r = c & 0xff; const uint32 g = (c >> 8) & 0xff; const uint32 b = (c >> 16) & 0xff; const uint32 a = c >> 24; return make_vec4f((float)r, (float)g, (float)b, (float)a) * BYTE2FLOAT; } inline vec4f getTexel_RGBA16(const void *data, const uint32 idx) { assert(data); const uint32 texelOfs = idx * 2; // fetch as 2x 32bit uint32 c = ((const uint32 *)data)[texelOfs]; const uint32 r = c & 0xffff; const uint32 g = c >> 16; c = ((const uint32 *)data)[texelOfs + 1]; const uint32 b = c & 0xffff; const uint32 a = c >> 16; return make_vec4f((float)r, (float)g, (float)b, (float)a) * SHORT2FLOAT; } inline vec4f getTexel_RGB8(const void *data, const uint32 idx) { assert(data); const uint8 *texel = (const uint8 *)data; const uint32 texelOfs = 3 * idx; const uint32 r = texel[texelOfs]; const uint32 g = texel[texelOfs + 1]; const uint32 b = texel[texelOfs + 2]; return make_vec4f(make_vec3f((float)r, (float)g, (float)b) * BYTE2FLOAT, 1.f); } inline vec4f getTexel_RGB16(const void *data, const uint32 idx) { assert(data); const uint16 *texel = (const uint16 *)data; const uint32 texelOfs = 3 * idx; const uint32 r = texel[texelOfs]; const uint32 g = texel[texelOfs + 1]; const uint32 b = texel[texelOfs + 2]; return make_vec4f( make_vec3f((float)r, (float)g, (float)b) * SHORT2FLOAT, 1.f); } inline vec4f getTexel_RA8(const void *data, const uint32 idx) { assert(data); const uint32 t = ((const uint16 *)data)[idx]; const uint32 c = t & 0xff; const uint32 a = t >> 8; return make_vec4f(c * BYTE2FLOAT, 0.f, 0.f, a * BYTE2FLOAT); } inline vec4f getTexel_RA16(const void *data, const uint32 idx) { assert(data); const uint32 t = ((const uint32 *)data)[idx]; const uint32 c = t & 0xffff; const uint32 a = t >> 16; return make_vec4f(c * SHORT2FLOAT, 0.f, 0.f, a * SHORT2FLOAT); } inline vec4f getTexel_R8(const void *data, const uint32 idx) { assert(data); const uint8 c = ((const uint8 *)data)[idx]; return make_vec4f(c * BYTE2FLOAT, 0.f, 0.f, 1.f); } inline vec4f getTexel_R16(const void *data, const uint32 idx) { assert(data); const uint16 c = ((const uint16 *)data)[idx]; return make_vec4f(c * SHORT2FLOAT, 0.f, 0.f, 1.f); } // luminance (basically gamma-corrected grayscale) with alpha inline vec4f getTexel_LA8(const void *data, const uint32 idx) { assert(data); const uint32 t = ((const uint16 *)data)[idx]; const uint32 l = t & 0xff; const uint32 a = t >> 8; return make_vec4f(make_vec3f(srgb_to_linear(l * BYTE2FLOAT)), a * BYTE2FLOAT); } // luminance (basically gamma-corrected grayscale) inline vec4f getTexel_L8(const void *data, const uint32 idx) { assert(data); const uint8 l = ((const uint8 *)data)[idx]; return make_vec4f(make_vec3f(srgb_to_linear(l * BYTE2FLOAT)), 1.f); } inline vec4f getTexel_SRGBA(const void *data, const uint32 idx) { return srgba_to_linear(getTexel_RGBA8(data, idx)); } inline vec4f getTexel_SRGB(const void *data, const uint32 idx) { return srgba_to_linear(getTexel_RGB8(data, idx)); } inline vec4f getTexel_RGBA32F(const void *data, const uint32 idx) { assert(data); return ((const vec4f *)data)[idx]; } inline vec4f getTexel_RGB32F(const void *data, const uint32 idx) { assert(data); vec3f v = ((const vec3f *)data)[idx]; return make_vec4f(v, 1.f); } inline vec4f getTexel_RA32F(const void *data, const uint32 idx) { assert(data); vec2f v = ((const vec2f *)data)[idx]; return make_vec4f(v.x, 0.0f, 0.0f, v.y); } inline vec4f getTexel_R32F(const void *data, const uint32 idx) { assert(data); float v = ((const float *)data)[idx]; return make_vec4f(v, 0.f, 0.f, 1.f); } inline vec4f getTexel_RGBA16F(const void *data, const uint32 idx) { assert(data); const uint32 texelOfs = idx * 2; // fetch as 2x 32bit uint32 c = ((const uint32 *)data)[texelOfs]; const int16 r = c & 0xffff; const int16 g = c >> 16; c = ((const uint32 *)data)[texelOfs + 1]; const int16 b = c & 0xffff; const int16 a = c >> 16; return make_vec4f( half_to_float(r), half_to_float(g), half_to_float(b), half_to_float(a)); } inline vec4f getTexel_RGB16F(const void *data, const uint32 idx) { assert(data); const half *texel = (const half *)data; const uint32 texelOfs = 3 * idx; const half r = texel[texelOfs]; const half g = texel[texelOfs + 1]; const half b = texel[texelOfs + 2]; return make_vec4f(half_to_float(r), half_to_float(g), half_to_float(b), 1.f); } inline vec4f getTexel_RA16F(const void *data, const uint32 idx) { assert(data); const uint32 t = ((const uint32 *)data)[idx]; const int16 c = t & 0xffff; const int16 a = t >> 16; return make_vec4f(half_to_float(c), 0.0f, 0.0f, half_to_float(a)); } inline vec4f getTexel_R16F(const void *data, const uint32 idx) { assert(data); const half c = ((const half *)data)[idx]; return make_vec4f(half_to_float(c), 0.f, 0.f, 1.f); } #undef BYTE2FLOAT #undef SHORT2FLOAT OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/TextureDispatch.ih000066400000000000000000000007251464752671100247000ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/OSPCommon.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct Texture; struct DifferentialGeometry; SYCL_EXTERNAL vec4f Texture_dispatch_get( const uniform Texture *uniform self, const DifferentialGeometry &dg); SYCL_EXTERNAL vec3f Texture_dispatch_getNormal( const uniform Texture *const uniform self, const DifferentialGeometry &dg); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/TextureDispatch.ispc000066400000000000000000000022161464752671100252330ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/DifferentialGeometry.ih" #include "texture/Texture.ih" #include "texture/Texture2D.ih" #include "texture/TextureVolume.ih" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f Texture_dispatch_get( const uniform Texture *uniform self, const DifferentialGeometry &dg) { switch (self->type) { case TEXTURE_TYPE_2D: return Texture2D_get(self, dg); #ifdef OSPRAY_ENABLE_VOLUMES case TEXTURE_TYPE_VOLUME: return TextureVolume_get(self, dg); #endif default: #ifndef OSPRAY_TARGET_SYCL return self->get(self, dg); #else break; #endif } return make_vec4f(0.f); } SYCL_EXTERNAL vec3f Texture_dispatch_getNormal( const uniform Texture *const uniform self, const DifferentialGeometry &dg) { switch (self->type) { case TEXTURE_TYPE_2D: return Texture2D_getNormal(self, dg); #ifdef OSPRAY_ENABLE_VOLUMES case TEXTURE_TYPE_VOLUME: return TextureVolume_getNormal(self, dg); #endif default: #ifndef OSPRAY_TARGET_SYCL return self->getNormal(self, dg); #else break; #endif } return make_vec3f(0.f); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/TextureParam.ih000066400000000000000000000032161464752671100241770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Texture.ih" #include "common/OSPCommon.ih" #include "rkcommon/math/AffineSpace.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "TextureParamShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE struct DifferentialGeometry; SYCL_EXTERNAL __noinline float get1f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg); SYCL_EXTERNAL __noinline vec3f get3f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg); SYCL_EXTERNAL __noinline vec4f get4f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg); SYCL_EXTERNAL __noinline vec3f getNormal(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg); inline uniform bool valid(const uniform TextureParam uniform &tex) { return tex.ptr; } inline uniform bool hasAlpha(const uniform TextureParam uniform &tex) { return hasAlpha(tex.ptr); } inline float get1f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg, const varying float defaultValue) { if (!valid(tp)) return defaultValue; return get1f(tp, dg); } inline vec3f get3f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg, const varying vec3f defaultValue) { if (!valid(tp)) return defaultValue; return get3f(tp, dg); } inline vec4f get4f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg, const varying vec4f defaultValue) { if (!valid(tp)) return defaultValue; return get4f(tp, dg); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/TextureParam.ispc000066400000000000000000000026621464752671100245410ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "TextureParam.ih" OSPRAY_BEGIN_ISPC_NAMESPACE #define TEXTURE_TRANSFORM(fn) \ DifferentialGeometry xfmDg = dg; \ if (tp.transformFlags & TRANSFORM_FLAG_2D) { \ xfmDg.st = xfmPoint(tp.xform2f, dg.st); \ xfmDg.pixelFootprint *= tp.scale2f; \ } \ if (tp.transformFlags & TRANSFORM_FLAG_3D) \ xfmDg.lP = xfmPoint(tp.xform3f, dg.lP); \ return fn(tp.ptr, xfmDg) SYCL_EXTERNAL __noinline float get1f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg) { TEXTURE_TRANSFORM(get1f); } SYCL_EXTERNAL __noinline vec3f get3f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg) { TEXTURE_TRANSFORM(get3f); } SYCL_EXTERNAL __noinline vec4f get4f(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg) { TEXTURE_TRANSFORM(get4f); } SYCL_EXTERNAL __noinline vec3f getNormal(const uniform TextureParam uniform &tp, const varying DifferentialGeometry &dg) { TEXTURE_TRANSFORM(getNormal); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/texture/TextureParamShared.h000066400000000000000000000012361464752671100251550ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "TextureShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus enum TransformFlags { TRANSFORM_FLAG_NONE = 0x0, TRANSFORM_FLAG_2D = 0x1, TRANSFORM_FLAG_3D = 0x2 }; struct TextureParam { Texture *ptr; TransformFlags transformFlags; float scale2f; // precompute for MIPmapping affine2f xform2f; affine3f xform3f; #ifdef __cplusplus TextureParam() : ptr(nullptr), transformFlags(TRANSFORM_FLAG_NONE), scale2f(1.f), xform2f(one), xform3f(one) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/texture/TextureShared.h000066400000000000000000000017701464752671100241770ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus #if defined(__cplusplus) && !defined(OSPRAY_TARGET_SYCL) typedef void *Texture_get; typedef void *Texture_getN; #else struct Texture; struct DifferentialGeometry; typedef varying vec4f (*Texture_get)( const Texture *uniform self, const varying DifferentialGeometry &dg); typedef varying vec3f (*Texture_getN)( const Texture *uniform self, const varying DifferentialGeometry &dg); #endif enum TextureType { TEXTURE_TYPE_2D, #ifdef OSPRAY_ENABLE_VOLUMES TEXTURE_TYPE_VOLUME, #endif TEXTURE_TYPE_UNKNOWN, }; struct Texture { TextureType type; Texture_get get; Texture_getN getNormal; bool hasAlpha; // 4 channel texture? #ifdef __cplusplus Texture(bool hasAlpha = false) : type(TEXTURE_TYPE_UNKNOWN), get(nullptr), getNormal(nullptr), hasAlpha(hasAlpha) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/texture/TextureVolume.cpp000066400000000000000000000017711464752671100245740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "TextureVolume.h" #ifndef OSPRAY_TARGET_SYCL #include "texture/TextureVolume_ispc.h" #endif namespace ospray { std::string TextureVolume::toString() const { return "ospray::TextureVolume"; } void TextureVolume::commit() { volume = getParamObject("volume"); if (!volume) throw std::runtime_error(toString() + " must have 'volume' object"); transferFunction = getParamObject("transferFunction"); if (!transferFunction) throw std::runtime_error(toString() + " must have 'transferFunction'"); getSh()->volume = volume->getSh(); getSh()->transferFunction = transferFunction->getSh(); #ifndef OSPRAY_TARGET_SYCL getSh()->super.get = reinterpret_cast(ispc::TextureVolume_get_addr()); getSh()->super.getNormal = reinterpret_cast(ispc::TextureVolume_getN_addr()); #endif } } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/texture/TextureVolume.h000066400000000000000000000013251464752671100242340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "Texture.h" #include "volume/Volume.h" #include "volume/transferFunction/TransferFunction.h" // ispc shared #include "TextureVolumeShared.h" namespace ospray { // A Texture defined through a volume struct OSPRAY_SDK_INTERFACE TextureVolume : public AddStructShared { TextureVolume(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) {} virtual std::string toString() const override; virtual void commit() override; private: Ref volume; Ref transferFunction; }; } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/texture/TextureVolume.ih000066400000000000000000000007311464752671100244050ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "Texture.ih" #include "TextureVolumeShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f TextureVolume_get( const uniform Texture *uniform self, const DifferentialGeometry &dg); SYCL_EXTERNAL vec3f TextureVolume_getNormal( const uniform Texture *uniform self, const DifferentialGeometry &dg); OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/texture/TextureVolume.ispc000066400000000000000000000024431464752671100247450ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "Texture.ih" #include "volume/Volume.ih" #include "volume/transferFunction/TransferFunctionDispatch.ih" // c++ shared #include "TextureVolumeShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f TextureVolume_get( const Texture *uniform _self, const varying DifferentialGeometry &dg) { const TextureVolume *uniform self = (const TextureVolume *uniform)_self; const Volume *uniform volume = self->volume; const uniform box3f bounds = volume->boundingBox; if (box_contains(bounds, dg.lP)) { const float sample = Volume_getSample(volume, dg.lP); const TransferFunction *uniform tfn = self->transferFunction; return TransferFunction_dispatch_get(tfn, sample); } else return make_vec4f(0.f); } SYCL_EXTERNAL vec3f TextureVolume_getNormal( const Texture *uniform, const varying DifferentialGeometry &) { // TODO return make_vec3f(0.f, 0.0f, 1.0f); } /////////////////////////////////////////////////////////////////////////////// export void *uniform TextureVolume_get_addr() { return (void *uniform)TextureVolume_get; } export void *uniform TextureVolume_getN_addr() { return (void *uniform)TextureVolume_getNormal; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/texture/TextureVolumeShared.h000066400000000000000000000010571464752671100253650ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "TextureShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Volume; struct TransferFunction; struct TextureVolume { Texture super; const Volume *volume; const TransferFunction *transferFunction; #ifdef __cplusplus TextureVolume() : super(true), volume(nullptr), transferFunction(nullptr) { super.type = TEXTURE_TYPE_VOLUME; } }; } // namespace ispc #else }; #endif // __cplusplus #endif RenderKit-ospray-85af292/modules/cpu/texture/registration.cpp000066400000000000000000000005641464752671100244550ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Texture2D.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "TextureVolume.h" #endif namespace ospray { void registerAllTextures() { Texture::registerType("texture2d"); #ifdef OSPRAY_ENABLE_VOLUMES Texture::registerType("volume"); #endif } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/texture/registration.h000066400000000000000000000002231464752671100241120ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllTextures(); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/volume/000077500000000000000000000000001464752671100210415ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/volume/Volume.cpp000066400000000000000000000157631464752671100230300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES // ospray #include "volume/Volume.h" #include "common/Data.h" #ifndef OSPRAY_TARGET_SYCL #include "volume/Volume_ispc.h" #else namespace ispc { void Volume_embreeBounds(const void *_args); } // namespace ispc #endif #include "openvkl/openvkl.h" #include "openvkl/vdb.h" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.h" #include namespace ospray { // Volume definitions //////////////////////////////////////////////////////// Volume::Volume(api::ISPCDevice &device, const std::string &type) : AddStructShared(device.getDRTDevice(), device), vklType(type), vklFeatureFlags(VKL_FEATURE_FLAGS_NONE) { // check VKL has default config for VDB if (type == "vdb" && (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."); managedObjectType = OSP_VOLUME; } Volume::~Volume() { if (vklSampler) vklRelease(vklSampler); if (vklVolume) vklRelease(vklVolume); if (embreeGeometry) rtcReleaseGeometry(embreeGeometry); } std::string Volume::toString() const { return "ospray::Volume"; } void Volume::commit() { VKLDevice vklDevice = getISPCDevice().getVklDevice(); if (!vklDevice) { throw std::runtime_error("invalid Open VKL device"); } RTCDevice embreeDevice = getISPCDevice().getEmbreeDevice(); if (!embreeDevice) { throw std::runtime_error("invalid Embree device"); } if (vklSampler) vklRelease(vklSampler); if (vklVolume) vklRelease(vklVolume); vklVolume = vklNewVolume(vklDevice, vklType.c_str()); if (!vklVolume) throw std::runtime_error("unsupported volume type '" + vklType + "'"); if (!embreeGeometry) { embreeGeometry = rtcNewGeometry(embreeDevice, RTC_GEOMETRY_TYPE_USER); } handleParams(); vklCommit(vklVolume); (vkl_box3f &)bounds = vklGetBoundingBox(vklVolume); vklSampler = vklNewSampler(vklVolume); vklCommit(vklSampler); vklFeatureFlags = vklGetFeatureFlags(vklSampler); // Setup Embree user-defined geometry rtcSetGeometryUserData(embreeGeometry, getSh()); rtcSetGeometryUserPrimitiveCount(embreeGeometry, 1); rtcSetGeometryBoundsFunction( embreeGeometry, (RTCBoundsFunction)&ispc::Volume_embreeBounds, getSh()); rtcCommitGeometry(embreeGeometry); // Initialize shared structure getSh()->vklVolume = vklVolume; getSh()->vklSampler = vklSampler; getSh()->boundingBox = bounds; } void Volume::checkDataStride(const Data *data) const { if (data->stride().y != int64_t(data->numItems.x) * data->stride().x || data->stride().z != int64_t(data->numItems.y) * data->stride().y) { throw std::runtime_error( toString() + " Open VKL only supports 1D strides between elements"); } } void Volume::handleParams() { // pass all supported parameters through to VKL volume object std::for_each(params_begin(), params_end(), [&](std::shared_ptr &p) { auto ¶m = *p; param.query = true; if (param.data.is()) { vklSetBool(vklVolume, param.name.c_str(), param.data.get()); } else if (param.data.is()) { vklSetFloat(vklVolume, param.name.c_str(), param.data.get()); } else if (param.data.is()) { vklSetInt(vklVolume, param.name.c_str(), param.data.get()); } else if (param.data.is()) { vklSetInt(vklVolume, param.name.c_str(), param.data.get()); } else if (param.data.is()) { vklSetVec3f(vklVolume, param.name.c_str(), param.data.get().x, param.data.get().y, param.data.get().z); } else if (param.data.is()) { vklSetVoidPtr(vklVolume, param.name.c_str(), param.data.get()); } else if (param.data.is()) { vklSetString( vklVolume, param.name.c_str(), param.data.get()); } else if (param.data.is()) { vklSetVec3i(vklVolume, param.name.c_str(), param.data.get().x, param.data.get().y, param.data.get().z); } else if (param.data.is()) { VKLDevice vklDevice = getISPCDevice().getVklDevice(); Data *data = (Data *)param.data.get(); if (data->type == OSP_DATA) { auto &dataD = data->as(); std::vector vklBlockData; vklBlockData.reserve(data->size()); for (auto &&data : dataD) { checkDataStride(data); VKLData vklData = vklNewData(vklDevice, data->size(), (VKLDataType)data->type, data->data(), VKL_DATA_SHARED_BUFFER, data->stride().x); vklBlockData.push_back(vklData); } VKLData vklData = vklNewData( vklDevice, vklBlockData.size(), VKL_DATA, vklBlockData.data()); vklSetData(vklVolume, param.name.c_str(), vklData); vklRelease(vklData); for (VKLData vd : vklBlockData) vklRelease(vd); if (vklType == "vdb" && param.name == "node.data") { // deduce format std::vector format; format.reserve(data->size()); for (auto &&data : dataD) { bool isTile = data->size() == 1; if (!isTile) { if (data->numItems.x != data->numItems.y || data->numItems.x != data->numItems.z) 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); } VKLData vklData = vklNewData(vklDevice, format.size(), VKL_UINT, format.data()); vklSetData(vklVolume, "node.format", vklData); vklRelease(vklData); } } else { checkDataStride(data); VKLData vklData = vklNewData(vklDevice, data->size(), (VKLDataType)data->type, data->data(), VKL_DATA_SHARED_BUFFER, data->stride().x); std::string name(param.name); if (name == "data") { // structured volumes vec3ul &dim = data->numItems; vklSetVec3i(vklVolume, "dimensions", dim.x, dim.y, dim.z); } if (name == "nodesPackedDense" || name == "nodesPackedTile") { // packed VDB volumes: wrap attribute VKLData vklDataWrapper = vklNewData(vklDevice, 1, VKL_DATA, &vklData); vklRelease(vklData); vklData = vklDataWrapper; } vklSetData(vklVolume, name.c_str(), vklData); vklRelease(vklData); } } else { param.query = false; } }); } OSPTYPEFOR_DEFINITION(Volume *); } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/volume/Volume.h000066400000000000000000000025201464752671100224600ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "ISPCDeviceObject.h" #include "common/FeatureFlagsEnum.h" #include "common/StructShared.h" // embree #include "common/Embree.h" // openvkl #include "openvkl/openvkl.h" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.h" // ispc shared #include "VolumeShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE Volume : public AddStructShared { Volume(api::ISPCDevice &device, const std::string &vklType); ~Volume() override; std::string toString() const override; void commit() override; FeatureFlags getFeatureFlags() const; private: void checkDataStride(const Data *) const; void handleParams(); // Friends // friend struct Isosurfaces; friend struct VolumetricModel; // Data // RTCGeometry embreeGeometry{nullptr}; VKLVolume vklVolume = VKLVolume(); VKLSampler vklSampler = VKLSampler(); box3f bounds{empty}; std::string vklType; VKLFeatureFlags vklFeatureFlags = VKL_FEATURE_FLAGS_NONE; }; OSPTYPEFOR_SPECIALIZATION(Volume *, OSP_VOLUME); inline FeatureFlags Volume::getFeatureFlags() const { FeatureFlags ff; ff.volume = vklFeatureFlags; return ff; } } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/volume/Volume.ih000066400000000000000000000030521464752671100226320ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "common/Embree.h" #ifdef ISPC #include "openvkl/openvkl.isph" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.isph" #else #include "openvkl/openvkl.h" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.h" #endif #include "common/FeatureFlags.ih" #include "rkcommon/math/box.ih" // c++ shared #include "VolumeShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // Helper functions /////////////////////////////////////////////////////////// inline float Volume_getSample(const Volume *uniform volume, const vec3f &P) { return vklComputeSampleV(&volume->vklSampler, &((const vkl_vec3f &)P)); } inline vec3f Volume_getGradient(const Volume *uniform volume, const vec3f &P, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); vkl_vec3f result = vklComputeGradientV(&volume->vklSampler, &((const vkl_vec3f &)P) #ifdef OSPRAY_TARGET_SYCL , 0, 0.f, ff.volume #endif ); // 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; return *((varying vec3f *)&result); } RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Volume_intersect_kernel( RTCIntersectFunctionNArguments *uniform args); OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/volume/Volume.ispc000066400000000000000000000047001464752671100231710ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "common/Intersect.ih" #include "common/Ray.ih" #include "common/VolumeIntervals.ih" #include "volume/Volume.ih" OSPRAY_BEGIN_ISPC_NAMESPACE export void Volume_embreeBounds(const void *uniform _args) { const RTCBoundsFunctionArguments *uniform args = (const RTCBoundsFunctionArguments *uniform)_args; Volume *uniform self = (Volume * uniform) args->geometryUserPtr; box3fa *uniform out = (box3fa * uniform) args->bounds_o; *out = make_box3fa(self->boundingBox); } RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Volume_intersect_kernel( RTCIntersectFunctionNArguments *uniform args) { // make sure to set the mask if (!args->valid[programIndex]) return; Volume *uniform self = (Volume * uniform) args->geometryUserPtr; varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; box3f *uniform box = &self->boundingBox; const Intersections isect = intersectBox(ray->org, ray->dir, *box); const float t_min = max(ray->t0, isect.entry.t); const float t_max = min(ray->t, isect.exit.t); if (t_min < t_max) { ray->instID = args->context->instID[0]; ray->geomID = args->geomID; ray->primID = 0; RayQueryContextVolume *uniform ctx = (RayQueryContextVolume * uniform) args->context; varying VolumeIntervals *uniform vIntervals = (varying VolumeIntervals * uniform) ctx->intervals; #ifndef OSPRAY_TARGET_SYCL // Grow TLS pool if needed, note that we cannot grow it on the GPU b/c no // dymanic memory. With SYCL we just take the first hit found uniform unsigned int numNeeded = reduce_max(vIntervals->numVolumeIntervals) + 1; if (numNeeded > vIntervals->numAllocated) { vIntervals->intervals = (varying VolumeInterval * uniform) reallocTLS( vIntervals->intervals, numNeeded * sizeof(varying VolumeInterval)); vIntervals->numAllocated = numNeeded; } varying VolumeInterval *varying vInterval = (varying VolumeInterval * varying)(vIntervals->intervals + vIntervals->numVolumeIntervals); #else varying VolumeInterval *uniform vInterval = vIntervals->intervals; #endif vInterval->primID = 0; vInterval->geomID = args->geomID; vInterval->instID = args->context->instID[0]; vInterval->interval.lower = t_min; vInterval->interval.upper = t_max; vIntervals->numVolumeIntervals++; } } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/volume/VolumeShared.h000066400000000000000000000015101464752671100236050ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus // Variables and methods common to all subtypes of the Volume // class, an abstraction for the concrete object which performs the // volume sampling (this struct must be the first field of a struct // representing a "derived" class to allow casting to that class). struct Volume { VKLVolume vklVolume; VKLSampler vklSampler; // Bounding box for the volume in world coordinates. // This is an internal derived parameter and not meant to be // redefined externally. box3f boundingBox; #ifdef __cplusplus Volume() : vklVolume(VKLVolume()), vklSampler(VKLSampler()), boundingBox(0.f) {} }; } // namespace ispc #else }; #endif // __cplusplus #endif RenderKit-ospray-85af292/modules/cpu/volume/VolumetricModel.cpp000066400000000000000000000056121464752671100246630ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #include "openvkl/openvkl.h" // ospray #include "VolumetricModel.h" namespace ospray { VolumetricModel::VolumetricModel(api::ISPCDevice &device, Volume *_volume) : AddStructShared(device.getDRTDevice(), device), volumeAPI(_volume) { managedObjectType = OSP_VOLUMETRIC_MODEL; } VolumetricModel::~VolumetricModel() { if (vklIntervalContext) vklRelease(vklIntervalContext); } std::string VolumetricModel::toString() const { return "ospray::VolumetricModel"; } void VolumetricModel::commit() { volume = getParamObject("volume", volumeAPI.ptr); if (!volume) throw std::runtime_error(toString() + " received NULL 'volume'"); transferFunction = getParamObject("transferFunction"); if (!transferFunction) throw std::runtime_error(toString() + " must have 'transferFunction'"); // create value selector using transfer function and pass to volume if (volume->vklVolume) { if (vklIntervalContext) { vklRelease(vklIntervalContext); } vklIntervalContext = vklNewIntervalIteratorContext(volume->vklSampler); std::vector valueRanges = transferFunction->getPositiveOpacityValueRanges(); if (valueRanges.empty()) { // volume made completely transparent and could be removed, which is // awkward here // set an "empty" interesting value range instead, which will lead to a // quick out during volume iteration valueRanges.push_back(range1f(neg_inf, neg_inf)); } VKLData valueRangeData = vklNewData(getISPCDevice().getVklDevice(), valueRanges.size(), VKL_BOX1F, valueRanges.data()); vklSetData(vklIntervalContext, "valueRanges", valueRangeData); vklRelease(valueRangeData); vklCommit(vklIntervalContext); // Pass interval context to ISPC getSh()->vklIntervalContext = vklIntervalContext; } // Finish getting/setting other appearance information volumeBounds = volume->bounds; // Initialize shared structure getSh()->volume = getVolume()->getSh(); getSh()->transferFunction = transferFunction->getSh(); getSh()->boundingBox = volumeBounds; getSh()->densityScale = getParam("densityScale", 1.f); getSh()->anisotropy = getParam("anisotropy", 0.f); getSh()->gradientShadingScale = getParam("gradientShadingScale", 0.f); getSh()->userID = getParam("id", RTC_INVALID_GEOMETRY_ID); featureFlagsOther = FFO_VOLUME_IN_SCENE; if (getSh()->gradientShadingScale > 0.f) featureFlagsOther |= FFO_VOLUME_SCIVIS_SHADING; } RTCGeometry VolumetricModel::embreeGeometryHandle() const { return volume->embreeGeometry; } box3f VolumetricModel::bounds() const { return volumeBounds; } Ref VolumetricModel::getVolume() const { return volume; } OSPTYPEFOR_DEFINITION(VolumetricModel *); } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/volume/VolumetricModel.h000066400000000000000000000025601464752671100243270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "Volume.h" #include "common/FeatureFlagsEnum.h" #include "openvkl/openvkl.h" // comment break to prevent clang-format from reordering openvkl includes #include "openvkl/device/openvkl.h" #include "transferFunction/TransferFunction.h" // ispc shared #include "volume/VolumetricModelShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE VolumetricModel : public AddStructShared { VolumetricModel(api::ISPCDevice &device, Volume *geometry); ~VolumetricModel() override; std::string toString() const override; void commit() override; RTCGeometry embreeGeometryHandle() const; box3f bounds() const; Ref getVolume() const; FeatureFlags getFeatureFlags() const; private: box3f volumeBounds; Ref volume; Ref transferFunction; const Ref volumeAPI; VKLIntervalIteratorContext vklIntervalContext = VKLIntervalIteratorContext(); FeatureFlagsOther featureFlagsOther{FFO_VOLUME_IN_SCENE}; }; OSPTYPEFOR_SPECIALIZATION(VolumetricModel *, OSP_VOLUMETRIC_MODEL); inline FeatureFlags VolumetricModel::getFeatureFlags() const { FeatureFlags ff = volume->getFeatureFlags(); ff.other |= featureFlagsOther; return ff; } } // namespace ospray #endif RenderKit-ospray-85af292/modules/cpu/volume/VolumetricModel.ih000066400000000000000000000015641464752671100245030ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #include "../common/DifferentialGeometry.ih" #include "../common/Ray.ih" #include "Volume.ih" #include "transferFunction/TransferFunctionShared.h" // c++ shared #include "VolumetricModelShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE inline void VolumetricModel_postIntersect(const VolumetricModel *uniform self, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64) { dg.Ng = make_vec3f(0.f); dg.Ns = make_vec3f(0.f); dg.dPds = make_vec3f(0.f); dg.dPdt = make_vec3f(0.f); dg.st = make_vec2f(0); dg.color = make_vec4f(0.f); dg.primID = 0; dg.objID = (self->userID == RTC_INVALID_GEOMETRY_ID) ? ray.geomID : self->userID; dg.areaPDF = 0.f; dg.epsilon = 0.f; dg.material = NULL; } OSPRAY_END_ISPC_NAMESPACE #endif RenderKit-ospray-85af292/modules/cpu/volume/VolumetricModelShared.h000066400000000000000000000017331464752671100254570ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifdef OSPRAY_ENABLE_VOLUMES #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct Volume; struct TransferFunction; struct VolumetricModel { Volume *volume; TransferFunction *transferFunction; VKLIntervalIteratorContext vklIntervalContext; box3f boundingBox; // Volume parameters understood by the pathtracer float densityScale; float anisotropy; // the anisotropy of the volume's phase function // (Heyney-Greenstein) float gradientShadingScale; unsigned int userID; #ifdef __cplusplus VolumetricModel() : volume(nullptr), transferFunction(nullptr), vklIntervalContext(VKLIntervalIteratorContext()), boundingBox(0.f), densityScale(1.f), anisotropy(0.f), gradientShadingScale(0.f), userID(RTC_INVALID_GEOMETRY_ID) {} }; } // namespace ispc #else }; #endif // __cplusplus #endif RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/000077500000000000000000000000001464752671100243735ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/LinearTransferFunction.cpp000066400000000000000000000113141464752671100315240ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "LinearTransferFunction.h" #ifndef OSPRAY_TARGET_SYCL #include "volume/transferFunction/LinearTransferFunction_ispc.h" #else namespace ispc { void *LinearTransferFunction_get_addr(); void *LinearTransferFunction_getMaxOpacity_addr(); } // namespace ispc #endif namespace ospray { LinearTransferFunction::LinearTransferFunction(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { getSh()->super.valueRange = range1f(0.0f, 1.0f); } void LinearTransferFunction::commit() { TransferFunction::commit(); colorValues = getParamDataT("color", true); opacityValues = getParamDataT("opacity", true); getSh()->color = *ispc(colorValues); getSh()->opacity = *ispc(opacityValues); precomputeMaxOpacityRanges(); } std::string LinearTransferFunction::toString() const { return "ospray::LinearTransferFunction"; } std::vector LinearTransferFunction::getPositiveOpacityIndexRanges() const { std::vector intervals; range1i interval; bool rangeActive = false; const DataT &opacities = *opacityValues; for (int i = 0; i < int(opacities.size()); i++) { if (opacities[i] > 0.f && !rangeActive) { rangeActive = true; interval.lower = i; } else if (opacities[i] <= 0.f && rangeActive) { rangeActive = false; interval.upper = i; intervals.push_back(interval); } } // special case for final value if (opacities[opacities.size() - 1] > 0.f) { if (rangeActive) { rangeActive = false; interval.upper = opacities.size(); intervals.push_back(interval); } else { throw std::runtime_error("getPositiveOpacityIndexRanges() error"); } } return intervals; } std::vector LinearTransferFunction::getPositiveOpacityValueRanges() const { std::vector valueRanges; // determine index ranges for positive opacities std::vector indexRanges = getPositiveOpacityIndexRanges(); const DataT &opacities = *opacityValues; // convert index ranges to value ranges // note that a positive opacity value has a span of +/-1 due to the linear // interpolation, and returned index ranges are [min, max) intervals for (int i = 0; i < int(indexRanges.size()); i++) { int minValueIndex = indexRanges[i].lower - 1; int maxValueIndex = indexRanges[i].upper; range1f range(neg_inf, inf); if (minValueIndex >= 0) { range.lower = valueRange.lower + minValueIndex * valueRange.size() / (opacities.size() - 1.f); } if (maxValueIndex < int(opacities.size())) { range.upper = valueRange.lower + maxValueIndex * valueRange.size() / (opacities.size() - 1.f); } valueRanges.push_back(range); } return valueRanges; } void LinearTransferFunction::precomputeMaxOpacityRanges() { const DataT &opacities = *opacityValues; const int maxOpacityDim = opacities.size() - 1; const int maxPrecomputedDim = PRECOMPUTED_OPACITY_SUBRANGE_COUNT - 1; // compute the diagonal for (int i = 0; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; i++) { // figure out the range of array indices we are going to compare; this is a // conservative range of feasible indices that may be used to lookup // opacities for any data value within the value range corresponding to [i, // i]. const int checkRangeLow = floor(maxOpacityDim * (float)i / maxPrecomputedDim); const int checkRangeHigh = ceil(maxOpacityDim * (float)i / maxPrecomputedDim); float maxOpacity = opacities[checkRangeLow]; for (int opacityIDX = checkRangeLow; opacityIDX <= checkRangeHigh; opacityIDX++) maxOpacity = std::max(maxOpacity, opacities[opacityIDX]); getSh()->maxOpacityInRange[i][i] = maxOpacity; } // fill out each column from the diagonal up for (int i = 0; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; i++) { for (int j = i + 1; j < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; j++) { // figure out the range of array indices we are going to compare; this is // a conservative range of feasible indices that may be used to lookup // opacities for any data value within the value range corresponding to // [i, j]. const int checkRangeLow = floor(maxOpacityDim * (float)i / maxPrecomputedDim); const int checkRangeHigh = ceil(maxOpacityDim * (float)j / maxPrecomputedDim); float maxOpacity = getSh()->maxOpacityInRange[i][i]; for (int opacityIDX = checkRangeLow; opacityIDX <= checkRangeHigh; opacityIDX++) maxOpacity = std::max(maxOpacity, opacities[opacityIDX]); getSh()->maxOpacityInRange[i][j] = maxOpacity; } } } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/LinearTransferFunction.h000066400000000000000000000015231464752671100311720ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "TransferFunction.h" #include "common/Data.h" // ispc shared #include "LinearTransferFunctionShared.h" namespace ospray { // piecewise linear transfer function struct OSPRAY_SDK_INTERFACE LinearTransferFunction : public AddStructShared { LinearTransferFunction(api::ISPCDevice &device); virtual void commit() override; virtual std::string toString() const override; virtual std::vector getPositiveOpacityValueRanges() const override; virtual std::vector getPositiveOpacityIndexRanges() const override; private: Ref> colorValues; Ref> opacityValues; void precomputeMaxOpacityRanges(); }; } // namespace ospray RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/LinearTransferFunction.ih000066400000000000000000000006711464752671100313460ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/box.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct TransferFunction; SYCL_EXTERNAL vec4f LinearTransferFunction_get( const TransferFunction *uniform _self, float value); SYCL_EXTERNAL float LinearTransferFunction_getMaxOpacity( const TransferFunction *uniform _self, const range1f &valueRange); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/LinearTransferFunction.ispc000066400000000000000000000037461464752671100317120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "LinearTransferFunction.ih" #include "common/Data.ih" // c++ shared #include "LinearTransferFunctionShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f LinearTransferFunction_get( const TransferFunction *uniform _self, float value) { const LinearTransferFunction *uniform self = (const LinearTransferFunction *uniform)_self; // remap to [0.0, 1.0] value = (value - self->super.valueRange.lower) * rcp(box_size(self->super.valueRange)); // clamp to [0.0, 1.0) const uniform float nextBefore1 = 0x1.fffffep-1f; value = clamp(value, 0.0f, nextBefore1); const uniform int maxIdxC = self->color.numItems - 1; const float idxCf = value * maxIdxC; const float fracC = frac(idxCf); const int idxC = idxCf; const vec3f col = lerp(fracC, get_vec3f(self->color, idxC), get_vec3f(self->color, min(maxIdxC, idxC + 1))); const uniform int maxIdxO = self->opacity.numItems - 1; const float idxOf = value * maxIdxO; const float fracO = frac(idxOf); const int idxO = idxOf; const float opacity = lerp(fracO, get_float(self->opacity, idxO), get_float(self->opacity, min(maxIdxO, idxO + 1))); return make_vec4f(col, opacity); } SYCL_EXTERNAL float LinearTransferFunction_getMaxOpacity( const TransferFunction *uniform _self, const range1f &valueRange) { uniform LinearTransferFunction *uniform self = (uniform LinearTransferFunction * uniform) _self; const uniform int maxDim = PRECOMPUTED_OPACITY_SUBRANGE_COUNT - 1; const uniform float denom = self->super.valueRange.upper - self->super.valueRange.lower; const varying int i = floor(clamp((valueRange.lower - self->super.valueRange.lower) / denom) * maxDim); const varying int j = ceil(clamp((valueRange.upper - self->super.valueRange.lower) / denom) * maxDim); return self->maxOpacityInRange[min(i, maxDim)][min(j, maxDim)]; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/LinearTransferFunctionShared.h000066400000000000000000000012431464752671100323200ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "TransferFunctionShared.h" #define PRECOMPUTED_OPACITY_SUBRANGE_COUNT 32 #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct LinearTransferFunction { TransferFunction super; Data1D color; Data1D opacity; // precomputed maximum opacity values per range float maxOpacityInRange[PRECOMPUTED_OPACITY_SUBRANGE_COUNT] [PRECOMPUTED_OPACITY_SUBRANGE_COUNT]; #ifdef __cplusplus LinearTransferFunction() { super.type = TRANSFER_FUNCTION_TYPE_LINEAR; } #endif }; #ifdef __cplusplus } // namespace ispc #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/TransferFunction.cpp000066400000000000000000000012411464752671100303670ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "TransferFunction.h" namespace ospray { // TransferFunction definitions /////////////////////////////////////////////// TransferFunction::TransferFunction(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device) { managedObjectType = OSP_TRANSFER_FUNCTION; } void TransferFunction::commit() { valueRange = getParam("value", range1f(0.0f, 1.0f)); getSh()->valueRange = valueRange; } std::string TransferFunction::toString() const { return "ospray::TransferFunction"; } OSPTYPEFOR_DEFINITION(TransferFunction *); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/TransferFunction.h000066400000000000000000000015061464752671100300400ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ISPCDeviceObject.h" #include "common/ObjectFactory.h" #include "common/StructShared.h" // ispc shared #include "TransferFunctionShared.h" namespace ospray { struct OSPRAY_SDK_INTERFACE TransferFunction : public AddStructShared, public ObjectFactory { TransferFunction(api::ISPCDevice &device); virtual void commit() override; virtual std::string toString() const override; range1f valueRange; virtual std::vector getPositiveOpacityValueRanges() const = 0; virtual std::vector getPositiveOpacityIndexRanges() const = 0; }; OSPTYPEFOR_SPECIALIZATION(TransferFunction *, OSP_TRANSFER_FUNCTION); } // namespace ospray RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/TransferFunctionDispatch.ih000066400000000000000000000006751464752671100316770ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/math/box.ih" OSPRAY_BEGIN_ISPC_NAMESPACE struct TransferFunction; SYCL_EXTERNAL vec4f TransferFunction_dispatch_get( const TransferFunction *uniform self, float value); SYCL_EXTERNAL float TransferFunction_dispatch_getMaxOpacity( const TransferFunction *uniform self, const range1f &valueRange); OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/TransferFunctionDispatch.ispc000066400000000000000000000014471464752671100322330ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "LinearTransferFunction.ih" #include "TransferFunctionDispatch.ih" #include "TransferFunctionShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE SYCL_EXTERNAL vec4f TransferFunction_dispatch_get( const TransferFunction *uniform self, float value) { switch (self->type) { case TRANSFER_FUNCTION_TYPE_LINEAR: return LinearTransferFunction_get(self, value); default: return make_vec4f(0.f); } } SYCL_EXTERNAL float TransferFunction_dispatch_getMaxOpacity( const TransferFunction *uniform self, const range1f &valueRange) { switch (self->type) { case TRANSFER_FUNCTION_TYPE_LINEAR: return LinearTransferFunction_getMaxOpacity(self, valueRange); default: return 0.f; } } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/TransferFunctionShared.h000066400000000000000000000012231464752671100311630ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus namespace ispc { #endif // __cplusplus // We only have one transfer function type, but we still have the type enum and // "dispatch" function so that we can easily extend it with more in the future enum TransferFunctionType { TRANSFER_FUNCTION_TYPE_LINEAR = 0, TRANSFER_FUNCTION_TYPE_UNKNOWN = 1, }; struct TransferFunction { TransferFunctionType type; range1f valueRange; #ifdef __cplusplus TransferFunction() : type(TRANSFER_FUNCTION_TYPE_UNKNOWN), valueRange(0.f, 1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/registration.cpp000066400000000000000000000004211464752671100276060ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "LinearTransferFunction.h" namespace ospray { void registerAllTransferFunctions() { TransferFunction::registerType("piecewiseLinear"); } } // namespace ospray RenderKit-ospray-85af292/modules/cpu/volume/transferFunction/registration.h000066400000000000000000000002341464752671100272550ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 namespace ospray { void registerAllTransferFunctions(); } // namespace ospray RenderKit-ospray-85af292/modules/denoiser/000077500000000000000000000000001464752671100205535ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/denoiser/CMakeLists.txt000066400000000000000000000012521464752671100233130ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_dependent_option( OSPRAY_MODULE_DENOISER "Build the Denoiser FrameOp module for denoising (requires OIDN)" OFF OSPRAY_MODULE_CPU OFF ) if (NOT OSPRAY_MODULE_DENOISER) return() endif() include(GenerateExportHeader) add_library(ospray_module_denoiser SHARED ${OSPRAY_RESOURCE} ModuleInit.cpp DenoiseFrameOp.cpp) generate_export_header(ospray_module_denoiser) target_link_libraries(ospray_module_denoiser PRIVATE OpenImageDenoise ospray ) target_include_directories(ospray_module_denoiser PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ) ospray_install_library(ospray_module_denoiser lib) RenderKit-ospray-85af292/modules/denoiser/DenoiseFrameOp.cpp000066400000000000000000000330551464752671100241250ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DenoiseFrameOp.h" #include "common/DeviceRT.h" #include "fb/FrameBufferView.h" namespace ospray { // error callback void checkError(void * /*userPtr*/, oidn::Error error, const char *errorMessage) { if (error != oidn::Error::None && error != oidn::Error::Cancelled) { throw std::runtime_error( "Error running OIDN: " + std::string(errorMessage)); } } void checkError(oidn::DeviceRef &oidnDevice) { const char *errorMessage = nullptr; auto error = oidnDevice.getError(errorMessage); checkError(nullptr, error, errorMessage); } struct OSPRAY_MODULE_DENOISER_EXPORT LiveDenoiseFrameOp : public LiveFrameOpInterface { LiveDenoiseFrameOp(DenoiseFrameOp *denoiser, FrameBufferView &fbView) : denoiser(denoiser), fbView(fbView), filter(denoiser->oidnDevice.newFilter("RT")) { filter.set("hdr", true); } protected: void updateFilters(); virtual void initFilterAlphaImages() = 0; virtual void initFilterAuxImages() = 0; virtual void updateFilterInput() = 0; virtual void updateAuxImages(oidn::FilterRef &) = 0; Ref denoiser; FrameBufferView fbView; oidn::FilterRef filter; oidn::FilterRef filterAlpha; oidn::FilterRef filterAlbedo; oidn::FilterRef filterNormal; bool prefilter{false}; }; void LiveDenoiseFrameOp::updateFilters() { prefilter = denoiser->quality == OIDN_QUALITY_HIGH; if (prefilter) { if (fbView.normalBuffer && !filterNormal) { filterNormal = denoiser->oidnDevice.newFilter("RT"); filterNormal.set("quality", OIDN_QUALITY_HIGH); } if (fbView.albedoBuffer && !filterAlbedo) { filterAlbedo = denoiser->oidnDevice.newFilter("RT"); filterAlbedo.set("quality", OIDN_QUALITY_HIGH); } initFilterAuxImages(); if (fbView.normalBuffer) filterNormal.commit(); if (fbView.albedoBuffer) filterAlbedo.commit(); } filter.set("quality", denoiser->quality); filter.set("cleanAux", prefilter); updateFilterInput(); updateAuxImages(filter); if (denoiser->denoiseAlpha) { if (!filterAlpha) { filterAlpha = denoiser->oidnDevice.newFilter("RT"); filterAlpha.set("hdr", false); initFilterAlphaImages(); } filterAlpha.set("quality", denoiser->quality); filterAlpha.set("cleanAux", prefilter); updateAuxImages(filterAlpha); } filter.commit(); if (denoiser->denoiseAlpha) filterAlpha.commit(); } struct OSPRAY_MODULE_DENOISER_EXPORT LiveDenoiseFrameOpShared : public LiveDenoiseFrameOp { LiveDenoiseFrameOpShared(DenoiseFrameOp *, FrameBufferView &); protected: // when alpha is not denoised we copy input buffer to output and then do // in-place denoising to preserve alpha oidn::BufferRef bufferOut; // shared buffer aliasing colorBufferOutput private: void initFilterAlphaImages() override; void initFilterAuxImages() override; void updateFilterInput() override; void updateAuxImages(oidn::FilterRef &) override; oidn::BufferRef bufferAux; // scratch buffer when prefiltering size_t byteAlbedoOffset; }; LiveDenoiseFrameOpShared::LiveDenoiseFrameOpShared( DenoiseFrameOp *denoiser, FrameBufferView &fbView) : LiveDenoiseFrameOp(denoiser, fbView), bufferOut(denoiser->oidnDevice.newBuffer(fbView.colorBufferOutput, fbView.viewDims.long_product() * sizeof(vec4f))) { filter.setImage("output", bufferOut, oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y, 0, 4 * sizeof(float)); updateFilters(); } void LiveDenoiseFrameOpShared::initFilterAlphaImages() { filterAlpha.setImage("color", const_cast(fbView.colorBufferInput), oidn::Format::Float, fbView.viewDims.x, fbView.viewDims.y, 3 * sizeof(float), 4 * sizeof(float)); filterAlpha.setImage("output", bufferOut, oidn::Format::Float, fbView.viewDims.x, fbView.viewDims.y, 3 * sizeof(float), 4 * sizeof(float)); } void LiveDenoiseFrameOpShared::initFilterAuxImages() { if (!bufferAux) { const size_t byteBufferSize = 3 * sizeof(float) * fbView.fbDims.product(); size_t sz = 0; if (fbView.normalBuffer) sz += byteBufferSize; if (fbView.albedoBuffer) { byteAlbedoOffset = sz; sz += byteBufferSize; } bufferAux = denoiser->oidnDevice.newBuffer(sz, oidn::Storage::Device); } if (fbView.normalBuffer) { filterNormal.setImage("normal", const_cast(fbView.normalBuffer), oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y); filterNormal.setImage("output", bufferAux, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y); } if (fbView.albedoBuffer) { filterAlbedo.setImage("albedo", const_cast(fbView.albedoBuffer), oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y); filterAlbedo.setImage("output", bufferAux, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteAlbedoOffset); } } void LiveDenoiseFrameOpShared::updateFilterInput() { if (denoiser->denoiseAlpha) filter.setImage("color", const_cast(fbView.colorBufferInput), oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y, 0, 4 * sizeof(float)); else filter.setImage("color", bufferOut, // in-place filtering of copied input oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y, 0, 4 * sizeof(float)); } void LiveDenoiseFrameOpShared::updateAuxImages(oidn::FilterRef &filter) { if (prefilter) { if (fbView.normalBuffer) filter.setImage("normal", bufferAux, oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y); if (fbView.albedoBuffer) filter.setImage("albedo", bufferAux, oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y, byteAlbedoOffset); } else { if (fbView.normalBuffer) filter.setImage("normal", const_cast(fbView.normalBuffer), oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y); if (fbView.albedoBuffer) filter.setImage("albedo", const_cast(fbView.albedoBuffer), oidn::Format::Float3, fbView.viewDims.x, fbView.viewDims.y); } } struct OSPRAY_MODULE_DENOISER_EXPORT LiveDenoiseFrameOpSharedSycl : public LiveDenoiseFrameOpShared { LiveDenoiseFrameOpSharedSycl( DenoiseFrameOp *denoiser, FrameBufferView &fbView) : LiveDenoiseFrameOpShared(denoiser, fbView) {} devicert::AsyncEvent process() override; }; devicert::AsyncEvent LiveDenoiseFrameOpSharedSycl::process() { updateFilters(); // Using SYCL calls without SYCL, that's supported in C99 API only if (prefilter) { if (filterNormal) oidnExecuteSYCLFilterAsync(filterNormal.getHandle(), nullptr, 0, nullptr); if (filterAlbedo) oidnExecuteSYCLFilterAsync(filterAlbedo.getHandle(), nullptr, 0, nullptr); } if (denoiser->denoiseAlpha) oidnExecuteSYCLFilterAsync(filterAlpha.getHandle(), nullptr, 0, nullptr); else bufferOut.writeAsync(0, fbView.viewDims.long_product() * sizeof(vec4f), fbView.colorBufferInput); devicert::AsyncEvent event = denoiser->drtDevice.createAsyncEvent(); oidnExecuteSYCLFilterAsync( filter.getHandle(), nullptr, 0, (sycl::event *)event.getSyclEventPtr()); return event; } struct OSPRAY_MODULE_DENOISER_EXPORT LiveDenoiseFrameOpSharedCpu : public LiveDenoiseFrameOpShared { LiveDenoiseFrameOpSharedCpu(DenoiseFrameOp *denoiser, FrameBufferView &fbView) : LiveDenoiseFrameOpShared(denoiser, fbView) {} devicert::AsyncEvent process() override; }; devicert::AsyncEvent LiveDenoiseFrameOpSharedCpu::process() { updateFilters(); devicert::AsyncEvent event = denoiser->drtDevice.launchHostTask([this]() { if (prefilter) { if (filterNormal) filterNormal.execute(); if (filterAlbedo) filterAlbedo.execute(); } if (denoiser->denoiseAlpha) filterAlpha.execute(); else bufferOut.write(0, fbView.viewDims.long_product() * sizeof(vec4f), fbView.colorBufferInput); filter.execute(); }); return event; } struct OSPRAY_MODULE_DENOISER_EXPORT LiveDenoiseFrameOpCopy : public LiveDenoiseFrameOp { LiveDenoiseFrameOpCopy(DenoiseFrameOp *, FrameBufferView &); devicert::AsyncEvent process() override; private: void initFilterAlphaImages() override; void initFilterAuxImages() override; void updateFilterInput() override; void updateAuxImages(oidn::FilterRef &) override; oidn::BufferRef buffer; size_t byteFloatBufferSize; size_t byteNormalOffset; size_t byteAlbedoOffset; }; LiveDenoiseFrameOpCopy::LiveDenoiseFrameOpCopy( DenoiseFrameOp *denoiser, FrameBufferView &fbView) : LiveDenoiseFrameOp(denoiser, fbView) { byteFloatBufferSize = sizeof(float) * fbView.fbDims.product(); size_t sz = 4 * byteFloatBufferSize; if (fbView.normalBuffer) { byteNormalOffset = sz; sz += 3 * byteFloatBufferSize; } if (fbView.albedoBuffer) { byteAlbedoOffset = sz; sz += 3 * byteFloatBufferSize; } buffer = denoiser->oidnDevice.newBuffer(sz, oidn::Storage::Device); filter.setImage("output", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, 0, sizeof(float) * 4); updateFilters(); } devicert::AsyncEvent LiveDenoiseFrameOpCopy::process() { updateFilters(); // As this path is taken when rendering on CPU and denoising on GPU, // the asynchronous OIDN API is used to reduce the number of CPU - GPU // synchronization points which would take place on every command in case // of using synchronous OIDN API. devicert::AsyncEvent event = denoiser->drtDevice.launchHostTask([this]() { buffer.writeAsync(0, 4 * byteFloatBufferSize, fbView.colorBufferInput); if (fbView.normalBuffer) buffer.writeAsync( byteNormalOffset, 3 * byteFloatBufferSize, fbView.normalBuffer); if (fbView.albedoBuffer) buffer.writeAsync( byteAlbedoOffset, 3 * byteFloatBufferSize, fbView.albedoBuffer); if (prefilter) { if (filterNormal) filterNormal.executeAsync(); if (filterAlbedo) filterAlbedo.executeAsync(); } filter.executeAsync(); if (denoiser->denoiseAlpha) filterAlpha.executeAsync(); buffer.readAsync(0, 4 * byteFloatBufferSize, fbView.colorBufferOutput); denoiser->oidnDevice.sync(); }); return event; } void LiveDenoiseFrameOpCopy::initFilterAlphaImages() { filterAlpha.setImage("color", buffer, oidn::Format::Float, fbView.fbDims.x, fbView.fbDims.y, sizeof(float) * 3, sizeof(float) * 4); filterAlpha.setImage("output", buffer, oidn::Format::Float, fbView.fbDims.x, fbView.fbDims.y, sizeof(float) * 3, sizeof(float) * 4); } void LiveDenoiseFrameOpCopy::initFilterAuxImages() { if (fbView.normalBuffer) { filterNormal.setImage("normal", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteNormalOffset); filterNormal.setImage("output", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteNormalOffset); } if (fbView.albedoBuffer) { filterAlbedo.setImage("albedo", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteAlbedoOffset); filterAlbedo.setImage("output", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteAlbedoOffset); } } void LiveDenoiseFrameOpCopy::updateFilterInput() { filter.setImage("color", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, 0, sizeof(float) * 4); } void LiveDenoiseFrameOpCopy::updateAuxImages(oidn::FilterRef &filter) { if (fbView.normalBuffer) filter.setImage("normal", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteNormalOffset); if (fbView.albedoBuffer) filter.setImage("albedo", buffer, oidn::Format::Float3, fbView.fbDims.x, fbView.fbDims.y, byteAlbedoOffset); } DenoiseFrameOp::DenoiseFrameOp(devicert::Device &device) : drtDevice(device) { // Get appropriate SYCL command queue for post-processing from device sycl::queue *syclQueuePtr = (sycl::queue *)drtDevice.getSyclQueuePtr(); if (syclQueuePtr) { // Using SYCL call without SYCL, that's supported in C99 API only oidnDevice = oidnNewSYCLDevice(syclQueuePtr, 1); } else { oidnDevice = oidn::newDevice(); } checkError(oidnDevice); oidnDevice.setErrorFunction(checkError); if (device.isDebug()) oidnDevice.set("verbose", 2); oidnDevice.commit(); } void DenoiseFrameOp::commit() { quality = getParam("quality", OSP_DENOISER_QUALITY_MEDIUM); denoiseAlpha = getParam("denoiseAlpha", false); } std::unique_ptr DenoiseFrameOp::attach( FrameBufferView &fbView) { if (drtDevice.getSyclQueuePtr()) return rkcommon::make_unique(this, fbView); if (oidnDevice.get("systemMemorySupported")) return rkcommon::make_unique(this, fbView); return rkcommon::make_unique(this, fbView); } std::string DenoiseFrameOp::toString() const { return "ospray::DenoiseFrameOp"; } } // namespace ospray RenderKit-ospray-85af292/modules/denoiser/DenoiseFrameOp.h000066400000000000000000000012441464752671100235650ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // oidn #include "OpenImageDenoise/oidn.hpp" // ospray #include "fb/ImageOp.h" #include "ospray_module_denoiser_export.h" namespace ospray { struct OSPRAY_MODULE_DENOISER_EXPORT DenoiseFrameOp : public FrameOpInterface { DenoiseFrameOp(devicert::Device &device); void commit() override; std::unique_ptr attach( FrameBufferView &fbView) override; std::string toString() const override; devicert::Device &drtDevice; oidn::DeviceRef oidnDevice; int quality{OSP_DENOISER_QUALITY_MEDIUM}; bool denoiseAlpha{false}; }; } // namespace ospray RenderKit-ospray-85af292/modules/denoiser/ModuleInit.cpp000066400000000000000000000017261464752671100233360ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // We don't want an instance of ObjectFactory static table in this library // so we have to include it with import define so the table will be imported // from 'ospray' library #define OBJECTFACTORY_IMPORT #include "common/ObjectFactory.h" #include "DenoiseFrameOp.h" #include "common/OSPCommon.h" extern "C" OSPError OSPRAY_DLLEXPORT ospray_module_init_denoiser( int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/) { auto status = ospray::moduleVersionCheck(versionMajor, versionMinor); if (status == OSP_NO_ERROR) ospray::ImageOp::registerType("denoiser"); return status; } extern "C" int OSPRAY_DLLEXPORT ospray_module_denoiser_gpu_supported() { int gpu = 0; const int numDevices = oidnGetNumPhysicalDevices(); for (int i = 0; i < numDevices; ++i) gpu += oidnGetPhysicalDeviceInt(i, "type") > OIDN_DEVICE_TYPE_CPU; return gpu; } RenderKit-ospray-85af292/modules/mpi/000077500000000000000000000000001464752671100175305ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/CMakeLists.txt000066400000000000000000000017211464752671100222710ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_dependent_option( OSPRAY_MODULE_MPI "Build the MPI module (Requires the CPU module)" OFF OSPRAY_MODULE_CPU OFF ) if (NOT OSPRAY_MODULE_MPI) return() endif() find_package(MPI REQUIRED) if(NOT TARGET MPI::MPI_CXX) # pre CMake 3.9 add_library(MPI::MPI_CXX IMPORTED INTERFACE) set_property(TARGET MPI::MPI_CXX PROPERTY INTERFACE_COMPILE_OPTIONS ${MPI_CXX_COMPILE_FLAGS}) set_property(TARGET MPI::MPI_CXX PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MPI_CXX_INCLUDE_DIRS}") set_property(TARGET MPI::MPI_CXX PROPERTY INTERFACE_LINK_LIBRARIES ${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}) endif() find_package(Snappy REQUIRED) rkcommon_configure_build_type() add_subdirectory(common) add_subdirectory(ospray) if (OSPRAY_ENABLE_APPS_EXAMPLES OR OSPRAY_ENABLE_APPS_TUTORIALS) add_subdirectory(tutorials) endif() if (OSPRAY_ENABLE_APPS_TESTING) add_subdirectory(testing) endif() RenderKit-ospray-85af292/modules/mpi/common/000077500000000000000000000000001464752671100210205ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/common/CMakeLists.txt000066400000000000000000000013201464752671100235540ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 add_library(ospray_mpi_common SHARED ${OSPRAY_RESOURCE} Collectives.cpp MPIBcastFabric.cpp MPICommon.cpp ObjectHandle.cpp maml/maml.cpp maml/Context.cpp ) include(GenerateExportHeader) generate_export_header(ospray_mpi_common) target_link_libraries(ospray_mpi_common PRIVATE Snappy::snappy PUBLIC rkcommon::rkcommon ospray MPI::MPI_CXX ) target_include_directories(ospray_mpi_common PUBLIC $ $ $ ) ospray_install_library(ospray_mpi_common mpi) RenderKit-ospray-85af292/modules/mpi/common/Collectives.cpp000066400000000000000000000214421464752671100240030ustar00rootroot00000000000000// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Collectives.h" #include #include #include #include #include "maml/maml.h" namespace mpicommon { using namespace rkcommon; OSPRAY_MPI_COMMON_EXPORT std::future bcast( void *buf, size_t count, MPI_Datatype datatype, int root, MPI_Comm comm) { int typeSize = 0; MPI_Type_size(datatype, &typeSize); auto view = std::make_shared>( static_cast(buf), count * typeSize); auto col = std::make_shared(view, count, datatype, root, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future bcast( std::shared_ptr> &buffer, size_t count, MPI_Datatype datatype, int root, MPI_Comm comm) { auto col = std::make_shared(buffer, count, datatype, root, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future barrier(MPI_Comm comm) { auto col = std::make_shared(comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future gather(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, int recvCount, MPI_Datatype recvType, int root, MPI_Comm comm) { auto col = std::make_shared(sendBuffer, sendCount, sendType, recvBuffer, recvCount, recvType, root, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future gatherv(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, const std::vector &recvCounts, const std::vector &recvOffsets, MPI_Datatype recvType, int root, MPI_Comm comm) { auto col = std::make_shared(sendBuffer, sendCount, sendType, recvBuffer, recvCounts, recvOffsets, recvType, root, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future send(void *buffer, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) { auto col = std::make_shared(buffer, count, datatype, dest, tag, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future recv(void *buffer, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm) { auto col = std::make_shared(buffer, count, datatype, source, tag, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future reduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, int root, MPI_Comm comm) { auto col = std::make_shared( sendBuffer, recvBuffer, count, datatype, operation, root, comm); maml::queueCollective(col); return col->future(); } OSPRAY_MPI_COMMON_EXPORT std::future allreduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, MPI_Comm comm) { auto col = std::make_shared( sendBuffer, recvBuffer, count, datatype, operation, comm); maml::queueCollective(col); return col->future(); } Collective::Collective(MPI_Comm comm) : comm(comm), request(MPI_REQUEST_NULL) {} bool Collective::finished() { int done = 0; MPI_CALL(Test(&request, &done, MPI_STATUS_IGNORE)); if (done) { onFinish(); } return done; } Barrier::Barrier(MPI_Comm comm) : Collective(comm) {} std::future Barrier::future() { return result.get_future(); } void Barrier::start() { MPI_CALL(Ibarrier(comm, &request)); } void Barrier::onFinish() { result.set_value(); } Bcast::Bcast(std::shared_ptr> buffer, size_t count, MPI_Datatype datatype, int root, MPI_Comm comm) : Collective(comm), buffer(buffer), count(count), datatype(datatype), root(root) { MPI_Type_size(datatype, &typeSize); } std::future Bcast::future() { return result.get_future(); } void Bcast::start() { // 1GB as the max bcast size const static size_t MAX_BCAST_SIZE = 1e9; size_t remaining = count; // TODO: This is Rust's slice::chunks iterator uint8_t *iter = buffer->begin(); do { MPI_Request req; const size_t toSend = std::min(MAX_BCAST_SIZE, remaining); MPI_CALL(Ibcast(iter, toSend, datatype, root, comm, &req)); requests.push_back(req); iter += toSend * typeSize; remaining -= toSend; } while (iter != buffer->end()); } bool Bcast::finished() { const size_t ndone = std::accumulate( requests.begin(), requests.end(), 0, [](const int &n, MPI_Request &r) { int d = 0; MPI_CALL(Test(&r, &d, MPI_STATUS_IGNORE)); if (d) { return n + 1; } return n; }); if (ndone == requests.size()) { onFinish(); } return ndone == requests.size(); } void Bcast::onFinish() { result.set_value(static_cast(buffer->data())); } Gather::Gather(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, int recvCount, MPI_Datatype recvType, int root, MPI_Comm comm) : Collective(comm), sendBuffer(sendBuffer), sendCount(sendCount), sendType(sendType), recvBuffer(recvBuffer), recvCount(recvCount), recvType(recvType), root(root) {} std::future Gather::future() { return result.get_future(); } void Gather::start() { MPI_CALL(Igather(sendBuffer, sendCount, sendType, recvBuffer, recvCount, recvType, root, comm, &request)); } void Gather::onFinish() { result.set_value(recvBuffer); } Gatherv::Gatherv(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, const std::vector &recvCounts, const std::vector &recvOffsets, MPI_Datatype recvType, int root, MPI_Comm comm) : Collective(comm), sendBuffer(sendBuffer), sendCount(sendCount), sendType(sendType), recvBuffer(recvBuffer), recvCounts(recvCounts), recvOffsets(recvOffsets), recvType(recvType), root(root) {} std::future Gatherv::future() { return result.get_future(); } void Gatherv::start() { MPI_CALL(Igatherv(sendBuffer, sendCount, sendType, recvBuffer, recvCounts.data(), recvOffsets.data(), recvType, root, comm, &request)); } void Gatherv::onFinish() { result.set_value(recvBuffer); } Reduce::Reduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, int root, MPI_Comm comm) : Collective(comm), sendBuffer(sendBuffer), recvBuffer(recvBuffer), count(count), datatype(datatype), operation(operation), root(root) {} std::future Reduce::future() { return result.get_future(); } void Reduce::start() { MPI_CALL(Ireduce(sendBuffer, recvBuffer, count, datatype, operation, root, comm, &request)); } void Reduce::onFinish() { result.set_value(recvBuffer); } AllReduce::AllReduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, MPI_Comm comm) : Collective(comm), sendBuffer(sendBuffer), recvBuffer(recvBuffer), count(count), datatype(datatype), operation(operation) {} std::future AllReduce::future() { return result.get_future(); } void AllReduce::start() { MPI_CALL(Iallreduce( sendBuffer, recvBuffer, count, datatype, operation, comm, &request)); } void AllReduce::onFinish() { result.set_value(recvBuffer); } Send::Send(void *buffer, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) : Collective(comm), buffer(buffer), count(count), datatype(datatype), dest(dest), tag(tag) {} std::future Send::future() { return result.get_future(); } void Send::start() { MPI_CALL(Isend(buffer, count, datatype, dest, tag, comm, &request)); } void Send::onFinish() { result.set_value(buffer); } Recv::Recv(void *buffer, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm) : Collective(comm), buffer(buffer), count(count), datatype(datatype), source(source), tag(tag) {} std::future Recv::future() { return result.get_future(); } void Recv::start() { MPI_CALL(Irecv(buffer, count, datatype, source, tag, comm, &request)); } void Recv::onFinish() { result.set_value(buffer); } } // namespace mpicommon RenderKit-ospray-85af292/modules/mpi/common/Collectives.h000066400000000000000000000247151464752671100234560ustar00rootroot00000000000000// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include "MPICommon.h" #include "ospray_mpi_common_export.h" #include "rkcommon/utility/ArrayView.h" namespace mpicommon { // Convenient wrappers over the collectives // /* Start an asynchronous bcast and return the future to wait on * for completion. The caller owns the passed buffer, and must keep it * valid until the future completes. */ OSPRAY_MPI_COMMON_EXPORT std::future bcast( void *buffer, size_t count, MPI_Datatype datatype, int root, MPI_Comm comm); OSPRAY_MPI_COMMON_EXPORT std::future bcast( std::shared_ptr> &buffer, size_t count, MPI_Datatype datatype, int root, MPI_Comm comm); /* Start an asynchronous barrier and return the future to wait on for * completion of the barrier */ OSPRAY_MPI_COMMON_EXPORT std::future barrier(MPI_Comm comm); /* Start an asynchronous gather and return the future to wait on for * completion of the gather. The called owns both the send and recv buffers, * and must keep them valid until the future completes. The pointer returned * in the future is to the receive buffer. */ OSPRAY_MPI_COMMON_EXPORT std::future gather(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, int recvCount, MPI_Datatype recvType, int root, MPI_Comm comm); /* Start an asynchronous gatherv and return the future to wait on for * completion of the gather. The called owns both the send and recv buffers, * and must keep them valid until the future completes. The pointer returned * in the future is to the receive buffer. The recvCounts and offsets * vectors are copied into the struct. */ OSPRAY_MPI_COMMON_EXPORT std::future gatherv(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, const std::vector &recvCounts, const std::vector &recvOffsets, MPI_Datatype recvType, int root, MPI_Comm comm); /* Start an asynchronously run reduce. The send/recv buffers are owned * by the caller and must be kept valid until the future is set, indicating * completion of the reduction. */ OSPRAY_MPI_COMMON_EXPORT std::future reduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, int root, MPI_Comm comm); /* Start an asynchronously run allreduce. The send/recv buffers are owned * by the caller and must be kept valid until the future is set, indicating * completion of the reduction. */ OSPRAY_MPI_COMMON_EXPORT std::future allreduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, MPI_Comm comm); /* Start an asynchronously run send. The buffer is owned by * the caller and must be kept valid until the future is set, indicating * completion of the send. * TODO: Chunking */ OSPRAY_MPI_COMMON_EXPORT std::future send(void *buffer, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm comm); /* Start an asynchronously run recv. The buffer is owned by * the caller and must be kept valid until the future is set, indicating * completion of the recv. * TODO: Chunking */ OSPRAY_MPI_COMMON_EXPORT std::future recv(void *buffer, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm); // An asynchronously executed collective operation which can be run // on the MPI messaging layer class OSPRAY_MPI_COMMON_EXPORT Collective { public: Collective(MPI_Comm comm); virtual ~Collective() = default; // Start the collective virtual void start() = 0; // Check if the collective is done and notify the child classes onFinish virtual bool finished(); protected: virtual void onFinish() = 0; MPI_Comm comm; MPI_Request request; }; class OSPRAY_MPI_COMMON_EXPORT Barrier : public Collective { public: Barrier(MPI_Comm comm); // Get the future to wait on completion of this barrier std::future future(); void start() override; protected: void onFinish() override; private: std::promise result; }; class OSPRAY_MPI_COMMON_EXPORT Bcast : public Collective { public: /* Construct an asynchronously run broadcast. The buffer is owned by * the caller and must be kept valid until the future is set, indicating * completion of the broadcast. */ Bcast(std::shared_ptr> buffer, size_t count, MPI_Datatype datatype, int root, MPI_Comm comm); // Get the future which will receive the result of this bcast std::future future(); void start() override; bool finished() override; protected: void onFinish() override; private: std::shared_ptr> buffer; size_t count; int typeSize; MPI_Datatype datatype; int root; std::promise result; std::vector requests; }; class OSPRAY_MPI_COMMON_EXPORT Gather : public Collective { public: /* Construct an asynchronously run gather. The send/recv buffers are owned * by the caller and must be kept valid until the future is set, indicating * completion of the gather. */ Gather(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, int recvCount, MPI_Datatype recvType, int root, MPI_Comm comm); /* Get the future which will receive the result of this gather. * The returned pointer will point to the recvBuffer containing the * received data. */ std::future future(); void start() override; protected: void onFinish() override; private: const void *sendBuffer; int sendCount; MPI_Datatype sendType; void *recvBuffer; int recvCount; MPI_Datatype recvType; int root; std::promise result; }; class OSPRAY_MPI_COMMON_EXPORT Gatherv : public Collective { public: /* Construct an asynchronously run gatherv. The send/recv buffers are owned * by the caller and must be kept valid until the future is set, indicating * completion of the gatherv. The recvOffsets and counts vectors are copied * into the struct. */ Gatherv(const void *sendBuffer, int sendCount, MPI_Datatype sendType, void *recvBuffer, const std::vector &recvCounts, const std::vector &recvOffsets, MPI_Datatype recvType, int root, MPI_Comm comm); /* Get the future which will receive the result of this gatherv. * The returned pointer will point to the recvBuffer containing the * received data. */ std::future future(); void start() override; protected: void onFinish() override; private: const void *sendBuffer; int sendCount; MPI_Datatype sendType; void *recvBuffer; std::vector recvCounts; std::vector recvOffsets; MPI_Datatype recvType; int root; std::promise result; }; class OSPRAY_MPI_COMMON_EXPORT Reduce : public Collective { public: /* Construct an asynchronously run reduce. The send/recv buffers are owned * by the caller and must be kept valid until the future is set, indicating * completion of the reduction. */ Reduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, int root, MPI_Comm comm); /* Get the future which will receive the result of this reduction. * The returned pointer will point to the recvBuffer containing the * result of the reduction. */ std::future future(); void start() override; protected: void onFinish() override; private: const void *sendBuffer; void *recvBuffer; int count; MPI_Datatype datatype; MPI_Op operation; int root; std::promise result; }; class OSPRAY_MPI_COMMON_EXPORT AllReduce : public Collective { public: /* Construct an asynchronously run allreduce. The send/recv buffers are owned * by the caller and must be kept valid until the future is set, indicating * completion of the reduction. */ AllReduce(const void *sendBuffer, void *recvBuffer, int count, MPI_Datatype datatype, MPI_Op operation, MPI_Comm comm); /* Get the future which will receive the result of this reduction. * The returned pointer will point to the recvBuffer containing the * result of the reduction. */ std::future future(); void start() override; protected: void onFinish() override; private: const void *sendBuffer; void *recvBuffer; int count; MPI_Datatype datatype; MPI_Op operation; std::promise result; }; /* Send/recv are not really collectives, but are separate from the typical * fire and forget style of messaging that the mpicommon::Message uses. * With these we actually want the ability to wait for a specific send to * finish, and a specific recv from a process to be completed. With the * fire and forget messaging layer we don't care about this and just queue * stuff up and receive whatever is coming to us. */ class OSPRAY_MPI_COMMON_EXPORT Send : public Collective { public: /* Construct an asynchronously run send. The buffer is owned by * the caller and must be kept valid until the future is set, indicating * completion of the send. */ Send(void *buffer, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm); /* Get the future which will return when this send is done, returns the * pointer to the sent buffer */ std::future future(); void start() override; protected: void onFinish() override; private: void *buffer; int count; MPI_Datatype datatype; int dest; int tag; std::promise result; }; class OSPRAY_MPI_COMMON_EXPORT Recv : public Collective { public: /* Construct an asynchronously run recv. The buffer is owned by * the caller and must be kept valid until the future is set, indicating * completion of the recv. */ Recv(void *buffer, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm); /* Get the future which will return when this recv is done, returns the * pointer to the buffer containing the recv'd data */ std::future future(); void start() override; protected: void onFinish() override; private: void *buffer; int count; MPI_Datatype datatype; int source; int tag; std::promise result; }; } // namespace mpicommon RenderKit-ospray-85af292/modules/mpi/common/MPIBcastFabric.cpp000066400000000000000000000046411464752671100242420ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include #include "Collectives.h" #include "MPIBcastFabric.h" #include "maml/maml.h" namespace mpicommon { MPIFabric::MPIFabric(const Group &parentGroup, int bcastRoot) : group(parentGroup.dup()), bcastRoot(bcastRoot) { if (!group.valid()) { throw std::runtime_error( "#osp:mpi: trying to set up an MPI fabric " "with an invalid MPI communicator"); } int isInter = 0; MPI_CALL(Comm_test_inter(group.comm, &isInter)); if (isInter && bcastRoot != MPI_ROOT) { throw std::runtime_error( "Invalid MPIFabric group config " "on an MPI intercomm group"); } } MPIFabric::~MPIFabric() { flushBcastSends(); MPI_Comm_free(&group.comm); } void MPIFabric::sendBcast(std::shared_ptr> buf) { auto future = mpicommon::bcast( buf->data(), buf->size(), MPI_BYTE, bcastRoot, group.comm); pendingSends.emplace_back( std::make_shared(std::move(future), buf)); checkPendingSends(); } void MPIFabric::flushBcastSends() { while (!pendingSends.empty()) { checkPendingSends(); } } void MPIFabric::recvBcast(utility::AbstractArray &buf) { mpicommon::bcast(buf.data(), buf.size(), MPI_BYTE, bcastRoot, group.comm) .wait(); checkPendingSends(); } void MPIFabric::send( std::shared_ptr> buf, int rank) { auto future = mpicommon::send(buf->data(), buf->size(), MPI_BYTE, rank, 0, group.comm); pendingSends.emplace_back( std::make_shared(std::move(future), buf)); checkPendingSends(); } void MPIFabric::recv(utility::AbstractArray &buf, int rank) { mpicommon::recv(buf.data(), buf.size(), MPI_BYTE, rank, 0, group.comm).wait(); checkPendingSends(); } void MPIFabric::checkPendingSends() { if (!pendingSends.empty()) { auto done = std::partition(pendingSends.begin(), pendingSends.end(), [](const std::shared_ptr &ps) { return ps->future.wait_for(std::chrono::milliseconds(0)) != std::future_status::ready; }); pendingSends.erase(done, pendingSends.end()); } } MPIFabric::PendingSend::PendingSend(std::future future, std::shared_ptr> &buf) : future(std::move(future)), buf(buf) {} } // namespace mpicommon RenderKit-ospray-85af292/modules/mpi/common/MPIBcastFabric.h000066400000000000000000000032271464752671100237060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "rkcommon/networking/DataStreaming.h" #include "rkcommon/networking/Fabric.h" #include "rkcommon/utility/AbstractArray.h" #include "MPICommon.h" #include "ospray_mpi_common_export.h" namespace mpicommon { /*! a specific fabric based on MPI. Note that in the case of an * MPIFabric using an intercommunicator the send rank must * be MPI_ROOT and the recv rank must be 0. The group passed will * be duplicated to avoid MPI collective matching issues with other * fabrics and collectives. */ class OSPRAY_MPI_COMMON_EXPORT MPIFabric : public networking::Fabric { public: MPIFabric(const Group &parentGroup, int bcastRoot); virtual ~MPIFabric() override; void sendBcast(std::shared_ptr> buf) override; void flushBcastSends() override; void recvBcast(utility::AbstractArray &buf) override; void send( std::shared_ptr> buf, int rank) override; void recv(utility::AbstractArray &buf, int rank) override; private: void checkPendingSends(); Group group; int bcastRoot; struct PendingSend { std::future future; std::shared_ptr> buf = nullptr; PendingSend() = default; PendingSend(std::future future, std::shared_ptr> &buf); PendingSend(const PendingSend &) = delete; PendingSend &operator=(const PendingSend &) = delete; }; std::vector> pendingSends; }; } // namespace mpicommon RenderKit-ospray-85af292/modules/mpi/common/MPICommon.cpp000066400000000000000000000066711464752671100233340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "MPICommon.h" namespace mpicommon { static std::mutex mpiMutex; bool mpiIsThreaded = false; Group world; Group worker; // Group definitions //////////////////////////////////////////////////////// /*! constructor. sets the 'comm', 'rank', and 'size' fields */ Group::Group(MPI_Comm initComm) { setTo(initComm); } /*! constructor. sets the 'comm', 'rank', and 'size' fields */ Group::Group(const Group &other) : containsMe(other.containsMe), comm(other.comm), rank(other.rank), size(other.size) {} void Group::makeIntraComm() { MPI_CALL(Comm_rank(comm, &rank)); MPI_CALL(Comm_size(comm, &size)); containsMe = true; } void Group::makeIntraComm(MPI_Comm _comm) { this->comm = _comm; makeIntraComm(); } void Group::makeInterComm() { containsMe = false; rank = MPI_ROOT; MPI_CALL(Comm_remote_size(comm, &size)); } void Group::makeInterComm(MPI_Comm _comm) { this->comm = _comm; makeInterComm(); } /*! set to given intercomm, and properly set size, root, etc */ void Group::setTo(MPI_Comm _comm) { if (this->comm == _comm) return; this->comm = _comm; if (comm == MPI_COMM_NULL) { rank = size = -1; } else { int isInter; MPI_CALL(Comm_test_inter(comm, &isInter)); if (isInter) makeInterComm(comm); else makeIntraComm(comm); } } /*! do an MPI_Comm_dup, and return duplicated communicator */ Group Group::dup() const { MPI_Comm duped; MPI_CALL(Comm_dup(comm, &duped)); return Group(duped); } // Message definitions ////////////////////////////////////////////////////// /*! create a new message with given amount of bytes in storage */ Message::Message(size_t size) : size(size) { data = (rkcommon::byte_t *)malloc(size); } /*! create a new message with given amount of storage, and copy memory from the given address to it */ Message::Message(const void *copyMem, size_t size) : Message(size) { if (copyMem == nullptr) OSPRAY_THROW("#mpicommon: cannot create a message from a null pointer!"); memcpy(data, copyMem, size); } /*! create a new message (addressed to given comm:rank) with given amount of storage, and copy memory from the given address to it */ Message::Message(MPI_Comm comm, int rank, const void *copyMem, size_t size) : Message(copyMem, size) { this->comm = comm; this->rank = rank; } /*! destruct message and free allocated memory */ Message::~Message() { free(data); } bool Message::isValid() const { return comm != MPI_COMM_NULL && rank >= 0; } bool init(int *ac, const char **av, bool useCommWorld) { int initialized = false; MPI_CALL(Initialized(&initialized)); int provided = 0; if (!initialized) { /* MPI not initialized by the app - it's up to us */ MPI_CALL(Init_thread( ac, const_cast(&av), MPI_THREAD_MULTIPLE, &provided)); } else { /* MPI was already initialized by the app that called us! */ MPI_Query_thread(&provided); } if (provided != MPI_THREAD_MULTIPLE && provided != MPI_THREAD_SERIALIZED) { throw std::runtime_error( "MPI initialization error: The MPI runtime must" " support either MPI_THREAD_MULTIPLE or" " MPI_THREAD_SERIALIZED."); } mpiIsThreaded = provided == MPI_THREAD_MULTIPLE; if (useCommWorld) { world.setTo(MPI_COMM_WORLD); } return !initialized; } bool isManagedObject(OSPDataType type) { return type & OSP_OBJECT; } } // namespace mpicommon RenderKit-ospray-85af292/modules/mpi/common/MPICommon.h000066400000000000000000000126321464752671100227730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #define OMPI_SKIP_MPICXX 1 #include #include "ospray/OSPEnums.h" #include "rkcommon/common.h" #include "ospray_mpi_common_export.h" // IMPI on Windows defines MPI_CALL already, erroneously #ifdef MPI_CALL #undef MPI_CALL #endif /*! helper macro that checks the return value of all MPI_xxx(...) calls via MPI_CALL(xxx(...)). */ #define MPI_CALL(a) \ { \ int rc = MPI_##a; \ if (rc != MPI_SUCCESS) \ throw std::runtime_error("MPI call returned error"); \ } #define OSPRAY_THROW(a) \ throw std::runtime_error( \ "in " + std::string(__PRETTY_FUNCTION__) + " : " + std::string(a)) #define OSPRAY_WORLD_GROUP_TAG 290374 namespace mpicommon { using namespace rkcommon; /*! global variable that turns on logging of MPI communication (for debugging) _may_ eventually turn this into a real logLevel, but for now this is cleaner here than in the MPI device */ OSPRAY_MPI_COMMON_EXPORT extern bool mpiIsThreaded; //! abstraction for an MPI group. /*! it's the responsibility of the respective mpi setup routines to fill in the proper values */ struct OSPRAY_MPI_COMMON_EXPORT Group { /*! constructor. sets the 'comm', 'rank', and 'size' fields */ Group(MPI_Comm initComm = MPI_COMM_NULL); Group(const Group &other); inline bool valid() const { return comm != MPI_COMM_NULL; } void makeIntraComm(); void makeIntraComm(MPI_Comm); void makeInterComm(); void makeInterComm(MPI_Comm); /*! set to given intercomm, and properly set size, root, etc */ void setTo(MPI_Comm comm); /*! do an MPI_Comm_dup, and return duplicated communicator */ Group dup() const; // whether the current process/thread is a member of this group bool containsMe{false}; // communictor for this group. intercommunicator if i'm a member of this // group; else it's an intracommunicator MPI_Comm comm{MPI_COMM_NULL}; /*! my rank in this group if i'm a member; else set to MPI_ROOT */ int rank{-1}; // size of this group if i'm a member, else size of remote group this // intracommunicator refers to int size{-1}; }; /*! object that handles a message. a message primarily consists of a pointer to data; the message itself "owns" this pointer, and will delete it once the message itself dies. the message itself is reference counted using the std::shared_ptr functionality. */ struct OSPRAY_MPI_COMMON_EXPORT Message { Message() = default; /*! create a new message with given amount of bytes in storage */ Message(size_t size); /*! create a new message with given amount of storage, and copy memory from the given address to it */ Message(const void *copyMem, size_t size); /*! create a new message (addressed to given comm:rank) with given amount of storage, and copy memory from the given address to it */ Message(MPI_Comm comm, int rank, const void *copyMem, size_t size); Message(const Message &) = delete; Message &operator=(const Message &) = delete; /*! destruct message and free allocated memory */ virtual ~Message(); bool isValid() const; /*! @{ sender/receiver of this message */ MPI_Comm comm{MPI_COMM_NULL}; int rank{-1}; int tag{0}; /*! @} */ /*! @{ actual payload of this message */ rkcommon::byte_t *data{nullptr}; size_t size{0}; /*! @} */ // TODO WILL: Profiling info, when this message started sending // or receiving std::chrono::high_resolution_clock::time_point started; }; /*! a message whose payload is owned by the user, and which we do NOT delete upon termination */ struct OSPRAY_MPI_COMMON_EXPORT UserMemMessage : public Message { UserMemMessage(void *nonCopyMem, size_t size) : Message() { data = (rkcommon::byte_t *)nonCopyMem; this->size = size; } /* set data to null to keep the parent from deleting it */ virtual ~UserMemMessage() override { data = nullptr; } }; //! MPI_COMM_WORLD OSPRAY_MPI_COMMON_EXPORT extern Group world; /* The communicator used for the OSPRay workers, may be equivalent to world * depending on the launch configuration */ OSPRAY_MPI_COMMON_EXPORT extern Group worker; // Initialize OSPRay's MPI groups, returns false if MPI // was already initialized. useCommWorld indicates if MPI_COMM_WORLD // should be set as the world group used for communication. If false, // it is up to the caller to configure the world group correctly. OSPRAY_MPI_COMMON_EXPORT bool init(int *ac, const char **av, bool useCommWorld); /* MPICommon has its own implementation so the offload worker can check for * managed objects without having to link ospray_module_cpu */ OSPRAY_MPI_COMMON_EXPORT bool isManagedObject(OSPDataType type); OSPRAY_MPI_COMMON_EXPORT inline int workerRank() { return worker.rank; } OSPRAY_MPI_COMMON_EXPORT inline int workerSize() { return worker.size; } OSPRAY_MPI_COMMON_EXPORT inline int masterRank() { return 0; } OSPRAY_MPI_COMMON_EXPORT inline bool IamTheMaster() { return workerRank() == masterRank(); } } // namespace mpicommon RenderKit-ospray-85af292/modules/mpi/common/ObjectHandle.cpp000066400000000000000000000052301464752671100240460ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ObjectHandle.h" #include #include namespace ospray { static std::map objectByHandle; static std::stack freedHandles; //! next unassigned ID on this node /*! we start numbering with 1 to make sure that "0:0" is an invalid handle (so we can typecast between (64-bit) handles and (64-bit)OSPWhatEver pointers */ static int32 nextFreeLocalID = 1; void ObjectHandle::free() { freedHandles.push((int64) * this); } ObjectHandle::ObjectHandle() : i64(NULL_HANDLE) {} ObjectHandle::ObjectHandle(int64 i) : i64(i) {} ObjectHandle::ObjectHandle(const ObjectHandle &other) : i64(other.i64) {} ObjectHandle &ObjectHandle::operator=(const ObjectHandle &other) { if (this != &other) i64 = other.i64; return *this; } /*! define the given handle to refer to given object */ void ObjectHandle::assign(const ObjectHandle &handle, memory::RefCount *object) { objectByHandle[handle] = object; } void ObjectHandle::assign(memory::RefCount *object) const { objectByHandle[i64] = object; } void ObjectHandle::freeObject() const { auto it = objectByHandle.find(i64); if (it != objectByHandle.end()) { // let internal device handle this -> it->second->refDec(); objectByHandle.erase(it); } } int32 ObjectHandle::ownerRank() const { return i32.owner; } int32 ObjectHandle::objID() const { return i32.ID; } ospray::ObjectHandle::operator int64() const { return i64; } bool ObjectHandle::defined() const { return objectByHandle.find(i64) != objectByHandle.end(); } ObjectHandle ObjectHandle::allocateLocalHandle() { ObjectHandle handle; if (freedHandles.empty()) { handle.i32.ID = nextFreeLocalID++; handle.i32.owner = 0; } else { handle.i64 = freedHandles.top(); freedHandles.pop(); } return handle; } memory::RefCount *ObjectHandle::lookup() const { if (i64 == 0) return nullptr; auto it = objectByHandle.find(i64); if (it == objectByHandle.end()) { #ifndef NDEBUG // iw - made this into a warning only; the original code had // this throw an actual exceptoin, but that may be overkill std::cout << "#osp: WARNING: ospray is trying to look up object handle " + std::to_string(i64) + " that isn't defined!" << std::endl; #endif return nullptr; } return it->second; } ObjectHandle ObjectHandle::lookup(memory::RefCount *object) { for (auto it = objectByHandle.begin(); it != objectByHandle.end(); it++) { if (it->second == object) return (ObjectHandle(it->first)); } return (nullHandle); } const ObjectHandle nullHandle(0); } // namespace ospray RenderKit-ospray-85af292/modules/mpi/common/ObjectHandle.h000066400000000000000000000047741464752671100235270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MPICommon.h" #include "common/OSPCommon.h" #include "ospray_mpi_common_export.h" #include "rkcommon/memory/RefCount.h" namespace ospray { #define NULL_HANDLE (ObjectHandle(0)) //! (local) handle to a (remote) managed object /*! abstraction for a remotely-held 'managed object'. the handle refers to both 'owner' (the machine that has it) as well as to a local ID (by which that owner can look it up). Note that other ranks may also have copies of that object. note that the 'null handle' is '0', not -1. This allows an app to test the handled resturend from ospNewXXX calls for null just as if they were pointers (and thus, 'null' objects are consistent between local and mpi rendering) */ union OSPRAY_MPI_COMMON_EXPORT ObjectHandle { ObjectHandle(); ObjectHandle(int64 i); ObjectHandle(const ObjectHandle &other); ObjectHandle &operator=(const ObjectHandle &other); void free(); /*! look up an object by handle, and return it. must be a defined handle */ memory::RefCount *lookup() const; /* Allocate a local ObjectHandle */ static ObjectHandle allocateLocalHandle(); /*! Return the handle associated with the given object. */ static ObjectHandle lookup(memory::RefCount *object); /*! check whether the handle is defined *on this rank* */ bool defined() const; /*! define the given handle to refer to given object */ static void assign(const ObjectHandle &handle, memory::RefCount *object); /*! define the given handle to refer to given object */ void assign(memory::RefCount *object) const; void freeObject() const; int32 ownerRank() const; int32 objID() const; /*! cast to int64 to allow fast operations with this type */ operator int64() const; // Data members // struct { int32 ID; int32 owner; } i32; int64 i64; }; OSPRAY_MPI_COMMON_EXPORT extern const ObjectHandle nullHandle; // Inlined operator definitions ///////////////////////////////////////////// OSPRAY_MPI_COMMON_EXPORT inline bool operator==( const ObjectHandle &a, const ObjectHandle &b) { return a.i64 == b.i64; } OSPRAY_MPI_COMMON_EXPORT inline bool operator!=( const ObjectHandle &a, const ObjectHandle &b) { return !(a == b); } template inline OSPRAY_TYPE *lookupObject(OSPObject obj) { auto &handle = reinterpret_cast(obj); return handle.defined() ? (OSPRAY_TYPE *)handle.lookup() : (OSPRAY_TYPE *)obj; } } // namespace ospray RenderKit-ospray-85af292/modules/mpi/common/maml/000077500000000000000000000000001464752671100217465ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/common/maml/Context.cpp000066400000000000000000000213161464752671100241010ustar00rootroot00000000000000// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Context.h" #include #include #include #include #include "common/OSPCommon.h" #include "rkcommon/memory/malloc.h" #include "rkcommon/tasking/async.h" #include "rkcommon/tasking/tasking_system_init.h" #include "rkcommon/utility/getEnvVar.h" using rkcommon::byte_t; using rkcommon::make_unique; using rkcommon::tasking::AsyncLoop; using rkcommon::tasking::numTaskingThreads; using rkcommon::utility::getEnvVar; using namespace std::chrono; namespace maml { /*! the singleton object that handles all the communication */ std::unique_ptr Context::singleton; Context::Context(bool enableCompression) : compressMessages(enableCompression) {} Context::~Context() { try { stop(); } catch (const std::exception &e) { ospray::handleError(OSP_UNKNOWN_ERROR, e.what()); } } /*! register a new incoing-message handler. if any message comes in on the given communicator we'll call this handler */ void Context::registerHandlerFor(MPI_Comm comm, MessageHandler *handler) { if (handlers.find(comm) != handlers.end()) { std::cerr << CODE_LOCATION << ": Warning: handler for this MPI_Comm already installed" << std::endl; } handlers[comm] = handler; /*! todo: to avoid race conditions we MAY want to check if there's any messages we've already received that would match this handler */ } /*! put the given message in the outbox. note that this can be done even if the actual sending mechanism is currently stopped */ void Context::send(std::shared_ptr msg) { // The message uses malloc/free, so use that instead of new/delete if (compressMessages) { byte_t *compressed = (byte_t *)malloc(snappy::MaxCompressedLength(msg->size)); size_t compressedSize = 0; snappy::RawCompress(reinterpret_cast(msg->data), msg->size, reinterpret_cast(compressed), &compressedSize); free(msg->data); msg->data = compressed; msg->size = compressedSize; } outbox.push_back(std::move(msg)); } void Context::queueCollective(std::shared_ptr col) { // TODO WILL: auto-compress collectives? collectiveOutbox.push_back(std::move(col)); } void Context::processInboxMessages() { auto incomingMessages = inbox.consume(); for (auto &msg : incomingMessages) { auto *handler = handlers[msg->comm]; if (compressMessages) { // Decompress the message before handing it off size_t uncompressedSize = 0; snappy::GetUncompressedLength(reinterpret_cast(msg->data), msg->size, &uncompressedSize); byte_t *uncompressed = (byte_t *)malloc(uncompressedSize); snappy::RawUncompress(reinterpret_cast(msg->data), msg->size, reinterpret_cast(uncompressed)); free(msg->data); msg->data = uncompressed; msg->size = uncompressedSize; } handler->incoming(msg); } } void Context::sendMessagesFromOutbox() { auto outgoingMessages = outbox.consume(); auto outgoingCollectives = collectiveOutbox.consume(); for (auto &msg : outgoingMessages) { MPI_Request request; int rank = 0; MPI_CALL(Comm_rank(msg->comm, &rank)); // Don't send to ourself, just forward to the inbox directly if (rank == msg->rank) { inbox.push_back(std::move(msg)); } else { MPI_CALL(Isend(msg->data, msg->size, MPI_BYTE, msg->rank, msg->tag, msg->comm, &request)); msg->started = high_resolution_clock::now(); pendingSends.push_back(request); sendCache.push_back(std::move(msg)); } } for (auto &col : outgoingCollectives) { col->start(); pendingCollectives.push_back(col); } } void Context::pollForAndRecieveMessages() { for (auto &it : handlers) { MPI_Comm comm = it.first; /* probe if there's something incoming on this handler's comm */ int hasIncoming = 0; MPI_Status status; MPI_CALL(Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &hasIncoming, &status)); if (hasIncoming) { int size; MPI_CALL(Get_count(&status, MPI_BYTE, &size)); auto msg = std::make_shared(size); msg->rank = status.MPI_SOURCE; msg->tag = status.MPI_TAG; msg->comm = comm; MPI_Request request; MPI_CALL(Irecv( msg->data, size, MPI_BYTE, msg->rank, msg->tag, msg->comm, &request)); msg->started = high_resolution_clock::now(); pendingRecvs.push_back(request); recvCache.push_back(std::move(msg)); } } } void Context::waitOnSomeRequests() { if (!pendingSends.empty() || !pendingRecvs.empty()) { const size_t totalMessages = pendingSends.size() + pendingRecvs.size(); int *done = STACK_BUFFER(int, totalMessages); MPI_Request *mergedRequests = STACK_BUFFER(MPI_Request, totalMessages); for (size_t i = 0; i < totalMessages; ++i) { if (i < pendingSends.size()) { mergedRequests[i] = pendingSends[i]; } else { mergedRequests[i] = pendingRecvs[i - pendingSends.size()]; } } int numDone = 0; MPI_CALL(Testsome( totalMessages, mergedRequests, &numDone, done, MPI_STATUSES_IGNORE)); for (int i = 0; i < numDone; ++i) { size_t msgId = done[i]; if (msgId < pendingSends.size()) { pendingSends[msgId] = MPI_REQUEST_NULL; sendCache[msgId] = nullptr; } else { msgId -= pendingSends.size(); inbox.push_back(std::move(recvCache[msgId])); pendingRecvs[msgId] = MPI_REQUEST_NULL; recvCache[msgId] = nullptr; } } // Clean up anything we sent sendCache.erase(std::remove(sendCache.begin(), sendCache.end(), nullptr), sendCache.end()); pendingSends.erase( std::remove(pendingSends.begin(), pendingSends.end(), MPI_REQUEST_NULL), pendingSends.end()); // Clean up anything we received recvCache.erase(std::remove(recvCache.begin(), recvCache.end(), nullptr), recvCache.end()); pendingRecvs.erase( std::remove(pendingRecvs.begin(), pendingRecvs.end(), MPI_REQUEST_NULL), pendingRecvs.end()); } if (!pendingCollectives.empty()) { pendingCollectives.erase(std::remove_if(pendingCollectives.begin(), pendingCollectives.end(), [](const std::shared_ptr &col) { return col->finished(); }), pendingCollectives.end()); } } void Context::flushRemainingMessages() { while (!pendingRecvs.empty() || !pendingSends.empty() || !pendingCollectives.empty() || !inbox.empty() || !outbox.empty()) { sendMessagesFromOutbox(); pollForAndRecieveMessages(); waitOnSomeRequests(); processInboxMessages(); } } /*! start the service; from this point on maml is free to use MPI calls to send/receive messages; if your MPI library is not thread safe the app should _not_ do any MPI calls until 'stop()' has been called */ void Context::start() { std::lock_guard lock(tasksMutex); if (!isRunning()) { tasksAreRunning = true; auto launchMethod = AsyncLoop::LaunchMethod::AUTO; auto MAML_SPAWN_THREADS = getEnvVar("MAML_SPAWN_THREADS"); if (MAML_SPAWN_THREADS) { launchMethod = MAML_SPAWN_THREADS.value() ? AsyncLoop::LaunchMethod::THREAD : AsyncLoop::LaunchMethod::TASK; } if (!sendReceiveThread.get()) { sendReceiveThread = make_unique( [&]() { sendMessagesFromOutbox(); pollForAndRecieveMessages(); waitOnSomeRequests(); }, launchMethod); } if (!processInboxThread.get()) { processInboxThread = make_unique( [&]() { processInboxMessages(); }, launchMethod); } sendReceiveThread->start(); processInboxThread->start(); } } bool Context::isRunning() const { return tasksAreRunning; } /*! stops the maml layer; maml will no longer perform any MPI calls; if the mpi layer is not thread safe the app is then free to use MPI calls of its own, but it should not expect that this node receives any more messages (until the next 'start()' call) even if they are already in fligh WILL: Don't actually stop, for reasons described above flush messages */ void Context::stop() { std::lock_guard lock(tasksMutex); if (tasksAreRunning) { quitThreads = true; if (sendReceiveThread) { sendReceiveThread->stop(); } if (processInboxThread) { processInboxThread->stop(); } tasksAreRunning = false; flushRemainingMessages(); } } } // namespace maml RenderKit-ospray-85af292/modules/mpi/common/maml/Context.h000066400000000000000000000073471464752671100235560ustar00rootroot00000000000000// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #include "common/Collectives.h" #include "maml.h" #include "rkcommon/containers/TransactionalBuffer.h" #include "rkcommon/tasking/AsyncLoop.h" namespace maml { /*! the singleton object that handles all the communication */ struct OSPRAY_MPI_COMMON_EXPORT Context { Context(bool enableCompression = false); ~Context(); static std::unique_ptr singleton; /*! register a new incoing-message handler. if any message comes in on the given communicator we'll call this handler */ void registerHandlerFor(MPI_Comm comm, MessageHandler *handler); bool isRunning() const; /*! put the given message in the outbox. note that this can be done even if the actual sending mechanism is currently stopped */ void send(std::shared_ptr msg); /*! queue the given collective to be executed */ void queueCollective(std::shared_ptr col); /*! start the service; from this point on maml is free to use MPI calls to send/receive messages; if your MPI library is not thread safe the app should _not_ do any MPI calls until 'stop()' has been called */ void start(); /*! stops the maml layer; maml will no longer perform any MPI calls; if the mpi layer is not thread safe the app is then free to use MPI calls of its own, but it should not expect that this node receives any more messages (until the next 'start()' call) even if they are already in flight */ void stop(); private: // Helper functions // /*! the thread that executes messages that the receiver thread put into the inbox */ void processInboxTask(); void processInboxMessages(); /*! the thread (function) that executes all MPI commands to send/receive messages via MPI. Some notes: - it only looks for incoming messages on communicators for which a handler has been specified. if you don't add a handler to a comm, nothing will ever get received from this comm (you may still send on it, though!) - messages to be sent are retrieved from 'outbox'; messages that are received get put to 'inbox' and the 'inboxcondition' gets triggered. it's another thread's job to execute those messages */ void sendMessagesFromOutbox(); void pollForAndRecieveMessages(); void waitOnSomeRequests(); void flushRemainingMessages(); // Data members // rkcommon::containers::TransactionalBuffer> inbox; rkcommon::containers::TransactionalBuffer> outbox; rkcommon::containers::TransactionalBuffer> collectiveOutbox; // NOTE(jda) - sendCache/pendingSends MUST correspond with each other by // their index in their respective vectors... std::vector> sendCache; std::vector pendingSends; // NOTE(jda) - recvCache/pendingRecvs MUST correspond with each other by // their index in their respective vectors... std::vector> recvCache; std::vector pendingRecvs; std::vector> pendingCollectives; std::map handlers; bool useTaskingSystem{true}; bool compressMessages{false}; // NOTE(jda) - these are only used when _not_ using the tasking system... std::mutex tasksMutex; bool tasksAreRunning{false}; // std::thread sendReceiveThread, processInboxThread; std::atomic quitThreads{false}; std::unique_ptr sendReceiveThread; std::unique_ptr processInboxThread; }; } // namespace maml RenderKit-ospray-85af292/modules/mpi/common/maml/maml.cpp000066400000000000000000000041401464752671100233770ustar00rootroot00000000000000// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "maml.h" #include "Context.h" namespace maml { using rkcommon::make_unique; // maml API definitions ///////////////////////////////////////////////////// /*! start the service; from this point on maml is free to use MPI calls to send/receive messages; if your MPI library is not thread safe the app should _not_ do any MPI calls until 'stop()' has been called */ OSPRAY_MPI_COMMON_EXPORT void init(bool enableCompression) { Context::singleton = make_unique(enableCompression); } /*! stops the maml layer; maml will no longer perform any MPI calls; if the mpi layer is not thread safe the app is then free to use MPI calls of its own, but it should not expect that this node receives any more messages (until the next 'start()' call) even if they are already in flight */ OSPRAY_MPI_COMMON_EXPORT void shutdown() { Context::singleton = nullptr; } /*! register a new incoing-message handler. if any message comes in on the given communicator we'll call this handler */ OSPRAY_MPI_COMMON_EXPORT void registerHandlerFor( MPI_Comm comm, MessageHandler *handler) { Context::singleton->registerHandlerFor(comm, handler); } OSPRAY_MPI_COMMON_EXPORT void start() { Context::singleton->start(); } OSPRAY_MPI_COMMON_EXPORT bool isRunning() { return Context::singleton && Context::singleton->isRunning(); } OSPRAY_MPI_COMMON_EXPORT void stop() { Context::singleton->stop(); } /*! send given message to given comm:rank. Once this function has called maml has full ownership of this message, and the user may no longer access it (because maml may delete it at any time) */ OSPRAY_MPI_COMMON_EXPORT void sendTo( MPI_Comm comm, int rank, std::shared_ptr msg) { if (!(rank >= 0 && msg.get())) OSPRAY_THROW("Incorrect argument values given to maml::sendTo(...)"); msg->rank = rank; msg->comm = comm; Context::singleton->send(msg); } OSPRAY_MPI_COMMON_EXPORT void queueCollective(std::shared_ptr col) { Context::singleton->queueCollective(col); } } // namespace maml RenderKit-ospray-85af292/modules/mpi/common/maml/maml.h000066400000000000000000000071531464752671100230530ustar00rootroot00000000000000// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "common/Collectives.h" #include "common/MPICommon.h" namespace maml { using Message = mpicommon::Message; // Only bcast for now, to test using Collective = mpicommon::Collective; /*! abstraction for an object that can receive messages. handlers get associated with MPI_Comm's, and get called automatically every time such a message comes in. maml receives the message, then passed it to the handler, from which point it is owned by - and the respsonsibility of - the handler */ struct OSPRAY_MPI_COMMON_EXPORT MessageHandler { virtual void incoming(const std::shared_ptr &message) = 0; virtual ~MessageHandler() = default; }; /*! initialize the service for this process and start the service; from this point on maml is free to use MPI calls to send/receive messages; if your MPI library is not thread safe the app should _not_ do any MPI calls until 'shutdown()' has been called */ OSPRAY_MPI_COMMON_EXPORT void init(bool enableCompression = false); /*! shutdown the service for this process. stops the maml layer; maml will no longer perform any MPI calls; if the mpi layer is not thread safe the app is then free to use MPI calls of its own, but it should not expect that this node receives any more messages (until the next 'init()' call) even if they are already in flight */ OSPRAY_MPI_COMMON_EXPORT void shutdown(); /*! register a new incoing-message handler. if any message comes in on the given communicator we'll call this handler */ OSPRAY_MPI_COMMON_EXPORT void registerHandlerFor( MPI_Comm comm, MessageHandler *handler); /*! start the service; from this point on maml is free to use MPI calls to send/receive messages; if your MPI library is not thread safe the app should _not_ do any MPI calls until 'stop()' has been called */ OSPRAY_MPI_COMMON_EXPORT void start(); OSPRAY_MPI_COMMON_EXPORT bool isRunning(); /*! stops the maml layer; maml will no longer perform any MPI calls; if the mpi layer is not thread safe the app is then free to use MPI calls of its own, but it should not expect that this node receives any more messages (until the next 'start()' call) even if they are already in flight */ OSPRAY_MPI_COMMON_EXPORT void stop(); /*! schedule the given message to be send to the given comm:rank. comm and rank have to be a valid address. Once this function has been called maml has full ownership of this message, and the user may no longer access it (because maml may delete it at any time). note this message will not be sent immediately if the mpi sending is stopped; it will, however, be placed in the outbox to be sent at the next possible opportunity. If a rank sends a message to itself the MPI communication layer will be skipped, however some cost may be incurred when compressing/decompressing the message and accessing the various inbox/outbox vectors. WARNING: calling flush does NOT guarantee that there's no more messages coming in to this node: it does mean that all the messages we've already MPI_Probe'd will get finished receiving, but it will NOT guarantee that another node(s) aren't just sending out some new message(s) that simply haven't even STARTED arriving on this node, yet!!! */ OSPRAY_MPI_COMMON_EXPORT void sendTo( MPI_Comm comm, int rank, std::shared_ptr msg); /*! Schedule a collective to be run on the messaging layer */ OSPRAY_MPI_COMMON_EXPORT void queueCollective(std::shared_ptr col); } // namespace maml RenderKit-ospray-85af292/modules/mpi/ospray/000077500000000000000000000000001464752671100210455ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/ospray/CMakeLists.txt000066400000000000000000000155541464752671100236170ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ## Options ## set(OSPRAY_MPI_COMPRESSION_THRESHOLD 16 CACHE STRING "Min. number of ranks to enable message compression at (number)" ) mark_as_advanced(OSPRAY_MPI_COMPRESSION_THRESHOLD) ## Build the MPI Offload module ## add_library(ospray_module_mpi_offload SHARED ${OSPRAY_RESOURCE} OffloadModuleInit.cpp MPIOffloadWorker.cpp MPIOffloadDevice.cpp common/OSPWork.cpp common/ApplicationData.cpp ) target_link_libraries(ospray_module_mpi_offload PRIVATE rkcommon::rkcommon ospray_mpi_common ) target_include_directories(ospray_module_mpi_offload PUBLIC $ ) target_compile_definitions(ospray_module_mpi_offload PUBLIC OSP_MPI_COMPRESSION_THRESHOLD=${OSPRAY_MPI_COMPRESSION_THRESHOLD} # We don't want an instance of ObjectFactory static table in this library # so we have to include it with import define so the table will be imported # from 'ospray' library OBJECTFACTORY_IMPORT) ospray_install_library(ospray_module_mpi_offload mpi) ## Build the worker executable ## add_executable(ospray_mpi_worker ${OSPRAY_RESOURCE} mpi_offload_worker_main.cpp) target_link_libraries(ospray_mpi_worker PRIVATE ospray) install(TARGETS ospray_mpi_worker DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mpi) ospray_sign_target(ospray_mpi_worker) ## Build the MPI Distributed CPU module ## set(OSPRAY_MPI_DISTRIBUTED_HOST_SOURCES ${OSPRAY_RESOURCE} MPIDistributedDevice.cpp DistributedModuleInit.cpp common/DistributedWorld.cpp common/Messaging.cpp common/DynamicLoadBalancer.cpp fb/DistributedFrameBuffer.cpp fb/DistributedFrameBuffer_TileMessages.cpp fb/TileOperation.cpp render/DistributedLoadBalancer.cpp render/WriteMultipleTileOperation.cpp render/distributed/DistributedRaycast.cpp render/distributed/DistributedRenderer.cpp render/distributed/AlphaCompositeTileOperation.cpp ) set(OSPRAY_MPI_DISTRIBUTED_KERNEL_SOURCES MPIDistributedDevice.ispc fb/DistributedFrameBuffer.ispc render/distributed/DistributedRaycast.ispc render/distributed/DistributedRenderer.ispc ) include_directories_ispc( ${PROJECT_SOURCE_DIR}/ospray/include ${PROJECT_SOURCE_DIR}/ospray ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${RKCOMMON_INCLUDE_DIRS} ${EMBREE_INCLUDE_DIRS} ) add_definitions_ispc( -DOSPRAY_BEGIN_ISPC_NAMESPACE= -DOSPRAY_END_ISPC_NAMESPACE= -DSYCL_EXTERNAL= ) if (OSPRAY_ENABLE_VOLUMES) include_directories_ispc( ${OPENVKL_INCLUDE_DIRS} ) # Keep the NOTFOUND out of the ISPC include dirs list, because CMake will # see the variable ending with NOTFOUND and evaluate it to false and not # pass our include directories if (OPENVKL_CPU_DEVICE_INCLUDE_DIRS) include_directories_ispc( ${OPENVKL_CPU_DEVICE_INCLUDE_DIRS} ) endif() add_definitions_ispc( -DOSPRAY_ENABLE_VOLUMES ) endif() add_library(ospray_module_mpi_distributed_cpu SHARED ${OSPRAY_MPI_DISTRIBUTED_HOST_SOURCES} ) ispc_target_add_sources(ospray_module_mpi_distributed_cpu ${OSPRAY_MPI_DISTRIBUTED_KERNEL_SOURCES} ) # XXX ISPC cannot DLL-import constants, need to directly link again if (WIN32) target_sources(ospray_module_mpi_distributed_cpu PRIVATE ../../cpu/math/halton.c ../../cpu/math/sobol.c ) endif() target_link_libraries(ospray_module_mpi_distributed_cpu PRIVATE Snappy::snappy rkcommon::rkcommon ospray_mpi_common ospray_module_cpu ) target_include_directories(ospray_module_mpi_distributed_cpu PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # For ISPC module generated ispc headers ${PROJECT_BINARY_DIR}/ospray/ ) # Note: GPU hybrid code defines are brought in for us by linking the CPU module target_compile_definitions(ospray_module_mpi_distributed_cpu PRIVATE OSP_MPI_COMPRESSION_THRESHOLD=${OSPRAY_MPI_COMPRESSION_THRESHOLD} # We don't want an instance of ObjectFactory static table in this library # so we have to include it with import define so the table will be imported # from 'ospray' library OBJECTFACTORY_IMPORT ) ospray_install_library(ospray_module_mpi_distributed_cpu mpi) ## Build the MPI Distributed GPU module ## if (OSPRAY_MODULE_GPU) # Have CMake's build infrastructure treat the ISPC files as C++ for SYCL set_source_files_properties(${OSPRAY_MPI_DISTRIBUTED_KERNEL_SOURCES} PROPERTIES LANGUAGE CXX) add_library(ospray_module_mpi_distributed_gpu_kernels OBJECT ${OSPRAY_MPI_DISTRIBUTED_KERNEL_SOURCES} ) target_link_libraries(ospray_module_mpi_distributed_gpu_kernels PRIVATE ospray_module_gpu_kernels ) target_include_directories(ospray_module_mpi_distributed_gpu_kernels PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # For ISPC module generated ispc headers ${PROJECT_BINARY_DIR}/ospray/ ) if (OSPRAY_COMPILER_NEEDS_X_CPP) target_compile_options(ospray_module_mpi_distributed_gpu_kernels PRIVATE -x c++) endif() target_compile_options(ospray_module_mpi_distributed_gpu_kernels PRIVATE -g0 # XXX debug on device broken -Wdouble-promotion ) # Install and export without DESTINATION to turn it into INTERFACE library install(TARGETS ospray_module_mpi_distributed_gpu_kernels EXPORT ospray_Exports) add_library(ospray_module_mpi_distributed_gpu SHARED ${OSPRAY_MPI_DISTRIBUTED_HOST_SOURCES} ) # Note: GPU hybrid code defines are brought in for us by linking the CPU module target_compile_definitions(ospray_module_mpi_distributed_gpu PRIVATE OSP_MPI_COMPRESSION_THRESHOLD=${OSPRAY_MPI_COMPRESSION_THRESHOLD} # We don't want an instance of ObjectFactory static table in this library # so we have to include it with import define so the table will be imported # from 'ospray' library OBJECTFACTORY_IMPORT ) target_link_libraries(ospray_module_mpi_distributed_gpu PUBLIC ospray_module_gpu_kernels ospray_module_mpi_distributed_gpu_kernels PRIVATE Snappy::snappy rkcommon::rkcommon ospray_mpi_common ospray_module_gpu ) ospray_install_library(ospray_module_mpi_distributed_gpu lib) endif() # ------------------------------------------------------- # Install SDK headers # ------------------------------------------------------- get_subdirectories(SUBDIRS ${CMAKE_CURRENT_LIST_DIR}) foreach(dir ${SUBDIRS}) install(DIRECTORY ${dir} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/SDK/modules/mpi COMPONENT devel FILES_MATCHING PATTERN *.h PATTERN *.ih ) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/SDK/modules/mpi COMPONENT devel FILES_MATCHING PATTERN *_ispc.h PATTERN CMakeFiles EXCLUDE ) endforeach() RenderKit-ospray-85af292/modules/mpi/ospray/DistributedModuleInit.cpp000066400000000000000000000021621464752671100260260ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // We don't want an instance of ObjectFactory static table in this library so // we set OBJECTFACTORY_IMPORT at the CMake build flag level for the module #include "common/ObjectFactory.h" #include "MPIDistributedDevice.h" #include "common/OSPCommon.h" #include "render/distributed/DistributedRaycast.h" extern "C" OSPError OSPRAY_DLLEXPORT #ifdef OSPRAY_TARGET_SYCL ospray_module_init_mpi_distributed_gpu( #else ospray_module_init_mpi_distributed_cpu( #endif int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/) { using namespace ospray; auto status = moduleVersionCheck(versionMajor, versionMinor); if (status == OSP_NO_ERROR) { // Run the CPU/GPU module's initialization function to register local types #ifdef OSPRAY_TARGET_SYCL status = ospLoadModule("gpu"); #else status = ospLoadModule("cpu"); #endif } if (status == OSP_NO_ERROR) { api::Device::registerType("mpiDistributed"); Renderer::registerType("mpiRaycast"); } return status; } RenderKit-ospray-85af292/modules/mpi/ospray/MPIDistributedDevice.cpp000066400000000000000000000444551464752671100255350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #ifdef _WIN32 #define NOMINMAX #include #else #include #endif #include "ISPCDevice.h" #include "MPIDistributedDevice.h" #include "camera/Camera.h" #include "common/Data.h" #include "common/DistributedWorld.h" #include "common/Group.h" #include "common/Instance.h" #include "common/MPICommon.h" #include "fb/DistributedFrameBuffer.h" #include "geometry/GeometricModel.h" #include "lights/Light.h" #include "render/DistributedLoadBalancer.h" #include "render/Material.h" #include "render/ThreadedRenderTask.h" #include "render/distributed/DistributedRaycast.h" #include "rkcommon/tasking/tasking_system_init.h" #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/CodeTimer.h" #include "rkcommon/utility/getEnvVar.h" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/Volume.h" #include "volume/VolumetricModel.h" #include "volume/transferFunction/TransferFunction.h" #endif static_assert(sizeof(bool) == 1, "OSPRay's implementation assumes the size of 'bool' to be 1 byte."); namespace ospray { namespace mpi { // Helper functions /////////////////////////////////////////////////////// using SetParamFcn = void(OSPObject, const char *, const void *m); template static void setParamOnObject(OSPObject _obj, const char *p, const T &v) { auto *obj = lookupObject(_obj); obj->setParam(p, v); } #define declare_param_setter(TYPE) \ { \ OSPTypeFor::value, [](OSPObject o, const char *p, const void *v) { \ setParamOnObject(o, p, *(TYPE *)v); \ } \ } #define declare_param_setter_object(TYPE) \ { \ OSPTypeFor::value, [](OSPObject o, const char *p, const void *v) { \ auto *obj = lookupObject( \ *reinterpret_cast(v)); \ setParamOnObject(o, p, obj); \ } \ } #define declare_param_setter_string(TYPE) \ { \ OSPTypeFor::value, [](OSPObject o, const char *p, const void *v) { \ const char *str = (const char *)v; \ setParamOnObject(o, p, std::string(str)); \ } \ } static std::map> setParamFcns = { declare_param_setter(api::Device *), declare_param_setter(void *), declare_param_setter(bool), declare_param_setter_object(ManagedObject *), declare_param_setter_object(Camera *), declare_param_setter_object(Data *), declare_param_setter_object(FrameBuffer *), declare_param_setter_object(Future *), declare_param_setter_object(Geometry *), declare_param_setter_object(GeometricModel *), declare_param_setter_object(Group *), declare_param_setter_object(ImageOp *), declare_param_setter_object(Instance *), declare_param_setter_object(Light *), declare_param_setter_object(Material *), declare_param_setter_object(Renderer *), declare_param_setter_object(Texture *), #ifdef OSPRAY_ENABLE_VOLUMES declare_param_setter_object(TransferFunction *), declare_param_setter_object(Volume *), declare_param_setter_object(VolumetricModel *), #endif declare_param_setter_object(World *), declare_param_setter_string(const char *), declare_param_setter(char *), declare_param_setter(char), declare_param_setter(vec2c), declare_param_setter(vec3c), declare_param_setter(vec4c), declare_param_setter(unsigned char), declare_param_setter(vec2uc), declare_param_setter(vec3uc), declare_param_setter(vec4uc), declare_param_setter(short), declare_param_setter(vec2s), declare_param_setter(vec3s), declare_param_setter(vec4s), declare_param_setter(unsigned short), declare_param_setter(vec2us), declare_param_setter(vec3us), declare_param_setter(vec4us), declare_param_setter(int), declare_param_setter(vec2i), declare_param_setter(vec3i), declare_param_setter(vec4i), declare_param_setter(unsigned int), declare_param_setter(vec2ui), declare_param_setter(vec3ui), declare_param_setter(vec4ui), declare_param_setter(int64_t), declare_param_setter(vec2l), declare_param_setter(vec3l), declare_param_setter(vec4l), declare_param_setter(uint64_t), declare_param_setter(vec2ul), declare_param_setter(vec3ul), declare_param_setter(vec4ul), declare_param_setter(float), declare_param_setter(vec2f), declare_param_setter(vec3f), declare_param_setter(vec4f), declare_param_setter(double), declare_param_setter(vec2d), declare_param_setter(vec3d), declare_param_setter(vec4d), declare_param_setter(box1i), declare_param_setter(box2i), declare_param_setter(box3i), declare_param_setter(box4i), declare_param_setter(box1f), declare_param_setter(box2f), declare_param_setter(box3f), declare_param_setter(box4f), declare_param_setter(linear2f), declare_param_setter(linear3f), declare_param_setter(affine2f), declare_param_setter(affine3f)}; #undef declare_param_setter template inline API_TYPE createDistributedObject( const char *type, api::ISPCDevice &device, ObjectHandle handle) { auto *instance = OSPRAY_TYPE::createInstance(type, device); handle.assign(instance); return (API_TYPE)(int64)handle; } // MPIDistributedDevice definitions /////////////////////////////////////// MPIDistributedDevice::MPIDistributedDevice() { internalDevice = std::make_shared(); } MPIDistributedDevice::~MPIDistributedDevice() { messaging::shutdown(); if (shouldFinalizeMPI) { try { MPI_CALL(Finalize()); } catch (...) { // Silently move on if finalize fails } } RKCOMMON_IF_TRACING_ENABLED({ char hostname[512] = {0}; gethostname(hostname, 511); const std::string workerTraceFile = std::string(hostname) + "_" + std::to_string(mpicommon::workerRank()) + ".json"; rkcommon::tracing::saveLog( workerTraceFile.c_str(), workerTraceFile.c_str()); }); } static void internalDeviceErrorFunc( void *, const OSPError code, const char *str) { postStatusMsg() << "#OSPRay MPI InternalDevice: internal error " << code << " : " << str; throw std::runtime_error( "OSPRay MPIInternalDevice internal error '" + std::string(str) + "'"); } void MPIDistributedDevice::commit() { Device::commit(); // MPI Device defaults to not setting affinity if (threadAffinity == AUTO_DETECT) { threadAffinity = DEAFFINITIZE; } if (!initialized) { internalDevice->error_fcn = internalDeviceErrorFunc; int _ac = 1; const char *_av[] = {"ospray_mpi_distributed_device"}; auto *setComm = static_cast(getParam("worldCommunicator", nullptr)); shouldFinalizeMPI = mpicommon::init(&_ac, _av, setComm == nullptr); if (setComm) mpicommon::worker.setTo(*setComm); else mpicommon::worker = mpicommon::world; initialized = true; auto OSPRAY_FORCE_COMPRESSION = utility::getEnvVar("OSPRAY_FORCE_COMPRESSION"); // Turning on the compression past 64 ranks seems to be a good // balancing point for cost of compressing vs. performance gain auto enableCompression = OSPRAY_FORCE_COMPRESSION.value_or( mpicommon::workerSize() >= OSP_MPI_COMPRESSION_THRESHOLD); maml::init(enableCompression); messaging::init(mpicommon::worker); maml::start(); RKCOMMON_IF_TRACING_ENABLED({ mpicommon::barrier(mpicommon::worker.comm).wait(); rkcommon::tracing::setMarker("clockSync", "mpiDistributed"); char hostname[512] = {0}; gethostname(hostname, 511); const std::string worker_log_file = std::string(hostname) + "_" + std::to_string(mpicommon::workerRank()) + "_worker_proc_status.txt"; std::ofstream fout(worker_log_file.c_str()); fout << "Worker on '" << hostname << "' /proc/self/status:\n" << rkcommon::tracing::getProcStatus() << "\n"; }); } // Pass down application's GPU selection made via SYCL or L0 (if any) void *appSyclCtx = getParam("syclContext", nullptr); internalDevice->setParam("syclContext", appSyclCtx); void *appSyclDevice = getParam("syclDevice", nullptr); internalDevice->setParam("syclDevice", appSyclDevice); internalDevice->commit(); } OSPFrameBuffer MPIDistributedDevice::frameBufferCreate( const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) { ObjectHandle handle = allocateHandle(); auto *instance = new DistributedFrameBuffer( *(ospray::api::ISPCDevice *)internalDevice.get(), size, handle, mode, channels); handle.assign(instance); return (OSPFrameBuffer)(int64)handle; } const void *MPIDistributedDevice::frameBufferMap( OSPFrameBuffer _fb, OSPFrameBufferChannel channel) { if (!mpicommon::IamTheMaster()) throw std::runtime_error("Can only map framebuffer on the master!"); auto *fb = lookupDistributedObject(_fb); return fb->mapBuffer(channel); } void MPIDistributedDevice::frameBufferUnmap( const void *mapped, OSPFrameBuffer _fb) { auto *fb = lookupDistributedObject(_fb); fb->unmap(mapped); } void MPIDistributedDevice::resetAccumulation(OSPFrameBuffer _fb) { auto *fb = lookupDistributedObject(_fb); fb->clear(); } OSPGroup MPIDistributedDevice::newGroup() { return internalDevice->newGroup(); } OSPInstance MPIDistributedDevice::newInstance(OSPGroup _group) { return internalDevice->newInstance(_group); } OSPWorld MPIDistributedDevice::newWorld() { ObjectHandle handle = allocateHandle(); auto *instance = new DistributedWorld(*(ospray::api::ISPCDevice *)internalDevice.get()); handle.assign(instance); return (OSPWorld)(int64)(handle); } box3f MPIDistributedDevice::getBounds(OSPObject _obj) { auto *obj = lookupObject(_obj); return internalDevice->getBounds((OSPObject)obj); } OSPData MPIDistributedDevice::newSharedData(const void *sharedData, OSPDataType type, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback freeFunction, const void *userPtr) { return internalDevice->newSharedData( sharedData, type, numItems, byteStride, freeFunction, userPtr); } OSPData MPIDistributedDevice::newData(OSPDataType type, const vec3ul &numItems) { return internalDevice->newData(type, numItems); } void MPIDistributedDevice::copyData( const OSPData source, OSPData destination, const vec3ul &destinationIndex) { internalDevice->copyData(source, destination, destinationIndex); } int MPIDistributedDevice::loadModule(const char *name) { return loadLocalModule(name); } OSPImageOperation MPIDistributedDevice::newImageOp(const char *type) { return internalDevice->newImageOp(type); } OSPRenderer MPIDistributedDevice::newRenderer(const char *type) { ObjectHandle handle = allocateHandle(); return createDistributedObject( type, *(api::ISPCDevice *)internalDevice.get(), handle); } OSPCamera MPIDistributedDevice::newCamera(const char *type) { return internalDevice->newCamera(type); } OSPVolume MPIDistributedDevice::newVolume(const char *type) { #ifdef OSPRAY_ENABLE_VOLUMES return internalDevice->newVolume(type); #else return nullptr; #endif } OSPGeometry MPIDistributedDevice::newGeometry(const char *type) { return internalDevice->newGeometry(type); } OSPGeometricModel MPIDistributedDevice::newGeometricModel(OSPGeometry _geom) { auto *geom = lookupObject(_geom); return internalDevice->newGeometricModel((OSPGeometry)geom); } OSPVolumetricModel MPIDistributedDevice::newVolumetricModel(OSPVolume _vol) { #ifdef OSPRAY_ENABLE_VOLUMES auto *volume = lookupObject(_vol); return internalDevice->newVolumetricModel((OSPVolume)volume); #else return nullptr; #endif } OSPMaterial MPIDistributedDevice::newMaterial(const char *material_type) { return internalDevice->newMaterial(material_type); } OSPTransferFunction MPIDistributedDevice::newTransferFunction(const char *type) { return internalDevice->newTransferFunction(type); } OSPLight MPIDistributedDevice::newLight(const char *type) { return internalDevice->newLight(type); } OSPFuture MPIDistributedDevice::renderFrame(OSPFrameBuffer _fb, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world) { RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::beginEvent("renderFrame", "MPIDD"); rkcommon::tracing::beginEvent("renderFrame-mpibarrier", "MPIDD"); }); mpicommon::barrier(mpicommon::worker.comm).wait(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("renderFrame-lookupObjects", "MPIDD"); }); auto *fb = lookupDistributedObject(_fb); auto *renderer = lookupDistributedObject(_renderer); auto *camera = lookupObject(_camera); auto *world = lookupObject(_world); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("renderFrame-createDLB", "MPIDD"); }); auto loadBalancer = std::make_shared(allocateHandle()); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); fb->setCompletedEvent(OSP_NONE_FINISHED); fb->refInc(); renderer->refInc(); camera->refInc(); world->refInc(); RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("renderFrame-spawnRenderThread", "MPIDD")); auto *f = new ThreadedRenderTask(fb, loadBalancer, [=]() { RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::setThreadName("MPIDD::threadedRenderTask"); rkcommon::tracing::beginEvent("renderFrameTask", "MPIDD"); }); utility::CodeTimer timer; timer.start(); loadBalancer->renderFrame(fb, renderer, camera, world); timer.stop(); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); fb->refDec(); renderer->refDec(); camera->refDec(); world->refDec(); return timer.seconds(); }); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); return (OSPFuture)f; } int MPIDistributedDevice::isReady(OSPFuture _task, OSPSyncEvent event) { auto *task = (Future *)_task; return task->isFinished(event); } void MPIDistributedDevice::wait(OSPFuture _task, OSPSyncEvent event) { auto *task = (Future *)_task; task->wait(event); } void MPIDistributedDevice::cancel(OSPFuture _task) { auto *task = (Future *)_task; return task->cancel(); } float MPIDistributedDevice::getProgress(OSPFuture _task) { auto *task = (Future *)_task; return task->getProgress(); } float MPIDistributedDevice::getTaskDuration(OSPFuture _task) { return internalDevice->getTaskDuration(_task); } float MPIDistributedDevice::getVariance(OSPFrameBuffer _fb) { auto *fb = lookupDistributedObject(_fb); return internalDevice->getVariance((OSPFrameBuffer)fb); } void MPIDistributedDevice::setObjectParam( OSPObject object, const char *name, OSPDataType type, const void *mem) { if (type == OSP_UNKNOWN) throw std::runtime_error("cannot set OSP_UNKNOWN parameter type"); if (type == OSP_BYTE || type == OSP_RAW) { setParamOnObject(object, name, *(const byte_t *)mem); return; } setParamFcns[type](object, name, mem); } void MPIDistributedDevice::removeObjectParam( OSPObject _object, const char *name) { auto *object = lookupObject(_object); return internalDevice->removeObjectParam((OSPObject)object, name); } void MPIDistributedDevice::commit(OSPObject _object) { auto *object = lookupObject(_object); internalDevice->commit((OSPObject)object); } void MPIDistributedDevice::release(OSPObject _obj) { if (!_obj) return; auto &handle = reinterpret_cast(_obj); auto *object = lookupObject(_obj); if (object->useCount() == 1 && handle.defined()) { handle.freeObject(); } object->refDec(); } void MPIDistributedDevice::retain(OSPObject _obj) { auto *object = lookupObject(_obj); object->refInc(); } OSPTexture MPIDistributedDevice::newTexture(const char *type) { return internalDevice->newTexture(type); } OSPPickResult MPIDistributedDevice::pick(OSPFrameBuffer _fb, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world, const vec2f &screenPos) { auto *fb = lookupDistributedObject(_fb); auto *renderer = lookupDistributedObject(_renderer); auto *camera = lookupObject(_camera); auto *world = lookupObject(_world); return renderer->pick(fb, camera, world, screenPos); } ObjectHandle MPIDistributedDevice::allocateHandle() { mpicommon::barrier(mpicommon::worker.comm).wait(); ObjectHandle handle = ObjectHandle::allocateLocalHandle(); // For debugging check that all ranks did in fact allocate the same handle. // Typically we assume this is the case, as the app should be creating // distributed objects in lock-step, even if their local objects differ. if (logLevel == OSP_LOG_DEBUG) { int maxID = handle.i32.ID; int minID = handle.i32.ID; auto reduceMax = mpicommon::reduce( &handle.i32.ID, &maxID, 1, MPI_INT, MPI_MAX, 0, mpicommon::worker.comm); auto reduceMin = mpicommon::reduce( &handle.i32.ID, &minID, 1, MPI_INT, MPI_MIN, 0, mpicommon::worker.comm); reduceMax.wait(); reduceMin.wait(); if (maxID != minID) { // Log it, but this is a fatal error postStatusMsg( "Error allocating distributed handles: Ranks do not all have the same handle!"); throw std::runtime_error( "Error allocating distributed handles: Ranks do not all have the same handle!"); } } return handle; } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/MPIDistributedDevice.h000066400000000000000000000101761464752671100251730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "api/Device.h" #include "common/MPICommon.h" #include "common/Managed.h" #include "common/ObjectHandle.h" #include "render/DistributedLoadBalancer.h" #include "render/LoadBalancer.h" #include "rkcommon/platform.h" namespace ospray { namespace mpi { template inline OSPRAY_TYPE *lookupDistributedObject(OSPObject obj) { auto &handle = reinterpret_cast(obj); auto *object = (OSPRAY_TYPE *)handle.lookup(); if (!object) { throw std::runtime_error("#dmpi: ObjectHandle doesn't exist!"); } return object; } struct MPIDistributedDevice : public api::Device { MPIDistributedDevice(); ~MPIDistributedDevice() override; // ManagedObject Implementation ///////////////////////////////////////// void commit() override; // Device Implementation //////////////////////////////////////////////// /*! create a new frame buffer */ OSPFrameBuffer frameBufferCreate(const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) override; /*! create a new transfer function object (out of list of registered transfer function types) */ OSPTransferFunction newTransferFunction(const char *type) override; /*! have given renderer create a new Light */ OSPLight newLight(const char *light_type) override; /*! map frame buffer */ const void *frameBufferMap( OSPFrameBuffer fb, OSPFrameBufferChannel channel) override; /*! unmap previously mapped frame buffer */ void frameBufferUnmap(const void *mapped, OSPFrameBuffer fb) override; /*! create a new ImageOp object (out of list of registered ImageOps) */ OSPImageOperation newImageOp(const char *type) override; void resetAccumulation(OSPFrameBuffer _fb) override; // Instancing /////////////////////////////////////////////////////////// OSPGroup newGroup() override; OSPInstance newInstance(OSPGroup group) override; // Top-level Worlds ///////////////////////////////////////////////////// OSPWorld newWorld() override; box3f getBounds(OSPObject) override; // OSPRay Data Arrays /////////////////////////////////////////////////// OSPData newSharedData(const void *sharedData, OSPDataType, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback, const void *userPtr) override; OSPData newData(OSPDataType, const vec3ul &numItems) override; void copyData(const OSPData source, OSPData destination, const vec3ul &destinationIndex) override; OSPRenderer newRenderer(const char *type) override; OSPGeometry newGeometry(const char *type) override; OSPMaterial newMaterial(const char *material_type) override; OSPCamera newCamera(const char *type) override; OSPVolume newVolume(const char *type) override; OSPGeometricModel newGeometricModel(OSPGeometry geom) override; OSPVolumetricModel newVolumetricModel(OSPVolume volume) override; OSPFuture renderFrame( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld) override; int isReady(OSPFuture, OSPSyncEvent) override; void wait(OSPFuture, OSPSyncEvent) override; void cancel(OSPFuture) override; float getProgress(OSPFuture) override; float getTaskDuration(OSPFuture) override; float getVariance(OSPFrameBuffer) override; /*! load module */ int loadModule(const char *name) override; // Object + Parameter Lifetime Management /////////////////////////////// void setObjectParam(OSPObject object, const char *name, OSPDataType type, const void *mem) override; void removeObjectParam(OSPObject object, const char *name) override; void commit(OSPObject object) override; void release(OSPObject _obj) override; void retain(OSPObject _obj) override; /*! create a new Texture object */ OSPTexture newTexture(const char *type) override; OSPPickResult pick( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, const vec2f &) override; private: ObjectHandle allocateHandle(); bool initialized{false}; bool shouldFinalizeMPI{false}; std::shared_ptr internalDevice = nullptr; }; } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/MPIDistributedDevice.ispc000066400000000000000000000003261464752671100256760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 OSPRAY_BEGIN_ISPC_NAMESPACE export uniform int MPIDistributedDevice_programCount() { return programCount; } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/mpi/ospray/MPIOffloadDevice.cpp000066400000000000000000001020321464752671100246070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifndef _WIN32 #include #include #endif #ifdef OPEN_MPI #include #include #endif #include "MPIOffloadDevice.h" #include "common/Library.h" #include "common/MPIBcastFabric.h" #include "common/MPICommon.h" #include "common/OSPWork.h" #include "common/maml/maml.h" #include "rkcommon/networking/DataStreaming.h" #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/ArrayView.h" #include "rkcommon/utility/FixedArrayView.h" #include "rkcommon/utility/OwnedArray.h" #include "rkcommon/utility/getEnvVar.h" namespace ospray { namespace mpi { using namespace mpicommon; using namespace rkcommon; /////////////////////////////////////////////////////////////////////////// // Forward declarations /////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //! this runs an ospray worker process. /*! it's up to the proper init routine to decide which processes call this function and which ones don't. This function will not return. */ void runWorker(bool useMPIFabric, MPIOffloadDevice *offloadDevice); /////////////////////////////////////////////////////////////////////////// // Misc helper functions ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// static inline void throwIfNotMpiParallel() { if (world.size <= 1) { throw std::runtime_error( "No MPI workers found.\n#osp:mpi: Fatal Error " "- OSPRay told to run in MPI mode, but there " "seems to be no MPI peers!?\n#osp:mpi: (Did " "you forget an 'mpirun' in front of your " "application?)"); } } static inline void setupMaster() { MPI_Comm appComm; MPI_CALL(Comm_split(world.comm, 1, world.rank, &appComm)); int size = 0; int rank = 0; MPI_Comm_size(appComm, &size); MPI_Comm_rank(appComm, &rank); postStatusMsg(OSP_LOG_INFO) << "#w: app process " << rank << '/' << size << " (global " << world.rank << '/' << world.size << ')'; MPI_CALL(Barrier(world.comm)); MPI_CALL(Comm_free(&appComm)); // ------------------------------------------------------- // at this point, all processes should be set up and synced. in // particular: // - app has intracommunicator to all workers (and vica versa) // - app process(es) are in one intercomm ("app"); workers all in // another ("worker") // - all processes (incl app) have barrier'ed, and thus now in sync. } static inline void setupWorker() { MPI_CALL(Comm_split(world.comm, 0, world.rank, &worker.comm)); worker.makeIntraComm(); postStatusMsg(OSP_LOG_INFO) << "master: Made 'worker' intercomm (through split): " << std::hex << std::showbase << worker.comm << std::noshowbase << std::dec; MPI_CALL(Barrier(world.comm)); // ------------------------------------------------------- // at this point, all processes should be set up and synced. in // particular: // - app has intracommunicator to all workers (and vica versa) // - app process(es) are in one intercomm ("app"); workers all in // another ("worker") // - all processes (incl app) have barrier'ed, and thus now in sync. } /////////////////////////////////////////////////////////////////////////// // MPI initialization helper functions //////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /*! TODO WILL: Update these comments in this mode ("ospray on ranks" mode, or "ranks" mode), the user has launched the app across all ranks using mpirun " "; no new processes need to get launched. Based on the 'startworkers' flag, this function can set up ospray in one of two modes: in "workers" mode (startworkers=true) all ranks > 0 become workers, and will NOT return to the application; rank 0 is the master that controls those workers but doesn't do any rendering (we may at some point allow the master to join in working as well, but currently this is not implemented). to reach that mode we call this function with 'startworkers=true', which will make sure that, even though all ranks _called_ mpiinit, only rank 0 will ever return to the app, while all other ranks will automatically go to running worker code, and never ever return from this function. b) in "distributed" mode the app itself is distributed, and will use the ospray distributed api to control ospray in a data-distributed mode. in this way, we'll call this function with startWorkers=false, which will let all ranks return from this function to do further work in the app. For this function, we assume: - all *all* MPI_COMM_WORLD processes are going into this function - this fct is called from ospInit (with ranksBecomeWorkers=true) or from ospdMpiInit (w/ ranksBecomeWorkers = false) */ void createMPI_RanksBecomeWorkers( int *ac, const char **av, MPIOffloadDevice *offloadDevice) { mpi::init(ac, av, true); postStatusMsg(OSP_LOG_INFO) << "#o: initMPI::OSPonRanks: " << world.rank << '/' << world.size; // Note: here we don't run this collective through MAML, since we // haven't started it yet. MPI_CALL(Barrier(world.comm)); RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("clockSync", "mpiOffload")); throwIfNotMpiParallel(); if (world.rank == 0) setupMaster(); else { setupWorker(); // now, all workers will enter their worker loop (ie, they will *not* // return) mpi::runWorker(true, offloadDevice); throw std::runtime_error("should never reach here!"); /* no return here - 'runWorker' will never return */ } } void createMPI_ListenForClient( int *ac, const char **av, MPIOffloadDevice *offloadDevice) { mpi::init(ac, av, true); if (world.rank == 0) { postStatusMsg(OSP_LOG_INFO) << "#o: Initialize OSPRay MPI in 'Listen for Client' Mode"; } worker.comm = world.comm; worker.makeIntraComm(); mpi::runWorker(false, offloadDevice); } /////////////////////////////////////////////////////////////////////////// // MPIDevice definitions ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// MPIOffloadDevice::~MPIOffloadDevice() { try { if (dynamic_cast(fabric.get()) && world.rank == 0) { postStatusMsg(OSP_LOG_INFO) << "shutting down mpi device"; sendWork( [](networking::WriteStream &writer) { writer << work::FINALIZE; }, true); fabric = nullptr; maml::shutdown(); MPI_Finalize(); RKCOMMON_IF_TRACING_ENABLED({ char hostname[512] = {0}; gethostname(hostname, 511); const std::string masterTraceFile = std::string(hostname) + "_master.json"; rkcommon::tracing::saveLog( masterTraceFile.c_str(), masterTraceFile.c_str()); }); } } catch (const std::exception &e) { handleError(OSP_UNKNOWN_ERROR, e.what()); } } void MPIOffloadDevice::initializeDevice() { initialized = true; int _ac = 1; const char *_av[] = {"ospray_mpi_worker"}; std::string mode = getParam("mpiMode", "mpi"); if (mode == "mpi") { createMPI_RanksBecomeWorkers(&_ac, _av, this); RKCOMMON_IF_TRACING_ENABLED({ char hostname[512] = {0}; gethostname(hostname, 511); const std::string master_log_file = std::string(hostname) + "_master_proc_status.txt"; std::ofstream fout(master_log_file.c_str()); fout << "Master on '" << hostname << "' /proc/self/status:\n" << rkcommon::tracing::getProcStatus() << "\n"; }); // Only the master returns from this call fabric = rkcommon::make_unique(world, 0); maml::init(false); maml::start(); } else { throw std::runtime_error("Invalid MPI mode!"); } // Setup the command buffer on the app rank maxCommandBufferEntries = getParam("maxCommandBufferEntries", 8192); commandBufferSize = getParam("commandBufferSize", 512) * (1 << 20); maxInlineDataSize = getParam("maxInlineDataSize", 32) * (1 << 20); auto OSPRAY_MPI_MAX_COMMAND_BUFFER_ENTRIES = utility::getEnvVar("OSPRAY_MPI_MAX_COMMAND_BUFFER_ENTRIES"); if (OSPRAY_MPI_MAX_COMMAND_BUFFER_ENTRIES) { maxCommandBufferEntries = OSPRAY_MPI_MAX_COMMAND_BUFFER_ENTRIES.value(); } auto OSPRAY_MPI_COMMAND_BUFFER_SIZE = utility::getEnvVar("OSPRAY_MPI_COMMAND_BUFFER_SIZE"); if (OSPRAY_MPI_COMMAND_BUFFER_SIZE) { commandBufferSize = OSPRAY_MPI_COMMAND_BUFFER_SIZE.value() * (1 << 20); } auto OSPRAY_MPI_MAX_INLINE_DATA_SIZE = utility::getEnvVar("OSPRAY_MPI_MAX_INLINE_DATA_SIZE"); if (OSPRAY_MPI_MAX_INLINE_DATA_SIZE) { maxInlineDataSize = OSPRAY_MPI_MAX_INLINE_DATA_SIZE.value() * (1 << 20); } if (commandBufferSize >= 1.8f * (1 << 30)) { static WarnOnce warn( "Command buffer size must be less than 1.8GB, resetting to 1.8GB"); commandBufferSize = 1.8f * (1 << 30); } if (maxInlineDataSize >= commandBufferSize / 2.f) { static WarnOnce warn( "Max inline data size must be less than half command buffer size"); maxInlineDataSize = std::ceil(commandBufferSize / 2.f); } commandBuffer = networking::FixedBufferWriter(commandBufferSize); } /////////////////////////////////////////////////////////////////////////// // ManagedObject Implementation /////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// void MPIOffloadDevice::commit() { Device::commit(); // MPI Device defaults to not setting affinity if (threadAffinity == AUTO_DETECT) { threadAffinity = DEAFFINITIZE; } if (!initialized) initializeDevice(); } /////////////////////////////////////////////////////////////////////////// // Device Implementation ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// int MPIOffloadDevice::loadModule(const char *name) { sendWork( [&](networking::WriteStream &writer) { writer << work::LOAD_MODULE << name; }, false); // TODO: Error reporting from the workers return 0; } /////////////////////////////////////////////////////////////////////////// // Renderable Objects ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPLight MPIOffloadDevice::newLight(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_LIGHT << handle.i64 << type; }, false); return (OSPLight)(int64)handle; } OSPCamera MPIOffloadDevice::newCamera(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_CAMERA << handle.i64 << type; }, false); return (OSPCamera)(int64)handle; } OSPGeometry MPIOffloadDevice::newGeometry(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_GEOMETRY << handle.i64 << type; }, false); return (OSPGeometry)(int64)handle; } OSPVolume MPIOffloadDevice::newVolume(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_VOLUME << handle.i64 << type; }, false); return (OSPVolume)(int64)handle; } OSPGeometricModel MPIOffloadDevice::newGeometricModel(OSPGeometry geom) { ObjectHandle handle = allocateHandle(); ObjectHandle geomHandle = (ObjectHandle &)geom; sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_GEOMETRIC_MODEL << handle.i64 << geomHandle.i64; }, false); return (OSPGeometricModel)(int64)handle; } OSPVolumetricModel MPIOffloadDevice::newVolumetricModel(OSPVolume volume) { ObjectHandle handle = allocateHandle(); ObjectHandle volHandle = (ObjectHandle &)volume; sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_VOLUMETRIC_MODEL << handle.i64 << volHandle.i64; }, false); return (OSPVolumetricModel)(int64)handle; } /////////////////////////////////////////////////////////////////////////// // Model Meta-Data //////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPMaterial MPIOffloadDevice::newMaterial(const char *material_type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_MATERIAL << handle.i64 << material_type; }, false); return (OSPMaterial)(int64)handle; } OSPTransferFunction MPIOffloadDevice::newTransferFunction(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_TRANSFER_FUNCTION << handle.i64 << type; }, false); return (OSPTransferFunction)(int64)handle; } OSPTexture MPIOffloadDevice::newTexture(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_TEXTURE << handle.i64 << type; }, false); return (OSPTexture)(int64)handle; } /////////////////////////////////////////////////////////////////////////// // Instancing ///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPGroup MPIOffloadDevice::newGroup() { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_GROUP << handle.i64; }, false); return (OSPGroup)(int64)handle; } OSPInstance MPIOffloadDevice::newInstance(OSPGroup group) { ObjectHandle handle = allocateHandle(); ObjectHandle groupHandle = (ObjectHandle &)group; sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_INSTANCE << handle.i64 << groupHandle.i64; }, false); return (OSPInstance)(int64)handle; } /////////////////////////////////////////////////////////////////////////// // World Manipulation ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPWorld MPIOffloadDevice::newWorld() { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_WORLD << handle.i64; }, false); return (OSPWorld)(int64)handle; } box3f MPIOffloadDevice::getBounds(OSPObject _obj) { const ObjectHandle obj = (ObjectHandle &)_obj; sendWork( [&](networking::WriteStream &writer) { writer << work::GET_BOUNDS << obj; }, true); box3f result; utility::ArrayView view( reinterpret_cast(&result), sizeof(box3f)); fabric->recv(view, rootWorkerRank()); return result; } /////////////////////////////////////////////////////////////////////////// // OSPRay Data Arrays ///////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPData MPIOffloadDevice::newSharedData(const void *sharedData, OSPDataType format, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback freeFunction, const void *userPtr) { ObjectHandle handle = allocateHandle(); this->sharedData[handle.i64] = ApplicationData( sharedData, format, numItems, byteStride, freeFunction, userPtr); sendWork( [&](networking::WriteStream &writer) { // Data on the workers is always compact, so we don't send the stride writer << work::NEW_SHARED_DATA << handle.i64 << format << numItems; sendDataWork(writer, this->sharedData[handle.i64]); }, false); return (OSPData)(int64)handle; } OSPData MPIOffloadDevice::newData(OSPDataType format, const vec3ul &numItems) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_DATA << handle.i64 << format << numItems; }, false); return (OSPData)(int64)handle; } void MPIOffloadDevice::copyData( const OSPData source, OSPData destination, const vec3ul &destinationIndex) { const ObjectHandle sourceHandle = (const ObjectHandle &)source; ObjectHandle destinationHandle = (ObjectHandle &)destination; sendWork( [&](networking::WriteStream &writer) { writer << work::COPY_DATA << sourceHandle.i64 << destinationHandle.i64 << destinationIndex; }, false); } /////////////////////////////////////////////////////////////////////////// // Object + Parameter Lifetime Management ///////////////////////////////// /////////////////////////////////////////////////////////////////////////// void MPIOffloadDevice::setObjectParam( OSPObject object, const char *name, OSPDataType type, const void *mem) { ObjectHandle handle = (ObjectHandle &)object; switch (type) { // All OSP_OBJECT fall through the same style of setting param since it's // just a handle case OSP_DEVICE: case OSP_OBJECT: case OSP_CAMERA: case OSP_DATA: case OSP_FRAMEBUFFER: case OSP_FUTURE: case OSP_GEOMETRIC_MODEL: case OSP_GEOMETRY: case OSP_GROUP: case OSP_IMAGE_OPERATION: case OSP_INSTANCE: case OSP_LIGHT: case OSP_MATERIAL: case OSP_RENDERER: case OSP_TEXTURE: case OSP_TRANSFER_FUNCTION: case OSP_VOLUME: case OSP_VOLUMETRIC_MODEL: case OSP_WORLD: setParam(handle, name, mem, type); break; case OSP_BOOL: setParam(handle, name, mem, type); break; case OSP_STRING: { sendWork( [&](networking::WriteStream &writer) { writer << work::SET_PARAM << handle.i64 << name << type << (const char *)mem; }, false); break; } case OSP_CHAR: case OSP_BYTE: setParam(handle, name, mem, type); break; case OSP_VEC2UC: setParam(handle, name, mem, type); break; case OSP_VEC3UC: setParam(handle, name, mem, type); break; case OSP_VEC4UC: setParam(handle, name, mem, type); break; case OSP_SHORT: setParam(handle, name, mem, type); break; // Will note: looks like ushort is missing in ispcdevice case OSP_USHORT: setParam(handle, name, mem, type); break; case OSP_INT: setParam(handle, name, mem, type); break; case OSP_VEC2I: setParam(handle, name, mem, type); break; case OSP_VEC3I: setParam(handle, name, mem, type); break; case OSP_VEC4I: setParam(handle, name, mem, type); break; case OSP_UINT: setParam(handle, name, mem, type); break; case OSP_VEC2UI: setParam(handle, name, mem, type); break; case OSP_VEC3UI: setParam(handle, name, mem, type); break; case OSP_VEC4UI: setParam(handle, name, mem, type); break; case OSP_LONG: setParam(handle, name, mem, type); break; case OSP_VEC2L: setParam(handle, name, mem, type); break; case OSP_VEC3L: setParam(handle, name, mem, type); break; case OSP_VEC4L: setParam(handle, name, mem, type); break; case OSP_ULONG: setParam(handle, name, mem, type); break; case OSP_VEC2UL: setParam(handle, name, mem, type); break; case OSP_VEC3UL: setParam(handle, name, mem, type); break; case OSP_VEC4UL: setParam(handle, name, mem, type); break; case OSP_FLOAT: setParam(handle, name, mem, type); break; case OSP_VEC2F: setParam(handle, name, mem, type); break; case OSP_VEC3F: setParam(handle, name, mem, type); break; case OSP_VEC4F: setParam(handle, name, mem, type); break; case OSP_DOUBLE: setParam(handle, name, mem, type); break; case OSP_BOX1I: setParam(handle, name, mem, type); break; case OSP_BOX2I: setParam(handle, name, mem, type); break; case OSP_BOX3I: setParam(handle, name, mem, type); break; case OSP_BOX4I: setParam(handle, name, mem, type); break; case OSP_BOX1F: setParam(handle, name, mem, type); break; case OSP_BOX2F: setParam(handle, name, mem, type); break; case OSP_BOX3F: setParam(handle, name, mem, type); break; case OSP_BOX4F: setParam(handle, name, mem, type); break; case OSP_LINEAR2F: setParam(handle, name, mem, type); break; case OSP_LINEAR3F: setParam(handle, name, mem, type); break; case OSP_AFFINE2F: setParam(handle, name, mem, type); break; case OSP_AFFINE3F: setParam(handle, name, mem, type); break; default: throw std::runtime_error("Unrecognized param type!"); } } void MPIOffloadDevice::removeObjectParam(OSPObject object, const char *name) { const ObjectHandle handle = (const ObjectHandle &)object; sendWork( [&](networking::WriteStream &writer) { writer << work::REMOVE_PARAM << handle.i64 << name; }, false); } void MPIOffloadDevice::commit(OSPObject _object) { const ObjectHandle handle = (const ObjectHandle &)_object; auto d = sharedData.find(handle.i64); sendWork( [&](networking::WriteStream &writer) { writer << work::COMMIT << handle.i64 << (d != sharedData.end() ? uint32_t(1) : uint32_t(0)); if (d != sharedData.end()) { writer << d->second.type << d->second.numItems; sendDataWork(writer, d->second); } }, false); } void MPIOffloadDevice::release(OSPObject _object) { const ObjectHandle handle = (const ObjectHandle &)_object; appRefCount[handle.i64]--; // If the app still has references to the object there's no need to // cleanup or send a release command if (appRefCount[handle.i64] > 0) { return; } if (futures.find(handle.i64) != futures.end()) { wait((OSPFuture)_object, OSP_TASK_FINISHED); futures.erase(handle.i64); } sendWork( [&](networking::WriteStream &writer) { writer << work::RELEASE << handle.i64; }, false); // If this object was sharing a data view with the application we need to // make sure the data has been transferred before letting the application // potentially release the buffer. We only need to flush any early data // sends here, since if the data was small enough to inline in the command // buffer we aren't actually sharing the pointer with the app anymore auto d = sharedData.find(handle.i64); if (d != sharedData.end()) { // Make sure there's no pending send referencing this data if we're going // to delete it if (d->second.releaseHazard) { postStatusMsg(OSP_LOG_DEBUG) << "#osp.mpi.app: ospRelease: data reference hazard exists, " << " flushing pending sends"; fabric->flushBcastSends(); } d->second.release(); sharedData.erase(handle.i64); } } void MPIOffloadDevice::retain(OSPObject _obj) { const ObjectHandle handle = (const ObjectHandle &)_obj; appRefCount[handle.i64]++; } /////////////////////////////////////////////////////////////////////////// // FrameBuffer Manipulation /////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPFrameBuffer MPIOffloadDevice::frameBufferCreate( const vec2i &size, const OSPFrameBufferFormat format, const uint32 channels) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::CREATE_FRAMEBUFFER << handle.i64 << size << (uint32_t)format << channels; }, false); return (OSPFrameBuffer)(int64)handle; } OSPImageOperation MPIOffloadDevice::newImageOp(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_IMAGE_OPERATION << handle.i64 << type; }, false); return (OSPImageOperation)(int64)handle; } const void *MPIOffloadDevice::frameBufferMap( OSPFrameBuffer _fb, OSPFrameBufferChannel channel) { using namespace utility; RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("mapFramebuffer", "mpiOffloadDevice")); ObjectHandle handle = (ObjectHandle &)_fb; sendWork( [&](networking::WriteStream &writer) { writer << work::MAP_FRAMEBUFFER << handle.i64 << (uint32_t)channel; }, true); uint64_t nbytes = 0; auto bytesView = ArrayView(reinterpret_cast(&nbytes), sizeof(nbytes)); fabric->recv(bytesView, rootWorkerRank()); if (nbytes == 0) { throw std::runtime_error( "Attempt to map framebuffer channel which does not exist!"); } auto mapping = rkcommon::make_unique>(); mapping->resize(nbytes, 0); fabric->recv(*mapping, rootWorkerRank()); void *ptr = mapping->data(); framebufferMappings[handle.i64] = std::move(mapping); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); return ptr; } void MPIOffloadDevice::frameBufferUnmap(const void *, OSPFrameBuffer _fb) { ObjectHandle handle = (ObjectHandle &)_fb; auto fnd = framebufferMappings.find(handle.i64); if (fnd != framebufferMappings.end()) { framebufferMappings.erase(fnd); } } float MPIOffloadDevice::getVariance(OSPFrameBuffer _fb) { using namespace utility; ObjectHandle handle = (ObjectHandle &)_fb; sendWork( [&](networking::WriteStream &writer) { writer << work::GET_VARIANCE << handle.i64; }, true); float variance = 0; auto view = ArrayView( reinterpret_cast(&variance), sizeof(variance)); fabric->recv(view, rootWorkerRank()); return variance; } void MPIOffloadDevice::resetAccumulation(OSPFrameBuffer _fb) { ObjectHandle handle = (ObjectHandle &)_fb; sendWork( [&](networking::WriteStream &writer) { writer << work::RESET_ACCUMULATION << handle.i64; }, false); } /////////////////////////////////////////////////////////////////////////// // Frame Rendering //////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// OSPRenderer MPIOffloadDevice::newRenderer(const char *type) { ObjectHandle handle = allocateHandle(); sendWork( [&](networking::WriteStream &writer) { writer << work::NEW_RENDERER << handle.i64 << type; }, false); return (OSPRenderer)(int64)handle; } OSPFuture MPIOffloadDevice::renderFrame(OSPFrameBuffer _fb, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world) { ObjectHandle futureHandle = allocateHandle(); const ObjectHandle fbHandle = (ObjectHandle &)_fb; const ObjectHandle rendererHandle = (ObjectHandle &)_renderer; const ObjectHandle cameraHandle = (ObjectHandle &)_camera; const ObjectHandle worldHandle = (ObjectHandle &)_world; sendWork( [&](networking::WriteStream &writer) { writer << work::RENDER_FRAME << fbHandle << rendererHandle << cameraHandle << worldHandle << futureHandle; }, true); futures.insert(futureHandle.i64); return (OSPFuture)(int64)futureHandle; } int MPIOffloadDevice::isReady(OSPFuture _task, OSPSyncEvent event) { const ObjectHandle handle = (ObjectHandle &)_task; sendWork( [&](networking::WriteStream &writer) { writer << work::FUTURE_IS_READY << handle.i64 << (uint32_t)event; }, true); int result = 0; utility::ArrayView view( reinterpret_cast(&result), sizeof(result)); fabric->recv(view, rootWorkerRank()); return result; } void MPIOffloadDevice::wait(OSPFuture _task, OSPSyncEvent event) { const ObjectHandle handle = (ObjectHandle &)_task; sendWork( [&](networking::WriteStream &writer) { writer << work::FUTURE_WAIT << handle.i64 << (uint32_t)event; }, true); int result = 0; utility::ArrayView view( reinterpret_cast(&result), sizeof(result)); fabric->recv(view, rootWorkerRank()); } void MPIOffloadDevice::cancel(OSPFuture _task) { const ObjectHandle handle = (ObjectHandle &)_task; sendWork( [&](networking::WriteStream &writer) { writer << work::FUTURE_CANCEL << handle.i64; }, true); } float MPIOffloadDevice::getProgress(OSPFuture _task) { const ObjectHandle handle = (ObjectHandle &)_task; sendWork( [&](networking::WriteStream &writer) { writer << work::FUTURE_GET_PROGRESS << handle.i64; }, true); float result = 0; utility::ArrayView view( reinterpret_cast(&result), sizeof(result)); fabric->recv(view, rootWorkerRank()); return result; } float MPIOffloadDevice::getTaskDuration(OSPFuture _task) { const ObjectHandle handle = (ObjectHandle &)_task; sendWork( [&](networking::WriteStream &writer) { writer << work::FUTURE_GET_TASK_DURATION << handle.i64; }, true); float result = 0; utility::ArrayView view( reinterpret_cast(&result), sizeof(result)); fabric->recv(view, rootWorkerRank()); return result; } OSPPickResult MPIOffloadDevice::pick(OSPFrameBuffer fb, OSPRenderer renderer, OSPCamera camera, OSPWorld world, const vec2f &screenPos) { const ObjectHandle fbHandle = (ObjectHandle &)fb; const ObjectHandle rendererHandle = (ObjectHandle &)renderer; const ObjectHandle cameraHandle = (ObjectHandle &)camera; const ObjectHandle worldHandle = (ObjectHandle &)world; sendWork( [&](networking::WriteStream &writer) { writer << work::PICK << fbHandle << rendererHandle << cameraHandle << worldHandle << screenPos; }, true); OSPPickResult result; utility::ArrayView view( reinterpret_cast(&result), sizeof(OSPPickResult)); fabric->recv(view, rootWorkerRank()); return result; } void MPIOffloadDevice::sendDataWork( networking::WriteStream &writer, ApplicationData &appData) { const uint64_t compactSize = appData.size() * sizeOf(appData.type); if (compactSize < maxInlineDataSize) { // Small data gets inline'd into the command buffer writer << (uint32_t)1; if (appData.compact()) { writer.write(appData.data(0), compactSize); } else { auto *sizer = dynamic_cast(&writer); if (sizer) { sizer->write(nullptr, compactSize); } else { // Reserve space and copy the compact data into the buffer auto *bufWriter = dynamic_cast(&writer); appData.compactTo(bufWriter->reserve(compactSize)); } } } else { // For large data we start sending it early as an early data command writer << (uint32_t)0; // Only send the data if we're not doing the size calculation step if (!dynamic_cast(&writer)) { networking::BufferWriter dataTransferCmd; dataTransferCmd << work::DATA_TRANSFER << appData.type << appData.numItems; networking::BufferWriter header; header << dataTransferCmd.buffer->size(); fabric->sendBcast(header.buffer); fabric->sendBcast(dataTransferCmd.buffer); std::shared_ptr> dataView = nullptr; if (appData.compact()) { appData.releaseHazard = true; dataView = appData.sharedData; } else { // Allocate space to store the compact data and compact into it, // we send from this compacted buffer directly auto mem = std::make_shared>(compactSize); appData.compactTo(mem->begin()); dataView = mem; } fabric->sendBcast(dataView); } } } void MPIOffloadDevice::submitWork() { if (commandBuffer.available() == commandBuffer.capacity()) { postStatusMsg(OSP_LOG_ERROR) << "submit on empty command buffer attempted, should not happen!"; return; } auto view = commandBuffer.getWrittenView(); networking::BufferWriter header; header << view->size(); fabric->sendBcast(header.buffer); postStatusMsg(OSP_LOG_DEBUG) << "#osp.mpi.app: submitting buffer with " << nBufferedCommands << " commands, size: " << view->size(); // Make view of the valid set of commands in the buffer and submit them fabric->sendBcast(view); nBufferedCommands = 0; // Write new commands to a new buffer while the previous buffer is sent // out asynchronously commandBuffer = networking::FixedBufferWriter(commandBufferSize); } int MPIOffloadDevice::rootWorkerRank() const { // TODO: we may also want to support MPI intercomm setups w/ comm // accept/connect? return 1; } ObjectHandle MPIOffloadDevice::allocateHandle() { auto handle = ObjectHandle::allocateLocalHandle(); // Assign an app refcount of 1 for new handles appRefCount[handle.i64] = 1; return handle; } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/MPIOffloadDevice.h000066400000000000000000000157651464752671100242740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "api/Device.h" #include "common/ApplicationData.h" #include "common/MPICommon.h" #include "common/OSPWork.h" #include "rkcommon/utility/FixedArray.h" /*! \file MPIDevice.h Implements the "mpi" device for mpi rendering */ namespace ospray { namespace mpi { struct MPIOffloadDevice : public api::Device { MPIOffloadDevice() = default; ~MPIOffloadDevice() override; ///////////////////////////////////////////////////////////////////////// // Device Implementation //////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// void commit() override; int loadModule(const char *name) override; // Renderable Objects /////////////////////////////////////////////////// OSPLight newLight(const char *type) override; OSPCamera newCamera(const char *type) override; OSPGeometry newGeometry(const char *type) override; OSPVolume newVolume(const char *type) override; OSPGeometricModel newGeometricModel(OSPGeometry geom) override; OSPVolumetricModel newVolumetricModel(OSPVolume volume) override; // Model Meta-Data ////////////////////////////////////////////////////// OSPMaterial newMaterial(const char *material_type) override; OSPTransferFunction newTransferFunction(const char *type) override; OSPTexture newTexture(const char *type) override; // Instancing /////////////////////////////////////////////////////////// OSPGroup newGroup() override; OSPInstance newInstance(OSPGroup group) override; // Top-level Worlds ///////////////////////////////////////////////////// OSPWorld newWorld() override; box3f getBounds(OSPObject) override; // OSPRay Data Arrays /////////////////////////////////////////////////// OSPData newSharedData(const void *sharedData, OSPDataType, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback, const void *userPtr) override; OSPData newData(OSPDataType, const vec3ul &numItems) override; void copyData(const OSPData source, OSPData destination, const vec3ul &destinationIndex) override; // Object + Parameter Lifetime Management /////////////////////////////// void setObjectParam(OSPObject object, const char *name, OSPDataType type, const void *mem) override; void removeObjectParam(OSPObject object, const char *name) override; void commit(OSPObject object) override; void release(OSPObject _obj) override; void retain(OSPObject _obj) override; // FrameBuffer Manipulation ///////////////////////////////////////////// OSPFrameBuffer frameBufferCreate(const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) override; OSPImageOperation newImageOp(const char *type) override; const void *frameBufferMap( OSPFrameBuffer fb, const OSPFrameBufferChannel) override; void frameBufferUnmap(const void *mapped, OSPFrameBuffer fb) override; float getVariance(OSPFrameBuffer) override; void resetAccumulation(OSPFrameBuffer _fb) override; // Frame Rendering ////////////////////////////////////////////////////// OSPRenderer newRenderer(const char *type) override; OSPFuture renderFrame( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld) override; int isReady(OSPFuture, OSPSyncEvent) override; void wait(OSPFuture, OSPSyncEvent) override; void cancel(OSPFuture) override; float getProgress(OSPFuture) override; float getTaskDuration(OSPFuture) override; OSPPickResult pick( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, const vec2f &) override; private: void initializeDevice(); template void setParam(ObjectHandle obj, const char *param, const void *_val, const OSPDataType tag); /*! Send work will use the write command function to pack the command into the * command buffer. The writeCmd method is called twice, once to compute the * size being written and a second time to output the data to the writer. */ template void sendWork(const Fcn &writeCmd, bool submitImmediately); /*! Send data work should be called by data transfer writeCmd lambdas, to * insert inline data or start the data transfer for large data. If doing * a large data transfer the transfer is started on the second time the * lambda is called (i.e., when writing to the command buffer, not when * computing the size) */ void sendDataWork( rkcommon::networking::WriteStream &writer, ApplicationData &appData); void submitWork(); int rootWorkerRank() const; ObjectHandle allocateHandle(); /*! @{ read and write stream for the work commands */ std::unique_ptr fabric; using FrameBufferMapping = std::unique_ptr>; std::unordered_map framebufferMappings; // Refcount from the app side is managed by appRefCount std::unordered_map sharedData; std::unordered_set futures; /* We track app ref counts locally to reduce how many retain/release commands * we need to send to the worker nodes. This reduces communication costs for * apps using the C++ wrappers or some automatic refcounting wrapper that * calls retain/release a lot. */ std::unordered_map appRefCount; uint32_t maxCommandBufferEntries; uint32_t commandBufferSize; uint32_t maxInlineDataSize; size_t nBufferedCommands = 0; rkcommon::networking::FixedBufferWriter commandBuffer; bool initialized{false}; }; template void MPIOffloadDevice::sendWork(const Fcn &writeCmd, bool submitImmediately) { networking::WriteSizeCalculator sizeCalc; writeCmd(sizeCalc); // Note: curious if this ever happens, with a reasonable command buffer size // (anything >= 1MB) I don't think this should be an issue since commands are // quite small, and limiting the inline data size to be half the command // buffer size should avoid this. if (sizeCalc.writtenSize >= commandBuffer.capacity()) { throw std::runtime_error("Work size is too large for command buffer!"); } if (sizeCalc.writtenSize >= commandBuffer.available()) { submitWork(); } const size_t dbgWriteStart = commandBuffer.cursor; writeCmd(commandBuffer); postStatusMsg(OSP_LOG_DEBUG) << "#osp.mpi.app: buffering command: " << work::tagName(*(reinterpret_cast( commandBuffer.buffer->begin() + dbgWriteStart))); ++nBufferedCommands; if (submitImmediately || nBufferedCommands >= maxCommandBufferEntries) { submitWork(); } } template void MPIOffloadDevice::setParam(ObjectHandle obj, const char *param, const void *_val, const OSPDataType type) { const T &val = *(const T *)_val; sendWork( [&](rkcommon::networking::WriteStream &writer) { writer << work::SET_PARAM << obj.i64 << param << type << val; }, false); } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/MPIOffloadWorker.cpp000066400000000000000000000112771464752671100246730ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray/ospray.h" #include "rkcommon/platform.h" #include #include #include "MPIOffloadDevice.h" #include "common/Library.h" #include "common/MPIBcastFabric.h" #include "common/MPICommon.h" #include "common/OSPWork.h" // Only temporary location for these files anyways #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/getEnvVar.h" namespace ospray { namespace mpi { using namespace mpicommon; /*! it's up to the proper init routine to decide which processes call this function and which ones don't. This function will not return. This function takes the offload device that spawned the workers so that it can be cleaned up at exit properly, as the workers are started on commit and do not return back to the application code. ospShutdown is not called as it would unload the shared library with the code and object being used here, and when created explicitly the offload device would not be set as the current device or visible to be cleaned up. \internal We assume that mpi::worker and mpi::app have already been set up */ void runWorker(bool useMPIFabric, MPIOffloadDevice *offloadDevice) { // Nested scope to ensure all OSPRay objects/etc. are cleaned up // before we exit { // We need to remove the offload device so that we call loadLocalModule // directly to load the mpi_distributed module, instead of trying to go // through the offload device's loadModule implementation which would try to // send the command to some "workers". ospSetCurrentDevice(nullptr); auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } OSPDevice distribDevice = ospNewDevice("mpiDistributed"); ospDeviceSetParam( distribDevice, "worldCommunicator", OSP_VOID_PTR, &worker.comm); ospDeviceCommit(distribDevice); ospSetCurrentDevice(distribDevice); // Release our local reference to the device ospDeviceRelease(distribDevice); RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("start", "mpiOffloadWorker")); std::unique_ptr fabric; if (useMPIFabric) fabric = make_unique(mpicommon::world, 0); else throw std::runtime_error("Invalid non-MPI connection mode"); work::OSPState ospState; uint64_t commandSize = 0; utility::ArrayView cmdView( reinterpret_cast(&commandSize), sizeof(uint64_t)); std::shared_ptr> recvBuffer = std::make_shared>(); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::setThreadName("main")); bool exitWorker = false; while (!exitWorker) { fabric->recvBcast(cmdView); recvBuffer->resize(commandSize, 0); fabric->recvBcast(*recvBuffer); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::setCounter("CmdBufSize", commandSize); rkcommon::tracing::beginEvent( "processCommandBuffer", "mpiOffloadWorker"); }); // Read each command in the buffer and execute it networking::BufferReader reader(recvBuffer); while (!reader.end()) { work::TAG workTag = work::NONE; reader >> workTag; RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::setMarker( work::tagName(workTag), "mpiOffloadWorker")); if (workTag == work::FINALIZE) { exitWorker = true; } else { dispatchWork(workTag, ospState, reader, *fabric); } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::recordMemUse()); } RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::setCounter("CmdBufSize", 0); }); } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // The API no longer knows about the offload device and we won't return back // to the app to release it, so we need to free it now offloadDevice->refDec(); // Explicitly release the distributed device by unsetting the current // device, to avoid it attempting to be freed again on exit ospray::api::Device::current = nullptr; } MPI_CALL(Comm_free(&worker.comm)); // The offload device initialized MPI, so the distributed device will see // the "app" as having already initialized MPI and assume it should not call // finalize. So the worker loop must call MPI finalize here as if it was a // distributed app. MPI_CALL(Finalize()); std::exit(0); } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/OffloadModuleInit.cpp000066400000000000000000000012601464752671100251140ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // We don't want an instance of ObjectFactory static table in this library so // we set OBJECTFACTORY_IMPORT at the CMake build flag level for the module #include "common/ObjectFactory.h" #include "MPIOffloadDevice.h" #include "common/OSPCommon.h" extern "C" OSPError OSPRAY_DLLEXPORT ospray_module_init_mpi_offload( int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/) { using namespace ospray; auto status = moduleVersionCheck(versionMajor, versionMinor); if (status == OSP_NO_ERROR) { api::Device::registerType("mpiOffload"); } return status; } RenderKit-ospray-85af292/modules/mpi/ospray/common/000077500000000000000000000000001464752671100223355ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/ospray/common/ApplicationData.cpp000066400000000000000000000042141464752671100260770ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ApplicationData.h" #include #include #include "MPICommon.h" #include "common/OSPCommon.h" #include "rkcommon/utility/ArrayView.h" #include "rkcommon/utility/multidim_index_sequence.h" namespace ospray { namespace mpi { ApplicationData::ApplicationData(const void *appData, OSPDataType type, const vec3ul &nItems, const vec3l &bStride, OSPDeleterCallback freeFunction, const void *userData) : type(type), numItems(nItems), byteStride(bStride), freeFunction(freeFunction), userData(userData) { // compute strides if requested if (byteStride.x == 0) byteStride.x = sizeOf(type); if (byteStride.y == 0) byteStride.y = numItems.x * byteStride.x; if (byteStride.z == 0) byteStride.z = numItems.y * byteStride.y; sharedData = std::make_shared>( const_cast(reinterpret_cast(appData)), byteStride.z * numItems.z); } void ApplicationData::release() { if (freeFunction) freeFunction(userData, sharedData->data()); } bool ApplicationData::compact() const { // Compare the last offset using the byte stride vs. the last offset we'd have // if using a compact stride return sharedData->data() + sizeOf(type) * (size() - 1) == data(numItems - 1); } // Copy/Compact the data to the output dst passed. If the data is already // compact this is equivalent to a memcpy. void ApplicationData::compactTo(void *dst) const { if (compact()) { std::memcpy(dst, sharedData->data(), sharedData->size()); } else { // Probably ok with assuming sizeof(void*) == 8b ? I don't think we support // 32bit builds? const size_t typeSize = mpicommon::isManagedObject(type) ? sizeof(int64_t) : sizeOf(type); uint8_t *out = reinterpret_cast(dst); index_sequence_3D srcIndices(numItems); size_t destIdx = 0; for (auto srcIdx : srcIndices) { const uint8_t *src = data(srcIdx); std::memcpy(out + destIdx * typeSize, src, typeSize); ++destIdx; } } } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/ApplicationData.h000066400000000000000000000032711464752671100255460ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include "ospray/ospray.h" #include "rkcommon/math/vec.h" #include "rkcommon/utility/ArrayView.h" namespace ospray { namespace mpi { using namespace rkcommon; using namespace rkcommon::math; /* The data shared with the application. The workerType may not be the same * as the type of the data, because managed objects are unknown on the * application rank, and are represented just as uint64 handles. Thus the * local data objects see them as OSP_ULONG types, while the worker type * is the true managed object type */ struct ApplicationData { std::shared_ptr> sharedData; OSPDataType type = OSP_UNKNOWN; vec3ul numItems = 0; vec3l byteStride = 0; OSPDeleterCallback freeFunction = nullptr; const void *userData = nullptr; bool releaseHazard = false; ApplicationData() = default; ApplicationData(const void *sharedData, OSPDataType type, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback, const void *userData); void release(); uint8_t *data(const vec3ul &idx) const; size_t size() const; bool compact() const; // Copy/Compact the data to the output dst passed. If the data is already // compact this is equivalent to a memcpy. void compactTo(void *dst) const; }; inline uint8_t *ApplicationData::data(const vec3ul &idx) const { return sharedData->data() + idx.x * byteStride.x + idx.y * byteStride.y + idx.z * byteStride.z; } inline size_t ApplicationData::size() const { return numItems.long_product(); } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/DistributedWorld.cpp000066400000000000000000000140051464752671100263330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DistributedWorld.h" #include #include #include "ISPCDevice.h" #include "MPICommon.h" #include "Messaging.h" #include "common/Data.h" namespace ospray { namespace mpi { using namespace rkcommon; DistributedWorld::DistributedWorld(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device), mpiGroup(mpicommon::worker.dup()) { managedObjectType = OSP_WORLD; } DistributedWorld::~DistributedWorld() { MPI_Comm_free(&mpiGroup.comm); } box3f DistributedWorld::getBounds() const { box3f bounds; for (const auto &b : allRegions) { bounds.extend(b); } return bounds; } std::string DistributedWorld::toString() const { return "ospray::mpi::DistributedWorld"; } void DistributedWorld::commit() { World::commit(); allRegions.clear(); myRegions.clear(); myRegionIds.clear(); regionOwners.clear(); localRegions = getParamDataT("region"); if (localRegions) { std::copy(localRegions->begin(), localRegions->end(), std::back_inserter(myRegions)); } else { // Assume we're going to treat everything on this node as a one region, // either for data-parallel rendering or to switch to replicated // rendering box3f localBounds; if (getSh()->super.embreeSceneHandleGeometries) { box4f b; rtcGetSceneBounds( getSh()->super.embreeSceneHandleGeometries, (RTCBounds *)&b); localBounds.extend(box3f(vec3f(b.lower.x, b.lower.y, b.lower.z), vec3f(b.upper.x, b.upper.y, b.upper.z))); } #ifdef OSPRAY_ENABLE_VOLUMES if (getSh()->super.embreeSceneHandleVolumes) { box4f b; rtcGetSceneBounds( getSh()->super.embreeSceneHandleVolumes, (RTCBounds *)&b); localBounds.extend(box3f(vec3f(b.lower.x, b.lower.y, b.lower.z), vec3f(b.upper.x, b.upper.y, b.upper.z))); } #endif myRegions.push_back(localBounds); } // Figure out the unique regions on this node which we can send // to the others to build the distributed world std::sort( myRegions.begin(), myRegions.end(), [](const box3f &a, const box3f &b) { return a.lower < b.lower || (a.lower == b.lower && a.upper < b.upper); }); auto last = std::unique(myRegions.begin(), myRegions.end()); myRegions.erase(last, myRegions.end()); exchangeRegions(); if (regionScene) { rtcReleaseScene(regionScene); regionScene = nullptr; } if (allRegions.size() > 0) { // Setup the boxes geometry which we'll use to leverage Embree for // accurately determining region visibility Data *allRegionsData = new Data(getISPCDevice(), allRegions.data(), OSP_BOX3F, vec3ul(allRegions.size(), 1, 1), vec3l(0)); regionGeometry = new Boxes(getISPCDevice()); regionGeometry->setParam("box", (ManagedObject *)allRegionsData); regionGeometry->commit(); regionScene = rtcNewScene(getISPCDevice().getEmbreeDevice()); rtcAttachGeometry(regionScene, regionGeometry->getEmbreeGeometry()); rtcSetSceneFlags(regionScene, RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS); rtcCommitScene(regionScene); // Remove the extra local refs regionGeometry->refDec(); allRegionsData->refDec(); } getSh()->localRegions = myRegions.data(); getSh()->numLocalRegions = myRegions.size(); getSh()->numRegions = allRegions.size(); getSh()->regionScene = regionScene; } void DistributedWorld::exchangeRegions() { // Exchange regions between the ranks in world to find which other // ranks may be sharing a region with this one, and the other regions // to expect to be rendered for each tile for (int i = 0; i < mpiGroup.size; ++i) { if (i == mpiGroup.rank) { int nRegions = myRegions.size(); auto sizeBcast = mpicommon::bcast(&nRegions, 1, MPI_INT, i, mpiGroup.comm); int nBytes = nRegions * sizeof(box3f); auto regionBcast = mpicommon::bcast( myRegions.data(), nBytes, MPI_BYTE, i, mpiGroup.comm); for (const auto &b : myRegions) { auto fnd = std::find_if(allRegions.begin(), allRegions.end(), [&](const box3f &r) { return r == b; }); int id = -1; if (fnd == allRegions.end()) { id = allRegions.size(); allRegions.push_back(b); } else { id = std::distance(allRegions.begin(), fnd); } regionOwners[id].insert(i); myRegionIds.push_back(id); } // As we recv/send regions see if they're unique or not sizeBcast.wait(); regionBcast.wait(); } else { int nRegions = 0; mpicommon::bcast(&nRegions, 1, MPI_INT, i, mpiGroup.comm).wait(); std::vector recv; recv.resize(nRegions); int nBytes = nRegions * sizeof(box3f); mpicommon::bcast(recv.data(), nBytes, MPI_BYTE, i, mpiGroup.comm).wait(); for (const auto &b : recv) { auto fnd = std::find_if(allRegions.begin(), allRegions.end(), [&](const box3f &r) { return r == b; }); int id = -1; if (fnd == allRegions.end()) { id = allRegions.size(); allRegions.push_back(b); } else { id = std::distance(allRegions.begin(), fnd); } regionOwners[id].insert(i); } } } if (logLevel() >= OSP_LOG_DEBUG) { StatusMsgStream debugLog; for (int i = 0; i < mpiGroup.size; ++i) { if (i == mpiGroup.rank) { debugLog << "Rank " << mpiGroup.rank << ": All regions in world {\n"; for (const auto &b : allRegions) { debugLog << "\t" << b << ",\n"; } debugLog << "}\n\n"; debugLog << "Ownership Information: {\n"; for (const auto &r : regionOwners) { debugLog << "(" << r.first << ": ["; for (const auto &i : r.second) { debugLog << i << ", "; } debugLog << "])\n"; } debugLog << "\n"; } mpicommon::barrier(mpiGroup.comm).wait(); } } } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/DistributedWorld.h000066400000000000000000000035731464752671100260100ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "camera/Camera.h" #include "common/Embree.h" #include "common/MPICommon.h" #include "common/World.h" #include "geometry/Boxes.h" #include "rkcommon/math/box.h" // ispc shared #include "DistributedWorldShared.h" namespace ospray { namespace mpi { /* The distributed world provides the renderer with the view of the local * and distributed objects in the entire scene across the cluster. For * remote objects we only store their bounds and the ID of the rank which * owns them. A region is some "clip box" within the world, which contains * some mix of volumes and geometries to be rendered, with rays clipped * against the bounds of this box. */ struct DistributedWorld : public AddStructShared { DistributedWorld(api::ISPCDevice &device); ~DistributedWorld() override; box3f getBounds() const override; virtual std::string toString() const override; // commit synchronizes the distributed models between processes // so that ranks know how many tiles to expect for sort-last // compositing. virtual void commit() override; private: /* Perform the region bounds exchange among the ranks to build the * distributed view of the world */ void exchangeRegions(); // The communicator to use for collectives in the world mpicommon::Group mpiGroup; public: Ref> localRegions; std::vector myRegions; // The global list of unique regions across all nodes, (including this // one), sorted by region id. std::vector allRegions; std::vector myRegionIds; // The ranks which own each region std::unordered_map> regionOwners; Ref regionGeometry; RTCScene regionScene = nullptr; }; } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/DistributedWorldShared.h000066400000000000000000000010131464752671100271220ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/WorldShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct DistributedWorld { World super; box3f *localRegions; int numLocalRegions; int numRegions; RTCScene regionScene; #ifdef __cplusplus DistributedWorld() : localRegions(nullptr), numLocalRegions(0), numRegions(0), regionScene(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/mpi/ospray/common/DynamicLoadBalancer.cpp000066400000000000000000000226111464752671100266570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // This code is for DynamicLoadBalancer using the lifeline scheduling method #include "DynamicLoadBalancer.h" #include #include "Messaging.h" #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/ArrayView.h" namespace ospray { namespace mpi { using namespace mpicommon; DynamicLoadBalancer::DynamicLoadBalancer(ObjectHandle myId, int numTasks) : MessageHandler(myId) { activeTasks = numTasks; } void DynamicLoadBalancer::setActiveTasks(int numTasks) { std::lock_guard guard(termMutex); activeTasks = numTasks; } void DynamicLoadBalancer::updateActiveTasks(int term) { std::lock_guard guard(termMutex); activeTasks = activeTasks - term; } int DynamicLoadBalancer::getActiveTasks() { int updatedActiveTasks = 0; { std::lock_guard guard(termMutex); updatedActiveTasks = activeTasks; } return updatedActiveTasks; } void DynamicLoadBalancer::addWork(Work workItem) { std::lock_guard guard(workMutex); workQueue.push_back(workItem); } int DynamicLoadBalancer::getWorkSize() { int workSize; { std::lock_guard guard(workMutex); workSize = workQueue.size(); } return workSize; } Work DynamicLoadBalancer::getWorkItemFront() { Work workItem; std::lock_guard guard(workMutex); workItem.ntasks = workQueue[0].ntasks; workItem.offset = workQueue[0].offset; workItem.ownerRank = workQueue[0].ownerRank; workQueue.pop_front(); return workItem; } Work DynamicLoadBalancer::getWorkItemBack() { std::lock_guard guard(workMutex); Work workItem = workQueue.back(); workQueue.pop_back(); return workItem; } // This function takes the rank id and convert it into coords based on the base // we are using to represent the ranks std::vector DynamicLoadBalancer::rankToCoords( int rank, unsigned int base, unsigned int power) { std::vector result; if (rank >= pow(base, power)) { postStatusMsg(OSP_LOG_DEBUG) << "ERROR: Requested rank (" << rank << ") out of bond. Increase base or power.\n"; return result; } result.resize(power); int left = rank; for (unsigned int i = 0; i < power; i++) { result[i] = left / pow(base, power - i - 1); left -= result[i] * pow(base, power - i - 1); } return result; } // -------------------------------------------------------------------- // This function Takes coords of a rank and returns the rank id int DynamicLoadBalancer::coordsToRank(std::vector &coords, unsigned int base, unsigned int power, int numRanks) { if (coords.size() != power) { postStatusMsg(OSP_LOG_DEBUG) << "ERROR: Coords do not match the requested dimensions.\n"; return -1; } int result = 0; for (unsigned int i = 0; i < power; i++) result += coords[i] * pow(base, power - i - 1); if (numRanks <= result) result -= numRanks; return result; } // -------------------------------------------------------------------- // This function takes the rank coords and compute the lifelines IDs std::vector DynamicLoadBalancer::getLifelineID( std::vector &rankCoords, unsigned base, unsigned int power, int numRanks) { std::vector result; if (rankCoords.size() != power) { return result; } int myLifeLineID; std::vector lifelineCoords(power); // loop over rank lifelines for (unsigned int i = 0; i < power; i++) { // loop over coords of lifeline i for (unsigned int j = 0; j < power; j++) { if (i == j) { if (int(base - 1) <= rankCoords[i]) lifelineCoords[j] = 0; else lifelineCoords[j] = rankCoords[i] + 1; } else lifelineCoords[j] = rankCoords[j]; } myLifeLineID = coordsToRank(lifelineCoords, base, power, numRanks); if (-1 < myLifeLineID) result.push_back(myLifeLineID); } return result; } // This function compute the lifelines of the passed rank std::vector DynamicLoadBalancer::getMyLifeLines( int rank, int numRanks, unsigned int base, unsigned int power) { std::vector ranksCoords = rankToCoords(rank, base, power); std::vector lifelines = getLifelineID(ranksCoords, base, power, numRanks); return lifelines; } // -------------------------------------------------------------------- void DynamicLoadBalancer::incoming( const std::shared_ptr &message) { auto *header = (DynamicLBMessage *)message->data; if (header->type == TERMINATED) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("TERMINATED", "DynamicLB")); int numTerm = ((DynamicLBTerminatedMessage *)message->data)->numTerm; updateActiveTasks(numTerm); } // TERMINATED else if (header->type == NEED_WORK) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("NEED_WORK", "DynamicLB")); sendWork(header->senderRank); } // NEED_WORK else if (header->type == RECV_WORK) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("RECV_WORK", "DynamicLB")); auto *workMsg = (DynamicLBSendWorkMessage *)message->data; int numRecvWork = workMsg->numWorkItems; auto *workItems = (Work *)(message->data + sizeof(DynamicLBSendWorkMessage)); Work myWork; int workSize; for (int i = 0; i < numRecvWork; i++) { myWork.ntasks = workItems[i].ntasks; myWork.offset = workItems[i].offset; myWork.ownerRank = workItems[i].ownerRank; addWork(myWork); } workSize = getWorkSize(); if (1 < workSize) { sendMultiWork(); } } // RECV_WORK else { postStatusMsg(OSP_LOG_ERROR) << "Rank " << workerRank() << " Recv Unknown message\n"; } } // -------------------------------------------------------------------- void DynamicLoadBalancer::requestWork() { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("requestWork", "DynamicLB")); const int msgSize = sizeof(DynamicLBMessage); int base, power; base = 2; float p = log2(workerSize()); if (pow(base, p) - workerSize() == 0) power = p; else power = int(p) + 1; myLifelines = getMyLifeLines(workerRank(), workerSize(), base, power); for (size_t i = 0; i < myLifelines.size(); i++) { if (myLifelines[i] == (unsigned int)workerRank()) continue; else { auto msg = std::make_shared(msgSize); auto *header = reinterpret_cast(msg->data); header->type = NEED_WORK; header->senderRank = workerRank(); mpi::messaging::sendTo(myLifelines[i], myId, msg); } } } // -------------------------------------------------------------------- void DynamicLoadBalancer::sendMultiWork() { std::lock_guard lockThieves(thiefMutex); if (thiefIds.empty()) { return; } // Try to steal as much work as we can for the thieves, while leaving some for // this rank too std::vector stolenWork = getWorkItems([&](size_t workSize) { // +1 here to pretend that this rank is also a thief, so that we leave some // work for it in the queue const size_t workPerRank = workSize / (thiefIds.size() + 1); return workPerRank * thiefIds.size(); }); if (stolenWork.empty()) { return; } RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::setMarker("sendMultiWork", "DynamicLB")); // Each thief will be sent workPerRank work items const size_t workPerThief = stolenWork.size() / thiefIds.size(); size_t nextWorkSet = 0; for (auto &thief : thiefIds) { sendWorkToThief(thief, stolenWork.data() + nextWorkSet, workPerThief); nextWorkSet += workPerThief; } thiefIds.clear(); } // -------------------------------------------------------------------- void DynamicLoadBalancer::sendWork(int thiefID) { if (thiefID != -1 && thiefID != workerRank()) { std::vector stolenWork = getWorkItems([&](size_t workSize) { return workSize / 2; }); if (!stolenWork.empty()) { sendWorkToThief(thiefID, stolenWork.data(), stolenWork.size()); } else { std::lock_guard lockThieves(thiefMutex); thiefIds.insert(thiefID); } } } void DynamicLoadBalancer::sendWorkToThief( int thiefID, const Work *toSend, const size_t numWorkItems) { const int msgSize = sizeof(DynamicLBSendWorkMessage) + numWorkItems * sizeof(Work); auto msg = std::make_shared(msgSize); auto *header = reinterpret_cast(msg->data); header->type = RECV_WORK; header->senderRank = workerRank(); header->numWorkItems = numWorkItems; auto *workItems = reinterpret_cast(msg->data + sizeof(DynamicLBSendWorkMessage)); std::memcpy(workItems, toSend, numWorkItems * sizeof(Work)); mpi::messaging::sendTo(thiefID, myId, msg); } // -------------------------------------------------------------------- void DynamicLoadBalancer::sendTerm(int term) { const int msgSize = sizeof(DynamicLBTerminatedMessage); if (0 < term) { for (int i = 0; i < workerSize(); i++) if (i != workerRank()) { auto msg = std::make_shared(msgSize); auto *header = reinterpret_cast(msg->data); header->type = TERMINATED; header->senderRank = workerRank(); header->numTerm = term; mpi::messaging::sendTo(i, myId, msg); } } } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/DynamicLoadBalancer.h000066400000000000000000000076571464752671100263410ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #include "../common/Messaging.h" namespace ospray { namespace mpi { enum MSG { TERMINATED = 1000, NEED_WORK = 2000, VICTIM_NO_WORK = 3000, RECV_WORK = 4000 }; struct Work { int ntasks = 0; int offset = 0; int ownerRank = -1; }; struct DynamicLBMessage { int type; int senderRank; }; struct DynamicLBTerminatedMessage : DynamicLBMessage { int numTerm; }; struct DynamicLBSendWorkMessage : DynamicLBMessage { int numWorkItems; }; struct DynamicLoadBalancer : public mpi::messaging::MessageHandler { DynamicLoadBalancer(ObjectHandle myHandle, int numTasks); ~DynamicLoadBalancer() override = default; void setActiveTasks(int numTasks); void updateActiveTasks(int term); int getActiveTasks(); void addWork(Work workItem); int getWorkSize(); Work getWorkItemFront(); Work getWorkItemBack(); void requestWork(); void sendTerm(int term); void incoming(const std::shared_ptr &message) override; private: void sendWork(int thiefID); void sendMultiWork(); void sendWorkToThief( int thiefID, const Work *toSend, const size_t numWorkItems); /* Request a variable size number of work items based on the current size of * the workQueue. computeItemsRequested will be called after acquiring the * workMutex to compute the number of items to be returned. * computeItemsRequested should take a size_t and return a size_t representing * the number of items to return. If computeItemsRequested returns 0 or more * than workQueue.size(), an empty vector will be returned */ template std::vector getWorkItems(const Fn computeItemsRequested); /* The number of lifelines is determined using the following formula: base ^ L-1 < #ranks <= base ^ L, where L = number of lifelines for example 8 ranks can be represented as one of the following options: 1- base 2, L = 3: 2 ^ 2 < 8 <= 2 ^ 3 2- base 3, L = 2, 3 ^ 1 < 8 <= 3 ^ 2 3- base 4, L = 2, 4 ^ 1 < 8 <= 4 ^ 2 After choosing the base, rankToCoords creates a virtual cyclic graph, where ranks are the graph nodes, and the coords for each graph node(rank) is represented in that base. The function rankToCoords returns the coords for the passed rank depending on the base and power. For example if the base is 2 and power then the coords are represented in zeros and ones, the power identify the number of digits representing each rank coords, if the power is 3, then the coords are represented as 3 digits. The function coordsToRank, takes the rank coords and return the rank id. */ std::vector rankToCoords( int rank, unsigned int base, unsigned int power); int coordsToRank(std::vector &coords, unsigned int base, unsigned int power, int numRanks); std::vector getLifelineID(std::vector &coords, unsigned base, unsigned int power, int numRanks); std::vector getMyLifeLines( int myRank, int numRanks, unsigned int base, unsigned int power); std::vector myLifelines; std::set thiefIds; std::deque workQueue; int activeTasks; std::mutex termMutex; std::mutex workMutex; std::mutex thiefMutex; }; // struct DynamicLoadBalancer template std::vector DynamicLoadBalancer::getWorkItems( const Fn computeItemsRequested) { std::vector reqWorkItems; std::lock_guard guard(workMutex); const size_t numReqWorkItems = computeItemsRequested(workQueue.size()); if (numReqWorkItems == 0 || numReqWorkItems > workQueue.size()) { return reqWorkItems; } for (size_t i = 0; i < numReqWorkItems; i++) { Work workItem = workQueue.back(); workQueue.pop_back(); reqWorkItems.push_back(workItem); } return reqWorkItems; } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/Messaging.cpp000066400000000000000000000101501464752671100247530ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Messaging.h" #include #include #include "rkcommon/memory/DeletedUniquePtr.h" namespace ospray { namespace mpi { namespace messaging { using namespace mpicommon; using rkcommon::memory::DeletedUniquePtr; using rkcommon::memory::make_deleted_unique; // Internal maml message handler for all of OSPRay ////////////////////// struct ObjectMessageHandler : maml::MessageHandler { virtual ~ObjectMessageHandler() override; void registerMessageListener(int handleObjID, maml::MessageHandler *listener); void removeMessageListener(int handleObjID); void incoming(const std::shared_ptr &message) override; // Data members // // The communicator used for object messages, to avoid conflicting // with other communication mpicommon::Group group; private: std::mutex objectListenersMutex; std::unordered_map objectListeners; }; // Inlined ObjectMessageHandler definitions ///////////////////////////// ObjectMessageHandler::~ObjectMessageHandler() { if (group.comm != MPI_COMM_NULL) { MPI_Comm_free(&group.comm); } } inline void ObjectMessageHandler::registerMessageListener( int handleObjID, maml::MessageHandler *listener) { std::lock_guard lock(objectListenersMutex); if (objectListeners.find(handleObjID) != objectListeners.end()) postStatusMsg() << "WARNING: overwriting an existing listener!"; objectListeners[handleObjID] = listener; } inline void ObjectMessageHandler::removeMessageListener(int handleObjID) { std::lock_guard lock(objectListenersMutex); objectListeners.erase(handleObjID); } inline void ObjectMessageHandler::incoming( const std::shared_ptr &message) { std::lock_guard lock(objectListenersMutex); auto obj = objectListeners.find(message->tag); if (obj != objectListeners.end()) { obj->second->incoming(message); } else { postStatusMsg() << "WARNING: No destination for incoming message " << "with tag " << message->tag << ", size = " << message->size; } } // Singleton instance (hidden) and helper creation function ///////////// static DeletedUniquePtr handler = nullptr; static bool handlerValid = false; // MessageHandler definitions /////////////////////////////////////////// MessageHandler::MessageHandler(ObjectHandle handle) : myId(handle) { registerMessageListener(myId, this); } MessageHandler::~MessageHandler() { removeMessageListener(myId); } // ospray::mpi::messaging definitions /////////////////////////////////// void init(mpicommon::Group parentGroup) { if (handlerValid) throw std::runtime_error("Error: Object Messaging was already init"); Group group = parentGroup.dup(); handler = make_deleted_unique( [](ObjectMessageHandler *_handler) { handlerValid = false; delete _handler; }); handler->group = group; maml::registerHandlerFor(group.comm, handler.get()); handlerValid = true; } void shutdown() { maml::shutdown(); handler = nullptr; } void registerMessageListener(int handleObjID, maml::MessageHandler *listener) { if (!handlerValid) throw std::runtime_error("ObjectMessageHandler was not created!"); handler->registerMessageListener(handleObjID, listener); } void removeMessageListener(int handleObjID) { if (handlerValid) handler->removeMessageListener(handleObjID); } void enableAsyncMessaging() { // TODO WILL: Supporting thread serialized is a pain and I don't // think it's necessary // maml::start(); } void sendTo(int globalRank, ObjectHandle object, std::shared_ptr msg) { #ifdef DEBUG if (!handlerValid) throw std::runtime_error( "ObjMessageHandler must be created before" " sending object messages"); #endif msg->tag = object.objID(); maml::sendTo(handler->group.comm, globalRank, msg); } bool asyncMessagingEnabled() { return maml::isRunning(); } void disableAsyncMessaging() { // maml::stop(); } } // namespace messaging } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/Messaging.h000066400000000000000000000024611464752671100244260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/MPIBcastFabric.h" #include "common/MPICommon.h" #include "common/ObjectHandle.h" #include "maml/maml.h" namespace ospray { namespace mpi { namespace messaging { // message handling base //////////////////////////////////////////////// struct MessageHandler : public maml::MessageHandler { //! NOTE: automatically register/de-registers itself MessageHandler(ObjectHandle handle); virtual ~MessageHandler() override; protected: ObjectHandle myId; }; // async point messaging interface ////////////////////////////////////// /* Register the object message handler and dispatcher to run all object * fire & forget messaging on the specified group. The internal * communicator used will be a dup'd from this group, to avoid * conflicting with other messaging. */ void init(mpicommon::Group parentGroup); void shutdown(); void registerMessageListener(int handleObjID, maml::MessageHandler *listener); void removeMessageListener(int handleObjID); void enableAsyncMessaging(); bool asyncMessagingEnabled(); void sendTo(int globalRank, ObjectHandle object, std::shared_ptr msg); void disableAsyncMessaging(); } // namespace messaging } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/OSPWork.cpp000066400000000000000000000632751464752671100243620ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include "MPICommon.h" #include "OSPWork.h" #include "common/ObjectHandle.h" #include "rkcommon/array3D/for_each.h" #include "rkcommon/memory/RefCount.h" #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/AbstractArray.h" #include "rkcommon/utility/ArrayView.h" #include "rkcommon/utility/FixedArray.h" #include "rkcommon/utility/OwnedArray.h" namespace ospray { namespace mpi { namespace work { FrameBufferInfo::FrameBufferInfo( const vec2i &size, OSPFrameBufferFormat format, uint32_t channels) : size(size), format(format), channels(channels) {} size_t FrameBufferInfo::pixelSize(uint32_t channel) const { switch (channel) { case OSP_FB_COLOR: switch (format) { case OSP_FB_RGBA8: case OSP_FB_SRGBA: return sizeof(uint32_t); case OSP_FB_RGBA32F: return sizeof(vec4f); default: return 0; } case OSP_FB_DEPTH: return channels & OSP_FB_DEPTH ? sizeof(float) : 0; case OSP_FB_NORMAL: return channels & OSP_FB_NORMAL ? sizeof(vec3f) : 0; case OSP_FB_ALBEDO: return channels & OSP_FB_ALBEDO ? sizeof(vec3f) : 0; case OSP_FB_ID_PRIMITIVE: return channels & OSP_FB_ID_PRIMITIVE ? sizeof(uint32) : 0; case OSP_FB_ID_OBJECT: return channels & OSP_FB_ID_OBJECT ? sizeof(uint32) : 0; case OSP_FB_ID_INSTANCE: return channels & OSP_FB_ID_INSTANCE ? sizeof(uint32) : 0; default: return 0; } } size_t FrameBufferInfo::getNumPixels() const { return size.x * size.y; } void newRenderer( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewRenderer(type.c_str()); } void newWorld( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; cmdBuf >> handle; state.objects[handle] = ospNewWorld(); } void newGeometry( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewGeometry(type.c_str()); } void newGeometricModel( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; int64_t geomHandle = 0; cmdBuf >> handle >> geomHandle; state.objects[handle] = ospNewGeometricModel(state.getObject(geomHandle)); } void newVolume( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewVolume(type.c_str()); } void newVolumetricModel( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; int64_t volHandle = 0; cmdBuf >> handle >> volHandle; state.objects[handle] = ospNewVolumetricModel(state.getObject(volHandle)); } void newCamera( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewCamera(type.c_str()); } void newTransferFunction( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewTransferFunction(type.c_str()); } void newImageOperation( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewImageOperation(type.c_str()); } void newMaterial( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewMaterial(type.c_str()); } void newLight( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewLight(type.c_str()); } void dataTransfer(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { using namespace utility; OSPDataType type; vec3ul numItems = 0; cmdBuf >> type >> numItems; auto data = std::make_shared>( array3D::longProduct(numItems) * sizeOf(type)); fabric.recvBcast(*data); state.dataTransfers.push(data); } std::shared_ptr> retrieveData(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &, const OSPDataType type, const vec3ul numItems) { uint32_t dataInline = 0; cmdBuf >> dataInline; std::shared_ptr> outputData = nullptr; if (dataInline) { const uint64_t nbytes = numItems.x * numItems.y * numItems.z * sizeOf(type); outputData = cmdBuf.getView(nbytes); } else { // All large data is sent before the command buffer using it, and will be // in the state's data transfers list in order by the command referencing it outputData = state.dataTransfers.front(); state.dataTransfers.pop(); } // If the data type is managed we need to convert the handles back into // OSPObjects and increment the refcount because we're populating the data // object manually if (mpicommon::isManagedObject(type)) { for (size_t i = 0; i < array3D::longProduct(numItems); ++i) { uint8_t *addr = outputData->data() + i * sizeOf(type); int64_t *h = reinterpret_cast(addr); OSPObject *obj = reinterpret_cast(addr); *obj = state.objects[*h]; } } return outputData; } void newSharedData(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { using namespace utility; int64_t handle = 0; OSPDataType format = OSP_UNKNOWN; vec3ul numItems = 0; cmdBuf >> handle >> format >> numItems; auto data = retrieveData(state, cmdBuf, fabric, format, numItems); // gives an opportunity to pass off to internal device(s) auto forsubs = ospNewSharedData( data->data(), format, numItems.x, 0, numItems.y, 0, numItems.z, 0); auto subscopy = ospNewData(format, numItems.x, numItems.y, numItems.z); ospCopyData(forsubs, subscopy); ospCommit(subscopy); ospRelease(forsubs); state.objects[handle] = (OSPData)subscopy; } void newData( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; OSPDataType format; vec3ul numItems = 0; cmdBuf >> handle >> format >> numItems; state.objects[handle] = ospNewData(format, numItems.x, numItems.y, numItems.z); } void copyData( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t sourceHandle = 0; int64_t destinationHandle = 0; vec3ul destinationIndex = 0; cmdBuf >> sourceHandle >> destinationHandle >> destinationIndex; ospCopyData(state.getObject(sourceHandle), state.getObject(destinationHandle), destinationIndex.x, destinationIndex.y, destinationIndex.z); } void newTexture( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string type; cmdBuf >> handle >> type; state.objects[handle] = ospNewTexture(type.c_str()); } void newGroup( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; cmdBuf >> handle; state.objects[handle] = ospNewGroup(); } void newInstance( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; int64_t groupHandle = 0; cmdBuf >> handle >> groupHandle; state.objects[handle] = ospNewInstance(state.getObject(groupHandle)); } void commit(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t handle = 0; uint32_t isSharedData = 0; cmdBuf >> handle >> isSharedData; // If it's a data being committed, we need to retrieve the updated data if (isSharedData) { OSPDataType format = OSP_UNKNOWN; vec3ul numItems = 0; cmdBuf >> format >> numItems; auto data = retrieveData(state, cmdBuf, fabric, format, numItems); auto subscopy = (OSPData)state.objects[handle]; // gives an opportunity to pass off to internal device(s) auto forsubs = ospNewSharedData( data->data(), format, numItems.x, 0, numItems.y, 0, numItems.z, 0); ospCopyData(forsubs, subscopy); ospCommit(subscopy); ospRelease(forsubs); } ospCommit(state.objects[handle]); } void release( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; cmdBuf >> handle; ospRelease(state.objects[handle]); // Note: we keep the handle in the state.objects list as it may be referenced // by other objects in the scene as a parameter or data. // Check if we should release a framebuffer info for this object { auto fnd = state.framebuffers.find(handle); if (fnd != state.framebuffers.end()) { if (fnd->second->useCount() == 1) { state.framebuffers.erase(fnd); } else { fnd->second->refDec(); } } } } // namespace work void retain( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; cmdBuf >> handle; ospRetain(state.objects[handle]); // Mirror the app's ref count for framebuffer info { auto fnd = state.framebuffers.find(handle); if (fnd != state.framebuffers.end()) { fnd->second->refInc(); } } } void loadModule( OSPState &, networking::BufferReader &cmdBuf, networking::Fabric &) { std::string module; cmdBuf >> module; ospLoadModule(module.c_str()); } void createFramebuffer( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; vec2i size(0, 0); uint32_t format; uint32_t channels = 0; cmdBuf >> handle >> size >> format >> channels; state.objects[handle] = ospNewFrameBuffer(size.x, size.y, (OSPFrameBufferFormat)format, channels); Ref fbInfo = new FrameBufferInfo(size, (OSPFrameBufferFormat)format, channels); state.framebuffers[handle] = fbInfo; // Release the local scope ref (see open issue about Ref) fbInfo->refDec(); } void mapFramebuffer(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("mapFramebuffer", "mpiOffloadWorker")); // Map the channel and send the image back over the fabric int64_t handle = 0; uint32_t channel = 0; cmdBuf >> handle >> channel; if (mpicommon::worker.rank == 0) { using namespace utility; const FrameBufferInfo *fbInfo = state.framebuffers[handle].ptr; uint64_t nbytes = fbInfo->pixelSize(channel) * fbInfo->getNumPixels(); auto bytesView = std::make_shared>( reinterpret_cast(&nbytes), sizeof(nbytes)); fabric.send(bytesView, 0); if (nbytes != 0) { OSPFrameBuffer fb = state.getObject(handle); void *map = const_cast( ospMapFrameBuffer(fb, (OSPFrameBufferChannel)channel)); auto fbView = std::make_shared>( reinterpret_cast(map), nbytes); fabric.send(fbView, 0); ospUnmapFrameBuffer(map, fb); } } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } void getVariance(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { // Map the channel and send the image back over the fabric int64_t handle = 0; cmdBuf >> handle; if (mpicommon::worker.rank == 0) { using namespace utility; float variance = ospGetVariance(state.getObject(handle)); auto bytesView = std::make_shared>( reinterpret_cast(&variance), sizeof(variance)); fabric.send(bytesView, 0); } } void resetAccumulation( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; cmdBuf >> handle; ospResetAccumulation(state.getObject(handle)); } void renderFrame( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t futureHandle = 0; int64_t fbHandle = 0; int64_t rendererHandle = 0; int64_t cameraHandle = 0; int64_t worldHandle = 0; cmdBuf >> fbHandle >> rendererHandle >> cameraHandle >> worldHandle >> futureHandle; state.objects[futureHandle] = ospRenderFrame(state.getObject(fbHandle), state.getObject(rendererHandle), state.getObject(cameraHandle), state.getObject(worldHandle)); } template void setParam(networking::BufferReader &cmdBuf, OSPObject obj, const std::string ¶m, OSPDataType type) { T val; cmdBuf >> val; ospSetParam(obj, param.c_str(), type, &val); } void setParam( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string param; OSPDataType type; cmdBuf >> handle >> param >> type; // OSP_OBJECT use the same style of setting param since it's just a handle if (mpicommon::isManagedObject(type)) { int64_t val = 0; cmdBuf >> val; ospSetParam( state.objects[handle], param.c_str(), type, &state.objects[val]); } else { switch (type) { case OSP_STRING: { std::string val; cmdBuf >> val; ospSetParam(state.objects[handle], param.c_str(), type, val.c_str()); break; } case OSP_BOOL: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_CHAR: case OSP_BYTE: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC2UC: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC3UC: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC4UC: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_SHORT: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_USHORT: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_INT: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC2I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC3I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC4I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_UINT: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC2UI: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC3UI: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC4UI: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_LONG: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC2L: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC3L: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC4L: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_ULONG: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC2UL: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC3UL: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC4UL: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_FLOAT: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC2F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC3F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_VEC4F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_DOUBLE: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX1I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX2I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX3I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX4I: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX1F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX2F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX3F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_BOX4F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_LINEAR2F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_LINEAR3F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_AFFINE2F: setParam(cmdBuf, state.objects[handle], param, type); break; case OSP_AFFINE3F: setParam(cmdBuf, state.objects[handle], param, type); break; default: throw std::runtime_error("Unrecognized param type!"); } } } void removeParam( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; std::string param; cmdBuf >> handle >> param; ospRemoveParam(state.objects[handle], param.c_str()); } void pick(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t fbHandle = 0; int64_t rendererHandle = 0; int64_t cameraHandle = 0; int64_t worldHandle = 0; vec2f screenPos; cmdBuf >> fbHandle >> rendererHandle >> cameraHandle >> worldHandle >> screenPos; OSPPickResult res; ospPick(&res, state.getObject(fbHandle), state.getObject(rendererHandle), state.getObject(cameraHandle), state.getObject(worldHandle), screenPos.x, screenPos.y); if (mpicommon::worker.rank == 0) { using namespace utility; auto view = std::make_shared>( reinterpret_cast(&res), sizeof(OSPPickResult)); fabric.send(view, 0); } } void getBounds(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t handle = 0; cmdBuf >> handle; OSPBounds res = ospGetBounds(state.objects[handle]); if (mpicommon::worker.rank == 0) { using namespace utility; auto view = std::make_shared>( reinterpret_cast(&res), sizeof(OSPBounds)); fabric.send(view, 0); } } void futureIsReady(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t handle = 0; uint32_t event = 0; cmdBuf >> handle >> event; int ready = ospIsReady(state.getObject(handle), (OSPSyncEvent)event); if (mpicommon::worker.rank == 0) { using namespace utility; auto view = std::make_shared>( reinterpret_cast(&ready), sizeof(ready)); fabric.send(view, 0); } } void futureWait(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t handle = 0; uint32_t event = 0; cmdBuf >> handle >> event; ospWait(state.getObject(handle), (OSPSyncEvent)event); if (mpicommon::worker.rank == 0) { using namespace utility; auto view = std::make_shared>( reinterpret_cast(&event), sizeof(event)); fabric.send(view, 0); } } void futureCancel( OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &) { int64_t handle = 0; cmdBuf >> handle; ospCancel(state.getObject(handle)); } void futureGetProgress(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t handle = 0; cmdBuf >> handle; float progress = ospGetProgress(state.getObject(handle)); if (mpicommon::worker.rank == 0) { using namespace utility; auto view = std::make_shared>( reinterpret_cast(&progress), sizeof(progress)); fabric.send(view, 0); } } void futureGetTaskDuration(OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { int64_t handle = 0; cmdBuf >> handle; float progress = ospGetTaskDuration(state.getObject(handle)); if (mpicommon::worker.rank == 0) { using namespace utility; auto view = std::make_shared>( reinterpret_cast(&progress), sizeof(progress)); fabric.send(view, 0); } } void dispatchWork(TAG t, OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric) { switch (t) { case NEW_RENDERER: newRenderer(state, cmdBuf, fabric); break; case NEW_WORLD: newWorld(state, cmdBuf, fabric); break; case NEW_GEOMETRY: newGeometry(state, cmdBuf, fabric); break; case NEW_GEOMETRIC_MODEL: newGeometricModel(state, cmdBuf, fabric); break; case NEW_VOLUME: newVolume(state, cmdBuf, fabric); break; case NEW_VOLUMETRIC_MODEL: newVolumetricModel(state, cmdBuf, fabric); break; case NEW_CAMERA: newCamera(state, cmdBuf, fabric); break; case NEW_TRANSFER_FUNCTION: newTransferFunction(state, cmdBuf, fabric); break; case NEW_IMAGE_OPERATION: newImageOperation(state, cmdBuf, fabric); break; case NEW_MATERIAL: newMaterial(state, cmdBuf, fabric); break; case NEW_LIGHT: newLight(state, cmdBuf, fabric); break; case DATA_TRANSFER: dataTransfer(state, cmdBuf, fabric); break; case NEW_SHARED_DATA: newSharedData(state, cmdBuf, fabric); break; case NEW_DATA: newData(state, cmdBuf, fabric); break; case COPY_DATA: copyData(state, cmdBuf, fabric); break; case NEW_TEXTURE: newTexture(state, cmdBuf, fabric); break; case NEW_GROUP: newGroup(state, cmdBuf, fabric); break; case NEW_INSTANCE: newInstance(state, cmdBuf, fabric); break; case COMMIT: commit(state, cmdBuf, fabric); break; case RELEASE: release(state, cmdBuf, fabric); break; case RETAIN: retain(state, cmdBuf, fabric); break; case LOAD_MODULE: loadModule(state, cmdBuf, fabric); break; case CREATE_FRAMEBUFFER: createFramebuffer(state, cmdBuf, fabric); break; case MAP_FRAMEBUFFER: mapFramebuffer(state, cmdBuf, fabric); break; case GET_VARIANCE: getVariance(state, cmdBuf, fabric); break; case RESET_ACCUMULATION: resetAccumulation(state, cmdBuf, fabric); break; case RENDER_FRAME: renderFrame(state, cmdBuf, fabric); break; case SET_PARAM: setParam(state, cmdBuf, fabric); break; case REMOVE_PARAM: removeParam(state, cmdBuf, fabric); break; case PICK: pick(state, cmdBuf, fabric); break; case GET_BOUNDS: getBounds(state, cmdBuf, fabric); break; case FUTURE_IS_READY: futureIsReady(state, cmdBuf, fabric); break; case FUTURE_WAIT: futureWait(state, cmdBuf, fabric); break; case FUTURE_CANCEL: futureCancel(state, cmdBuf, fabric); break; case FUTURE_GET_PROGRESS: futureGetProgress(state, cmdBuf, fabric); break; case FUTURE_GET_TASK_DURATION: futureGetTaskDuration(state, cmdBuf, fabric); break; case NONE: default: throw std::runtime_error("Invalid work tag!"); } } const char *tagName(work::TAG t) { switch (t) { case NEW_RENDERER: return "NEW_RENDERER"; case NEW_WORLD: return "NEW_WORLD"; case NEW_GEOMETRY: return "NEW_GEOMETRY"; case NEW_GEOMETRIC_MODEL: return "NEW_GEOMETRIC_MODEL"; case NEW_VOLUME: return "NEW_VOLUME"; case NEW_VOLUMETRIC_MODEL: return "NEW_VOLUMETRIC_MODEL"; case NEW_CAMERA: return "NEW_CAMERA"; case NEW_TRANSFER_FUNCTION: return "NEW_TRANSFER_FUNCTION"; case NEW_IMAGE_OPERATION: return "NEW_IMAGE_OPERATION"; case NEW_MATERIAL: return "NEW_MATERIAL"; case NEW_LIGHT: return "NEW_LIGHT"; case DATA_TRANSFER: return "DATA_TRANSFER"; case NEW_SHARED_DATA: return "NEW_SHARED_DATA"; case NEW_DATA: return "NEW_DATA"; case COPY_DATA: return "COPY_DATA"; case NEW_TEXTURE: return "NEW_TEXTURE"; case NEW_GROUP: return "NEW_GROUP"; case NEW_INSTANCE: return "NEW_INSTANCE"; case COMMIT: return "COMMIT"; case RELEASE: return "RELEASE"; case RETAIN: return "RETAIN"; case LOAD_MODULE: return "LOAD_MODULE"; case CREATE_FRAMEBUFFER: return "CREATE_FRAMEBUFFER"; case MAP_FRAMEBUFFER: return "MAP_FRAMEBUFFER"; case GET_VARIANCE: return "GET_VARIANCE"; case RESET_ACCUMULATION: return "RESET_ACCUMULATION"; case RENDER_FRAME: return "RENDER_FRAME"; case SET_PARAM: return "SET_PARAM"; case REMOVE_PARAM: return "REMOVE_PARAM"; case PICK: return "PICK"; case GET_BOUNDS: return "GET_BOUNDS"; case FUTURE_IS_READY: return "FUTURE_IS_READY"; case FUTURE_WAIT: return "FUTURE_WAIT"; case FUTURE_CANCEL: return "FUTURE_CANCEL"; case FUTURE_GET_PROGRESS: return "FUTURE_GET_PROGRESS"; case FUTURE_GET_TASK_DURATION: return "FUTURE_GET_TASK_DURATION"; case FINALIZE: return "FINALIZE"; case NONE: default: return "NONE/UNKNOWN/INVALID"; } } } // namespace work } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/common/OSPWork.h000066400000000000000000000042531464752671100240160ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #include #include "MPICommon.h" #include "common/ObjectHandle.h" #include "rkcommon/memory/RefCount.h" #include "rkcommon/networking/DataStreaming.h" #include "rkcommon/networking/Fabric.h" #include "rkcommon/platform.h" #include "rkcommon/utility/ArrayView.h" #include "rkcommon/utility/FixedArray.h" namespace ospray { namespace mpi { namespace work { using namespace rkcommon; enum TAG { NONE, NEW_RENDERER, NEW_WORLD, NEW_GEOMETRY, NEW_GEOMETRIC_MODEL, NEW_VOLUME, NEW_VOLUMETRIC_MODEL, NEW_CAMERA, NEW_TRANSFER_FUNCTION, NEW_IMAGE_OPERATION, NEW_MATERIAL, NEW_LIGHT, DATA_TRANSFER, NEW_SHARED_DATA, NEW_DATA, COPY_DATA, NEW_TEXTURE, NEW_GROUP, NEW_INSTANCE, COMMIT, RELEASE, RETAIN, LOAD_MODULE, CREATE_FRAMEBUFFER, MAP_FRAMEBUFFER, GET_VARIANCE, RESET_ACCUMULATION, RENDER_FRAME, SET_PARAM, REMOVE_PARAM, PICK, GET_BOUNDS, FUTURE_IS_READY, FUTURE_WAIT, FUTURE_CANCEL, FUTURE_GET_PROGRESS, FUTURE_GET_TASK_DURATION, FINALIZE }; struct FrameBufferInfo : rkcommon::memory::RefCountedObject { vec2i size = vec2i(0, 0); OSPFrameBufferFormat format = OSP_FB_NONE; uint32_t channels = 0; FrameBufferInfo() = default; FrameBufferInfo( const vec2i &size, OSPFrameBufferFormat format, uint32_t channels); size_t pixelSize(uint32_t channel) const; size_t getNumPixels() const; }; struct OSPState { std::unordered_map objects; std::unordered_map> framebuffers; // Large data which is transferred separately from the command buffer, // prior to sending the command buffer std::queue>> dataTransfers; template T getObject(int64_t handle) { return reinterpret_cast(objects[handle]); } }; void dispatchWork(TAG t, OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &fabric); const char *tagName(work::TAG t); } // namespace work } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/fb/000077500000000000000000000000001464752671100214345ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/ospray/fb/DistributedFrameBuffer.cpp000066400000000000000000000654661464752671100265500ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DistributedFrameBuffer.h" #include "DistributedFrameBuffer_TileMessages.h" #include "ISPCDevice.h" #include "TileOperation.h" #include "fb/FrameBufferView.h" #include "rkcommon/tracing/Tracing.h" #ifndef OSPRAY_TARGET_SYCL #include "fb/DistributedFrameBuffer_ispc.h" #endif #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/tasking/schedule.h" #include "api/Device.h" #include "common/Collectives.h" #include "common/MPICommon.h" #include #include #include using namespace std::chrono; namespace ospray { // Helper types ///////////////////////////////////////////////////////////// using DFB = DistributedFrameBuffer; // DistributedTileError definitions ///////////////////////////////////////// DistributedTileError::DistributedTileError( api::ISPCDevice &device, const vec2i &numTiles, mpicommon::Group group) : TaskError(device.getDRTDevice(), numTiles), group(group) {} void DistributedTileError::sync() { if (!taskErrorBuffer || taskErrorBuffer->size() == 0) { return; } // TODO: USM thrashing possible issue mpicommon::bcast(taskErrorBuffer->data(), taskErrorBuffer->size(), MPI_FLOAT, 0, group.comm) .wait(); } // DistributedFrameBuffer definitions /////////////////////////////////////// DFB::DistributedFrameBuffer(api::ISPCDevice &device, const vec2i &numPixels, ObjectHandle myId, ColorBufferFormat colorBufferFormat, const uint32 channels) // TODO WILL: The DFB should use a separate identifier than myID // since large scenes can push this ID beyond the max value we can use // for MPI Tag (i.e., Moana). The IDs for the message handler should not // be set from the object handle but pulled from some other ID pool // specific to those objects using the messaging layer : MessageHandler(myId), FrameBuffer(device, numPixels, colorBufferFormat, channels, FFO_NONE), mpiGroup(mpicommon::worker.dup()), totalTiles(divRoundUp(size, vec2i(TILE_SIZE))), numRenderTasks((totalTiles * TILE_SIZE) / getRenderTaskSize()), tileErrorRegion( device, hasVarianceBuffer ? totalTiles : vec2i(0), mpiGroup), localFBonMaster(nullptr), frameIsActive(false), frameIsDone(false) { if (mpicommon::IamTheMaster() && colorBufferFormat != OSP_FB_NONE) { localFBonMaster = rkcommon::make_unique(device, numPixels, colorBufferFormat, channels & ~(OSP_FB_ACCUM | OSP_FB_VARIANCE)); } } DFB::~DistributedFrameBuffer() { MPI_Comm_free(&mpiGroup.comm); } void DFB::commit() { FrameBuffer::commit(); if (localFBonMaster) { // We need image operations to be added to inner local FB as well, the local // FB possess complete image and is responsible for post-processing // execution if (hasParam("imageOperation")) localFBonMaster->setParam("imageOperation", static_cast(getParamObject("imageOperation"))); localFBonMaster->commit(); } } mpicommon::Group DFB::getMPIGroup() { return mpiGroup; } void DFB::startNewFrame(const float errorThreshold) { { std::lock_guard lock(finalTileBufferMutex); nextTileWrite = 0; tileBufferOffsets.clear(); } if (colorBufferFormat != OSP_FB_NONE) { RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::beginEvent( "startFrame::reserveTileGatherBuf", "DFB")); // Allocate a conservative upper bound of space which we'd need to // store the compressed tiles const size_t uncompressedSize = masterMsgSize( hasDepthBuffer, hasNormalBuffer, hasAlbedoBuffer, hasIDBuf()); const size_t compressedSize = snappy::MaxCompressedLength(uncompressedSize); tileGatherBuffer.resize(myTiles.size() * compressedSize, 0); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("startFrame::initTilesInfo", "DFB")); { std::lock_guard fbLock(mutex); std::lock_guard numTilesLock(numTilesMutex); if (frameIsActive) { throw std::runtime_error( "Attempt to start frame on already started frame!"); } frameProgress = 0.f; FrameBuffer::beginFrame(); lastProgressReport = std::chrono::steady_clock::now(); renderingProgressTiles = 0; tileErrorRegion.sync(); if (colorBufferFormat == OSP_FB_NONE) { std::lock_guard errsLock(tileErrorsMutex); tileIDs.clear(); tileErrors.clear(); tileIDs.reserve(myTiles.size()); tileErrors.reserve(myTiles.size()); } // May be worth parallelizing if we have tile ops where // new frame becomes expensive for (auto &tile : myTiles) tile->newFrame(); for (auto &l : layers) { l->beginFrame(); } if (mpicommon::IamTheMaster()) { numTilesExpected.resize(mpicommon::workerSize(), 0); std::fill(numTilesExpected.begin(), numTilesExpected.end(), 0); } globalTilesCompletedThisFrame = 0; numTilesCompletedThisFrame = 0; for (uint32_t t = 0; t < getGlobalTotalTiles(); t++) { if (doAccumulation() && tileError(t) <= errorThreshold) { if (allTiles[t]->mine()) { numTilesCompletedThisFrame++; } } else if (mpicommon::IamTheMaster()) { ++numTilesExpected[allTiles[t]->ownerID]; } } frameIsDone = false; frameIsActive = true; } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); mpicommon::barrier(mpiGroup.comm).wait(); if (isFrameComplete(0)) closeCurrentFrame(); } bool DFB::isFrameComplete(const size_t numTiles) { std::lock_guard numTilesLock(numTilesMutex); numTilesCompletedThisFrame += numTiles; renderingProgressTiles += numTiles; auto now = std::chrono::steady_clock::now(); auto timeSinceUpdate = duration_cast(now - lastProgressReport); if (timeSinceUpdate.count() >= 1000) { auto msg = std::make_shared(sizeof(ProgressMessage)); ProgressMessage *msgData = reinterpret_cast(msg->data); msgData->command = PROGRESS_MESSAGE; msgData->numCompleted = renderingProgressTiles; msgData->frameID = getSh()->frameID; mpi::messaging::sendTo(mpicommon::masterRank(), myId, msg); renderingProgressTiles = 0; lastProgressReport = now; } return numTilesCompletedThisFrame == myTiles.size(); } size_t DFB::ownerIDFromTileID(size_t tileID) const { return tileID % mpicommon::workerSize(); } void DistributedFrameBuffer::setSparseFBLayerCount(size_t numLayers) { // Layer 0 is the base owned tiles layer created by the DFB, so we'll always // have numLayers + 1 layers layers.resize(numLayers + 1, nullptr); // The sparse layers don't do accumulation and variance calculation because // this needs data from all ranks rendering a given tile const int channelFlags = getChannelFlags() & ~(OSP_FB_ACCUM | OSP_FB_VARIANCE); // Allocate any new layers that have been added to the DFB for (size_t i = 1; i < layers.size(); ++i) { if (!layers[i]) { layers[i] = rkcommon::make_unique( getISPCDevice(), size, getColorBufferFormat(), channelFlags); } } for (auto &l : layers) l->getSh()->super.targetFrames = getSh()->targetFrames; } size_t DistributedFrameBuffer::getSparseLayerCount() const { return layers.size(); } SparseFrameBuffer *DistributedFrameBuffer::getSparseFBLayer(size_t l) { return layers[l].get(); } void DFB::cancelFrame() { FrameBuffer::cancelFrame(); // Propagate the frame cancellation to the sparse fb layers as well for (auto &l : layers) { l->cancelFrame(); } } float DFB::getCurrentProgress() const { if (stagesCompleted == OSP_FRAME_FINISHED) { return 1.f; } return frameProgress; } void DFB::createTiles() { allTiles.clear(); myTiles.clear(); const vec2i totalTiles = divRoundUp(size, vec2i(TILE_SIZE)); std::vector myTileIDs; for (int y = 0; y < totalTiles.y; ++y) { for (int x = 0; x < totalTiles.x; ++x) { size_t tileID = size_t(x) + size_t(totalTiles.x) * size_t(y); const size_t ownerID = ownerIDFromTileID(tileID); const vec2i tileStart(x * TILE_SIZE, y * TILE_SIZE); if (ownerID == size_t(mpicommon::workerRank())) { auto td = tileOperation->makeTile(this, tileStart, tileID, ownerID); myTiles.push_back(td.get()); allTiles.push_back(std::move(td)); myTileIDs.push_back(tileID); } else { allTiles.push_back(make_unique(tileStart, tileID, ownerID)); } } } // Allocate the sparse fb for the tiles we own uint32 channels = OSP_FB_DEPTH; // Accum and variance are not done in the sparse FB for the DFB if (hasNormalBuf()) { channels |= OSP_FB_NORMAL; } if (hasAlbedoBuf()) { channels |= OSP_FB_ALBEDO; } if (layers.empty()) { layers.push_back(rkcommon::make_unique( getISPCDevice(), size, OSP_FB_NONE, channels, myTileIDs)); } else { layers[0]->setTiles(myTileIDs); layers[0]->clear(); } layers[0]->commit(); } void DFB::setTileOperation( std::shared_ptr tileOp, const Renderer *renderer) { // TODO WILL: Is this really the best way to avoid re-attaching all the // tiles each frame? Maybe take a string identifying it and find the // obj. creation method instead? if (tileOperation && lastRenderer == renderer) return; tileOperation = tileOp; tileOperation->attach(this); lastRenderer = renderer; createTiles(); } std::shared_ptr DFB::getTileOperation() { return tileOperation; } const Renderer *DFB::getLastRenderer() const { return lastRenderer; } const void *DFB::mapBuffer(OSPFrameBufferChannel channel) { if (!localFBonMaster) { throw std::runtime_error( "#osp:mpi:dfb: tried to 'ospMap()' a frame " "buffer that doesn't have a host-side correspondence"); } return localFBonMaster->mapBuffer(channel); } void DFB::unmap(const void *mappedMem) { if (!localFBonMaster) { throw std::runtime_error( "#osp:mpi:dfb: tried to 'ospUnmap()' a frame " "buffer that doesn't have a host-side color " "buffer"); } localFBonMaster->unmap(mappedMem); } void DFB::waitUntilFinished() { using namespace mpicommon; using namespace std::chrono; RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("waitUntilDoneCond", "DFB")); std::unique_lock lock(mutex); frameDoneCond.wait(lock, [&] { return frameIsDone; }); frameIsActive = false; RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); setCompletedEvent(OSP_WORLD_RENDERED); if (frameCancelled()) { return; } RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("finalGather", "DFB")); if (colorBufferFormat != OSP_FB_NONE) { gatherFinalTiles(); } else if (hasVarianceBuf()) { gatherFinalErrors(); } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } void DFB::processMessage(WriteTileMessage *msg) { ispc::Tile tile; unpackWriteTileMessage( msg, tile, hasNormalBuffer || hasAlbedoBuffer || hasIDBuf()); auto *tileDesc = this->getTileDescFor(tile.region.lower); LiveTileOperation *td = (LiveTileOperation *)tileDesc; td->process(tile); } void DistributedFrameBuffer::processMessage(MasterTileMessage_FB *msg) { if (hasVarianceBuffer) { const vec2i tileID = msg->coords / TILE_SIZE; if (msg->error < (float)inf) { tileErrorRegion.update(tileID, msg->error); } } vec2i numPixels = getNumPixels(); MasterTileMessage_FB_Depth *depth = nullptr; if (hasDepthBuffer && msg->command & MASTER_TILE_HAS_DEPTH) { depth = reinterpret_cast(msg); } MasterTileMessage_FB_Depth_Aux *aux = nullptr; if (msg->command & MASTER_TILE_HAS_AUX) aux = reinterpret_cast(msg); uint32 *pidBuf = nullptr; uint32 *gidBuf = nullptr; uint32 *iidBuf = nullptr; // TODO: Make the rest of the tile more dynamically sized and use a buffer // cursor style to get the pointers to the individual tile components if (msg->command & MASTER_TILE_HAS_ID) { // The ID buffer data comes at the end of the tile message uint8 *data = reinterpret_cast(msg); if (!aux) { if (depth) { data += sizeof(MasterTileMessage_FB_Depth); } else { data += sizeof(MasterTileMessage_FB); } } else { data += sizeof(MasterTileMessage_FB_Depth_Aux); } // All IDs are sent if any were requested, however we need to write only the // ones that actually exist in the local FB since it doesn't allocate // buffers for the non-existent channels if (hasPrimitiveIDBuffer) { pidBuf = reinterpret_cast(data); } if (hasObjectIDBuffer) { gidBuf = reinterpret_cast( data + sizeof(uint32) * TILE_SIZE * TILE_SIZE); } if (hasInstanceIDBuffer) { iidBuf = reinterpret_cast( data + 2 * sizeof(uint32) * TILE_SIZE * TILE_SIZE); } } // TODO: Here we're just accessing the local fb on the host, but have it // allocated in USM. Will work, but maybe wasting some USM space? vec4f *color = (localFBonMaster->colorBuffer) ? localFBonMaster->colorBuffer->data() : nullptr; for (int iy = 0; iy < TILE_SIZE; iy++) { int iiy = iy + msg->coords.y; if (iiy >= numPixels.y) { continue; } for (int ix = 0; ix < TILE_SIZE; ix++) { int iix = ix + msg->coords.x; if (iix >= numPixels.x) { continue; } if (color) { color[iix + iiy * numPixels.x] = msg->color[ix + iy * TILE_SIZE]; } if (depth) { (*localFBonMaster->depthBuffer)[iix + iiy * numPixels.x] = depth->depth[ix + iy * TILE_SIZE]; } if (aux) { if (hasNormalBuffer) (*localFBonMaster->normalBuffer)[iix + iiy * numPixels.x] = aux->normal[ix + iy * TILE_SIZE]; if (hasAlbedoBuffer) (*localFBonMaster->albedoBuffer)[iix + iiy * numPixels.x] = aux->albedo[ix + iy * TILE_SIZE]; } if (pidBuf) { (*localFBonMaster->primitiveIDBuffer)[iix + iiy * numPixels.x] = pidBuf[ix + iy * TILE_SIZE]; } if (gidBuf) { (*localFBonMaster->objectIDBuffer)[iix + iiy * numPixels.x] = gidBuf[ix + iy * TILE_SIZE]; } if (iidBuf) { (*localFBonMaster->instanceIDBuffer)[iix + iiy * numPixels.x] = iidBuf[ix + iy * TILE_SIZE]; } } } } bool DFB::hasIDBuf() const { // ID buffers are only needed on the first frame when rendering with // accumulation return getFrameID() == 0 && (hasPrimitiveIDBuffer || hasObjectIDBuffer || hasInstanceIDBuffer); } void DFB::tileIsFinished(LiveTileOperation *tile) { // Write the final colors into the color buffer // normalize and write final color, and compute error if (colorBufferFormat != OSP_FB_NONE) DFB_writeTile((ispc::VaryingTile *)&tile->finished, &tile->color); auto msg = [&] { MasterTileMessageBuilder msg(hasDepthBuffer, hasNormalBuffer, hasAlbedoBuffer, hasIDBuf(), tile->begin, tile->error); msg.setColor(tile->color); msg.setDepth(tile->finished.z); msg.setNormal((vec3f *)tile->finished.nx); msg.setAlbedo((vec3f *)tile->finished.ar); msg.setPrimitiveID(tile->finished.pid); msg.setObjectID(tile->finished.gid); msg.setInstanceID(tile->finished.iid); return msg; }; // TODO still send normal & albedo? if (colorBufferFormat == OSP_FB_NONE) { std::lock_guard lock(tileErrorsMutex); tileIDs.push_back(tile->begin / TILE_SIZE); tileErrors.push_back(tile->error); } else { auto tileMsg = msg().message; size_t compressedSize = snappy::MaxCompressedLength(tileMsg->size); std::vector compressedTile(compressedSize, 0); snappy::RawCompress(reinterpret_cast(tileMsg->data), tileMsg->size, compressedTile.data(), &compressedSize); uint32_t tileOffset; { std::lock_guard lock(finalTileBufferMutex); tileOffset = nextTileWrite; tileBufferOffsets.push_back(tileOffset); nextTileWrite += compressedSize; } std::memcpy( &tileGatherBuffer[tileOffset], compressedTile.data(), compressedSize); } if (isFrameComplete(1)) { closeCurrentFrame(); } } void DFB::updateProgress(ProgressMessage *msg) { globalTilesCompletedThisFrame += msg->numCompleted; frameProgress = globalTilesCompletedThisFrame / (float)getGlobalTotalTiles(); } size_t DFB::numMyTiles() const { return myTiles.size(); } TileDesc *DFB::getTileDescFor(const vec2i &coords) const { return allTiles[getTileIDof(coords)].get(); } size_t DFB::getTileIDof(const vec2i &c) const { return (c.x / TILE_SIZE) + (c.y / TILE_SIZE) * totalTiles.x; } std::string DFB::toString() const { return "ospray::DFB"; } void DFB::incoming(const std::shared_ptr &message) { auto *msg = (TileMessage *)message->data; /* if (msg->command & CANCEL_RENDERING) { std::cout << "Rank " << mpicommon::globalRank() << " rendering was cancelled\n" << std::flush; cancelRendering = true; // TODO: We need to mark the frame as done as well here, in case // this rank had already finished the frame and was waiting. // We also then need to know to discard any additional tile messages // we receive until we start the next frame. closeCurrentFrame(); return; } */ // Any delayed progress messages are about the previous frame anyways, // so we don't care. if (!frameIsActive && !(msg->command & PROGRESS_MESSAGE)) { std::lock_guard lock(mutex); if (!frameIsActive) { throw std::runtime_error( "Somehow received a tile message when frame inactive!?"); } } scheduleProcessing(message); } void DFB::scheduleProcessing(const std::shared_ptr &message) { tasking::schedule([=]() { auto *msg = (TileMessage *)message->data; if (msg->command & MASTER_WRITE_TILE) { throw std::runtime_error("#dfb: master msg should not be scheduled!"); } else if (msg->command & WORKER_WRITE_TILE) { this->processMessage((WriteTileMessage *)msg); } else if (msg->command & PROGRESS_MESSAGE) { updateProgress((ProgressMessage *)msg); } else { throw std::runtime_error("#dfb: unknown tile type processed!"); } }); } void DFB::gatherFinalTiles() { using namespace mpicommon; using namespace std::chrono; RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("preGatherComputeStart", "DFB")); const size_t tileSize = masterMsgSize( hasDepthBuffer, hasNormalBuffer, hasAlbedoBuffer, hasIDBuf()); const int totalTilesExpected = std::accumulate(numTilesExpected.begin(), numTilesExpected.end(), 0); std::vector processOffsets; if (IamTheMaster()) { processOffsets.resize(workerSize(), 0); int recvOffset = 0; for (int i = 0; i < workerSize(); ++i) { processOffsets[i] = recvOffset; recvOffset += numTilesExpected[i]; } } RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("gatherTileData", "DFB"); }); // Each rank sends us the offset lists of the individually compressed tiles // in its compressed data buffer std::vector compressedTileOffsets; if (IamTheMaster()) { compressedTileOffsets.resize(totalTilesExpected, 0); } auto tileOffsetsGather = gatherv(tileBufferOffsets.data(), tileBufferOffsets.size(), MPI_INT, compressedTileOffsets.data(), numTilesExpected, processOffsets, MPI_INT, masterRank(), mpiGroup.comm); // We've got to use an int since Gatherv only takes int counts. // However, it's pretty unlikely we'll reach the point where someone // is sending 2GB in final tile data from a single process const int sendCompressedSize = static_cast(nextTileWrite); // Get info about how many bytes each proc is sending us std::vector gatherSizes; if (IamTheMaster()) { gatherSizes.resize(workerSize(), 0); } gather(&sendCompressedSize, 1, MPI_INT, gatherSizes.data(), 1, MPI_INT, masterRank(), mpiGroup.comm) .wait(); std::vector compressedOffsets; if (IamTheMaster()) { compressedOffsets.resize(workerSize(), 0); int offset = 0; for (size_t i = 0; i < gatherSizes.size(); ++i) { compressedOffsets[i] = offset; offset += gatherSizes[i]; } compressedResults.resize(offset, 0); } gatherv(tileGatherBuffer.data(), sendCompressedSize, MPI_BYTE, compressedResults.data(), gatherSizes, compressedOffsets, MPI_BYTE, masterRank(), mpiGroup.comm) .wait(); tileOffsetsGather.wait(); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // Now we must decompress each ranks data to process it, though we // already know how much data each is sending us and where to write it. if (IamTheMaster()) { RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("masterTileWrite", "DFB")); tasking::parallel_for(workerSize(), [&](int i) { tasking::parallel_for(numTilesExpected[i], [&](int tid) { int processTileOffset = processOffsets[i] + tid; int compressedSize = 0; if (tid + 1 < numTilesExpected[i]) { compressedSize = compressedTileOffsets[processTileOffset + 1] - compressedTileOffsets[processTileOffset]; } else { compressedSize = gatherSizes[i] - compressedTileOffsets[processTileOffset]; } char *decompressedTile = STACK_BUFFER(char, tileSize); snappy::RawUncompress(&compressedResults[compressedOffsets[i] + compressedTileOffsets[processTileOffset]], compressedSize, decompressedTile); MasterTileMessage_FB *msg = reinterpret_cast(decompressedTile); this->processMessage(msg); }); }); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // not accurate, did we render something at all localFBonMaster->getSh()->super.numPixelsRendered = totalTilesExpected; } } void DFB::gatherFinalErrors() { using namespace mpicommon; using namespace rkcommon; std::vector tilesFromRank(workerSize(), 0); const int myTileCount = tileIDs.size(); gather(&myTileCount, 1, MPI_INT, tilesFromRank.data(), 1, MPI_INT, masterRank(), mpiGroup.comm) .wait(); std::vector tileGatherResult; std::vector tileBytesExpected(workerSize(), 0); std::vector processOffsets(workerSize(), 0); const size_t tileInfoSize = sizeof(float) + sizeof(vec2i); if (IamTheMaster()) { size_t recvOffset = 0; for (int i = 0; i < workerSize(); ++i) { processOffsets[i] = recvOffset; tileBytesExpected[i] = tilesFromRank[i] * tileInfoSize; recvOffset += tileBytesExpected[i]; } tileGatherResult.resize(recvOffset); } std::vector sendBuffer(myTileCount * tileInfoSize); std::memcpy( sendBuffer.data(), tileIDs.data(), tileIDs.size() * sizeof(vec2i)); std::memcpy(sendBuffer.data() + tileIDs.size() * sizeof(vec2i), tileErrors.data(), tileErrors.size() * sizeof(float)); gatherv(sendBuffer.data(), sendBuffer.size(), MPI_BYTE, tileGatherResult.data(), tileBytesExpected, processOffsets, MPI_BYTE, masterRank(), mpiGroup.comm) .wait(); if (IamTheMaster()) { tasking::parallel_for(workerSize(), [&](int rank) { const vec2i *tileID = reinterpret_cast( tileGatherResult.data() + processOffsets[rank]); const float *error = reinterpret_cast(tileGatherResult.data() + processOffsets[rank] + tilesFromRank[rank] * sizeof(vec2i)); for (int i = 0; i < tilesFromRank[rank]; ++i) { if (error[i] < (float)inf) { tileErrorRegion.update(tileID[i], error[i]); } } }); } } void DFB::closeCurrentFrame() { std::lock_guard lock(mutex); frameIsDone = true; frameDoneCond.notify_all(); } //! write given tile data into the frame buffer, sending to remote owner if //! required void DFB::setTile(const ispc::Tile &tile) { auto *tileDesc = this->getTileDescFor(tile.region.lower); // Note my tile, send to the owner if (!tileDesc->mine()) { auto msg = makeWriteTileMessage( tile, hasNormalBuffer || hasAlbedoBuffer || hasIDBuf()); int dstRank = tileDesc->ownerID; mpi::messaging::sendTo(dstRank, myId, msg); } else { if (!frameIsActive) throw std::runtime_error("#dfb: cannot setTile if frame is inactive!"); LiveTileOperation *td = (LiveTileOperation *)tileDesc; td->process(tile); } } void DFB::clear() { FrameBuffer::clear(); if (hasVarianceBuffer) { tileErrorRegion.clear(); } if (localFBonMaster) { localFBonMaster->clear(); } for (auto &l : layers) { l->clear(); } } vec2i DFB::getNumRenderTasks() const { return numRenderTasks; } uint32_t DFB::getTotalRenderTasks() const { return numRenderTasks.product(); } vec2i DFB::getGlobalNumTiles() const { return totalTiles; } uint32_t DFB::getGlobalTotalTiles() const { return totalTiles.product(); } utility::ArrayView DFB::getRenderTaskIDs( const float errorThreshold, const uint32_t spp) { return layers[0]->getRenderTaskIDs(errorThreshold, spp); } float DFB::getVariance() const { // TODO: No proper error calculation for DFB now, // need to use FrameOp via LocalFB if (mpicommon::IamTheMaster()) return 1.f; // Return set value otherwise return FrameBuffer::getVariance(); } float DFB::taskError(const uint32_t) const { NOT_IMPLEMENTED; } float DFB::tileError(const uint32_t tileID) { return tileErrorRegion[tileID]; } devicert::AsyncEvent DFB::postProcess() { devicert::AsyncEvent event; if (localFBonMaster) { // FrameOps are run on the device, but the DFB receives the final image // data over MPI into host-memory, and returns host-memory pointers // directly. So, we need to copy the host data to the device, run the frame // ops. If we can receive with MPI directly into device // memory we can drop this first copy step. When running on the CPU device, // these copies will become no-ops. if (localFBonMaster->colorBuffer) { localFBonMaster->colorBuffer->copyToDevice(); } if (localFBonMaster->depthBuffer) { localFBonMaster->depthBuffer->copyToDevice(); } if (localFBonMaster->normalBuffer) { localFBonMaster->normalBuffer->copyToDevice(); } if (localFBonMaster->albedoBuffer) { localFBonMaster->albedoBuffer->copyToDevice(); } event = localFBonMaster->postProcess(); } return event; } } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/fb/DistributedFrameBuffer.h000066400000000000000000000245751464752671100262110ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "../common/Messaging.h" #include "DistributedFrameBuffer_TileMessages.h" #include "ISPCDevice.h" #include "fb/LocalFB.h" #include "fb/SparseFB.h" #include "fb/TaskError.h" #include "render/Renderer.h" #include "rkcommon/containers/AlignedVector.h" #include "rkcommon/math/vec.h" #include "DistributedFrameBufferShared.h" namespace ospray { struct TileDesc; struct TileOperation; struct LiveTileOperation; class DistributedTileError : public TaskError { mpicommon::Group group; public: DistributedTileError( api::ISPCDevice &device, const vec2i &numTiles, mpicommon::Group group); // broadcast tileErrorBuffer to all workers in this group void sync(); }; struct DistributedFrameBuffer : public mpi::messaging::MessageHandler, public FrameBuffer { DistributedFrameBuffer(api::ISPCDevice &device, const vec2i &numPixels, ObjectHandle myHandle, ColorBufferFormat, const uint32 channels); ~DistributedFrameBuffer() override; // ================================================================== // framebuffer / device interface // ================================================================== void commit() override; const void *mapBuffer(OSPFrameBufferChannel channel) override; void unmap(const void *mappedMem) override; /*! \brief clear (the specified channels of) this frame buffer \details for the *distributed* frame buffer, we assume that *all* nodes get this command, and that each instance therefore can clear only its own tiles without having to tell any other node about it */ void clear() override; // ================================================================== // framebuffer-renderer/loadbalancer interface // ================================================================== // Return the number of render tasks in the x and y direction // This is the kernel launch dims to render the image vec2i getNumRenderTasks() const override; uint32_t getTotalRenderTasks() const override; vec2i getGlobalNumTiles() const; uint32_t getGlobalTotalTiles() const; /* Get render task IDs will return the render task IDs for layer 0, * the tiles owned by the DFB for compositing. */ utility::ArrayView getRenderTaskIDs( const float errorThreshold, const uint32_t spp) override; virtual float getVariance() const override; // Task error is not valid for the DFB, as error is tracked at a per-tile // level. Use tileError to get rendering error float taskError(const uint32_t taskID) const override; float tileError(const uint32_t tileID); /*! framebuffer-renderer/loadbalancer interface: loadbalancer calls this function whenever a local node has finished a tile, and wants the (distributed) frame buffer to process it */ void setTile(const ispc::Tile &tile); void startNewFrame(const float errorThreshold); void closeCurrentFrame(); void waitUntilFinished(); devicert::AsyncEvent postProcess() override; void setTileOperation( std::shared_ptr tileOp, const Renderer *renderer); std::shared_ptr getTileOperation(); const Renderer *getLastRenderer() const; mpicommon::Group getMPIGroup(); // ================================================================== // interface for maml messaging, enables communication between // different instances of same object // ================================================================== //! handle incoming message from commlayer. it's the //! recipient's job to properly delete the message. void incoming(const std::shared_ptr &message) override; //! process a (non-empty) write tile message at the master void processMessage(MasterTileMessage_FB *msg); //! process a client-to-client write tile message */ void processMessage(WriteTileMessage *msg); size_t ownerIDFromTileID(size_t tileID) const; void setSparseFBLayerCount(size_t numLayers); size_t getSparseLayerCount() const; SparseFrameBuffer *getSparseFBLayer(size_t l); void cancelFrame() override; float getCurrentProgress() const override; private: friend struct LiveTileOperation; bool hasIDBuf() const; // ================================================================== // internal helper functions // ================================================================== /*! this function gets called whenever one of our tiles is done writing/compositing/blending/etc; i.e., as soon as we know that all the ingredient tile data for that tile have been received from the client(s) that generated them. By the time the tile gets called we do know that 'accum' field of the tile has been set; it is this function's job to make sure we properly call the post-op(s), properly send final color data to the master (if required), and properly do the bookkeeping that this tile is now done. */ void tileIsFinished(LiveTileOperation *tile); /*! This function is called when a worker reports how many tiles it's completed to the master, to update the user's progress callback. This is only used if the user has set a progress callback. */ void updateProgress(ProgressMessage *msg); //! number of tiles that "I" own size_t numMyTiles() const; //! \brief common function to help printf-debugging /*! \detailed Every derived class should override this! */ std::string toString() const override; /*! return tile descriptor for given pixel coordinates. this tile ! may or may not belong to current instance */ TileDesc *getTileDescFor(const vec2i &coords) const; /*! return the tile ID for given pair of coordinates. this tile may or may not belong to current instance */ size_t getTileIDof(const vec2i &c) const; void createTiles(); /*! atomic update and check if frame is complete with given tiles */ bool isFrameComplete(size_t numTiles); /*! Offloads processing of incoming message to tasking system */ void scheduleProcessing(const std::shared_ptr &message); /*! Gather the final tiles from the other ranks to the master rank to * copy into the framebuffer */ void gatherFinalTiles(); /*! Gather the tile IDs and error info from the other ranks to the master, * for OSP_FB_NONE rendering, where we only track that info on the master */ void gatherFinalErrors(); // Data members /////////////////////////////////////////////////////////// // The communicator used by this DFB instance for collectives, to avoid // conflicts with other framebuffers mpicommon::Group mpiGroup; // Total number of tiles that the framebuffer is divided into, including those // not owned by this sparsefb vec2i totalTiles; // Total number of render tasks that the framebuffer is divided into, // including those not owned by this sparsefb vec2i numRenderTasks; std::vector tileGatherBuffer; std::vector compressedResults; // Locations of the compressed tiles in the tileGatherBuffer std::vector tileBufferOffsets; uint32_t nextTileWrite{0}; std::mutex finalTileBufferMutex; /*! holds error per tile and adaptive regions, for variance estimation / stopping */ DistributedTileError tileErrorRegion; /*! local frame buffer on the master used for storing the final tiles. will be null on all workers, and _may_ be null on the master if the master does not have a color buffer */ std::unique_ptr localFBonMaster; /* SparseFrameBuffer layers in the DFB, layer 0 stores the tiles owned by DFB * for compositing, and layers 1-N are those added by the renderer. For * renderers whose local rendering work is dynamic/data-dependent (e.g., * data-parallel rendering), layers can be allocated and resized as needed to * avoid having to reallocate the set of SparseFrameBuffer(s) needed each * frame. */ std::vector> layers; /*! #tiles we've (already) sent to / received by the master this frame (used to track when current node is done with this frame - we are done exactly once we've completed sending / receiving the last tile to / by the master) */ size_t numTilesCompletedThisFrame{0}; /*! The total number of tiles completed by all workers during this frame, to track progress for the user's progress callback. NOTE: This is not the numTilesCompletedThisFrame , which tracks how many tiles this rank has finished of the ones it's responsible for completing */ size_t globalTilesCompletedThisFrame{0}; /*! The number of tiles the master is expecting to receive from each rank */ std::vector numTilesExpected; /* protected numTilesCompletedThisFrame to ensure atomic update and compare */ std::mutex numTilesMutex; /* vector of info for *all* tiles. Each logical tile in the screen has an * entry here. allTiles owns the lifetime for tiles in myTiles as well, which * is a subset of those in allTiles containing the live tile operations for * the tiles this rank owns */ std::vector> allTiles; /* list of *our* tiles ('our' as in 'that belong to the given node'), with the actual data of those tiles. NOTE: for msvc15 issue with shared_ptr, the tile operation lifetime is managed in allTiles which holds a unique_ptr for all tiles (both ones we own, and don't). */ std::vector myTiles; std::shared_ptr tileOperation = nullptr; const Renderer *lastRenderer = nullptr; /*! mutex used to protect all threading-sensitive data in this object */ std::mutex mutex; //! set to true when the frame becomes 'active', and write tile //! messages can be consumed. std::atomic frameIsActive{false}; /*! set to true when the framebuffer is done for the given frame */ bool frameIsDone{false}; int renderingProgressTiles{0}; std::chrono::steady_clock::time_point lastProgressReport; std::atomic frameProgress{0.f}; //! condition that gets triggered when the frame is done std::condition_variable frameDoneCond; /*! Gather all tile errors in the optimized FB_NONE case to send them out in the single gatherv. */ std::mutex tileErrorsMutex; std::vector tileIDs; std::vector tileErrors; }; } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/fb/DistributedFrameBuffer.ispc000066400000000000000000000303501464752671100267040ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" #include "fb/FrameBuffer.ih" #include "fb/TileShared.h" #include "rkcommon/math/vec.ih" #include "fb/FrameBufferShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE // accumulates the colors in a tile, writes the final normalized colors into a // separate tile, and computes the error export uniform float DFB_accumulateTile(const VaryingTile *uniform tile, VaryingTile *uniform final, VaryingTile *uniform accum, VaryingTile *uniform variance, uniform bool doAccumulation, uniform bool hasVarianceBuffer) { const uniform int accumID = tile->accumID; const uniform vec2i size = box_size(tile->region); const uniform int maxi = size.y * (TILE_SIZE / programCount); uniform float errf = inf; /* variance buffer accumulates every other frame */ const uniform bool accumulateVariance = hasVarianceBuffer && (accumID & 1) == 1; if (!doAccumulation || accumID < 1) { for (uniform int i = 0; i < maxi; i++) { vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]); accum->r[i] = col.x; accum->g[i] = col.y; accum->b[i] = col.z; accum->a[i] = col.w; accum->z[i] = tile->z[i]; final->r[i] = col.x; final->g[i] = col.y; final->b[i] = col.z; final->a[i] = col.w; final->z[i] = tile->z[i]; // ID buffers only written on the first frame final->pid[i] = tile->pid[i]; final->gid[i] = tile->gid[i]; final->iid[i] = tile->iid[i]; } } else { const uniform float rcpAccumID = rcpf(accumID + 1); const uniform float accHalfScale = rcpf(accumID / 2 + 1); float err = 0.f; int cnt = 0; for (uniform int i = 0; i < maxi; i++) { vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]); vec4f acc = col + make_vec4f(accum->r[i], accum->g[i], accum->b[i], accum->a[i]); accum->r[i] = acc.x; accum->g[i] = acc.y; accum->b[i] = acc.z; accum->a[i] = acc.w; acc = acc * rcpAccumID; if (accumulateVariance) { varying vec4f vari = make_vec4f(0.f); if (accumID > 1) vari = make_vec4f( variance->r[i], variance->g[i], variance->b[i], variance->a[i]); vari = vari + col; variance->r[i] = vari.x; variance->g[i] = vari.y; variance->b[i] = vari.z; variance->a[i] = vari.w; /* invert alpha (bright alpha is more important */ const float den2 = reduce_add(make_vec3f(acc)) + (1.f - acc.w); if (den2 > 0.0f) { const vec4f diff = absf(acc - accHalfScale * vari); if ((i * programCount % TILE_SIZE) + programIndex < size.x) { err += reduce_add(diff) * rsqrtf(den2); cnt++; } } } final->r[i] = acc.x; final->g[i] = acc.y; final->b[i] = acc.z; final->a[i] = acc.w; } /* error is also only updated every other frame to avoid alternating * error (get a monotone sequence) */ if (accumulateVariance) { // scaling factor to stay backward compatible to default TILE_SIZE=64 errf = reduce_add(err) * rcp((uniform float)reduce_add(cnt)) * 64.f; } } return errf; } // variant that only accumulates (without computing error) // assumption: there is always ACCUM and VARIANCE buffer (otherwise variance // will always be inf and WriteMultipleTiles mode won't be used) export void DFB_accumulateTileSimple(const VaryingTile *uniform tile, VaryingTile *uniform accum, VaryingTile *uniform variance) { // variance buffer accumulates every other frame const uniform bool accumulateVariance = (tile->accumID & 1) == 1; const uniform vec2i size = box_size(tile->region); const uniform int maxi = size.y * (TILE_SIZE / programCount); for (uniform int i = 0; i < maxi; i++) { vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]); accum->r[i] += col.x; accum->g[i] += col.y; accum->b[i] += col.z; accum->a[i] += col.w; if (accumulateVariance) { variance->r[i] += col.x; variance->g[i] += col.y; variance->b[i] += col.z; variance->a[i] += col.w; } } } // accumulate normal and albedo export void DFB_accumulateAuxTile(const VaryingTile *uniform tile, void *uniform _final, VaryingTile *uniform accum) { Tile *uniform final = (Tile * uniform) _final; const uniform vec2i size = box_size(tile->region); const uniform int maxi = size.y * (TILE_SIZE / programCount); if (tile->accumID < 1) { for (uniform int i = 0; i < maxi; i++) { const float fnx = tile->nx[i]; const float fny = tile->ny[i]; const float fnz = tile->nz[i]; accum->nx[i] = fnx; accum->ny[i] = fny; accum->nz[i] = fnz; #ifdef OSPRAY_TARGET_SYCL final->nx[3 * i] = fnx; final->nx[3 * i + 1] = fny; final->nx[3 * i + 2] = fnz; /* final->nx[i] = fnx; final->ny[i] = fny; final->nz[i] = fnz; */ #else // TODO: This is not right but some other bug/data use cancels it out. // The tile struct stores SoA layout memory too, but here we treat it // like SoA for some reason, so final->nx will hold: // {fnx0, fny0, fnz0, fnx1, fny1, fnz1, ..., progCount,...} // after the write here soa_to_aos3(fnx, fny, fnz, final->nx + 3 * programCount * i); #endif const float far = tile->ar[i]; const float fag = tile->ag[i]; const float fab = tile->ab[i]; accum->ar[i] = far; accum->ag[i] = fag; accum->ab[i] = fab; #ifdef OSPRAY_TARGET_SYCL final->ar[3 * i] = far; final->ar[3 * i + 1] = fag; final->ar[3 * i + 2] = fab; /* final->ar[i] = far; final->ag[i] = fag; final->ab[i] = fab; */ #else soa_to_aos3(far, fag, fab, final->ar + 3 * programCount * i); #endif } } else { const uniform float rcpAccumID = rcpf(tile->accumID + 1); for (uniform int i = 0; i < maxi; i++) { accum->nx[i] += tile->nx[i]; accum->ny[i] += tile->ny[i]; accum->nz[i] += tile->nz[i]; const float fnx = accum->nx[i] * rcpAccumID; const float fny = accum->ny[i] * rcpAccumID; const float fnz = accum->nz[i] * rcpAccumID; #ifdef OSPRAY_TARGET_SYCL final->nx[3 * i] = fnx; final->nx[3 * i + 1] = fny; final->nx[3 * i + 2] = fnz; /* final->nx[i] = fnx; final->ny[i] = fny; final->nz[i] = fnz; */ #else soa_to_aos3(fnx, fny, fnz, final->nx + 3 * programCount * i); #endif accum->ar[i] += tile->ar[i]; accum->ag[i] += tile->ag[i]; accum->ab[i] += tile->ab[i]; const float far = accum->ar[i] * rcpAccumID; const float fag = accum->ag[i] * rcpAccumID; const float fab = accum->ab[i] * rcpAccumID; #ifdef OSPRAY_TARGET_SYCL final->ar[3 * i] = far; final->ar[3 * i + 1] = fag; final->ar[3 * i + 2] = fab; /* final->ar[i] = far; final->ag[i] = fag; final->ab[i] = fab; */ #else soa_to_aos3(far, fag, fab, final->ar + 3 * programCount * i); #endif } } } // computes the error for a tile export uniform float DFB_computeErrorForTile( const uniform int *uniform const size_, // vec2i const VaryingTile *uniform accum, const VaryingTile *uniform variance, const uniform float accumID) { const uniform vec2i size = make_vec2i(size_[0], size_[1]); const uniform int maxi = size.y * (TILE_SIZE / programCount); const uniform float rcpAccumID = rcpf(accumID + 1); const uniform float accHalfScale = rcpf(accumID / 2 + 1); float err = 0.f; for (uniform int i = 0; i < maxi; i++) { vec4f acc = make_vec4f(accum->r[i], accum->g[i], accum->b[i], accum->a[i]); acc = acc * rcpAccumID; /* invert alpha (bright alpha is more important */ const float den2 = reduce_add(make_vec3f(acc)) + (1.f - acc.w); if (den2 > 0.0f) { const vec4f vari = make_vec4f( variance->r[i], variance->g[i], variance->b[i], variance->a[i]); const vec4f diff = absf(acc - accHalfScale * vari); if ((i * programCount % TILE_SIZE) + programIndex < size.x) err += reduce_add(diff) * rsqrtf(den2); } } uniform float cntu = (uniform float)size.x * size.y; // scaling factor to stay backward compatible to default TILE_SIZE=64 return reduce_add(err) * rcp(cntu) * 64.f; } // writes the final normalized colors in a tile into a color buffer export void DFB_writeTile(const VaryingTile *uniform tile, void *uniform _color) { const uniform vec2i size = box_size(tile->region); const uniform int maxi = size.y * (TILE_SIZE / programCount); varying vec4f *uniform color = (varying vec4f * uniform) _color; for (uniform int i = 0; i < maxi; i++) { const vec4f c = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]); #ifndef OSPRAY_TARGET_SYCL soa_to_aos4(c.x, c.y, c.z, c.w, (uniform float *uniform) & color[i]); #else color[i] = c; #endif } } export void DFB_zComposite( const VaryingTile *uniform delta, VaryingTile *uniform current) { for (uniform int i = 0; i < TILE_SIZE * TILE_SIZE / programCount; i++) { const bool closer = delta->z[i] < current->z[i]; current->r[i] = closer ? delta->r[i] : current->r[i]; current->g[i] = closer ? delta->g[i] : current->g[i]; current->b[i] = closer ? delta->b[i] : current->b[i]; current->a[i] = closer ? delta->a[i] : current->a[i]; current->z[i] = closer ? delta->z[i] : current->z[i]; } } inline void swapFragments( VaryingTile *uniform t0, VaryingTile *uniform t1, uniform int fragID) { float r = t0->r[fragID]; t0->r[fragID] = t1->r[fragID]; t1->r[fragID] = r; float g = t0->g[fragID]; t0->g[fragID] = t1->g[fragID]; t1->g[fragID] = g; float b = t0->b[fragID]; t0->b[fragID] = t1->b[fragID]; t1->b[fragID] = b; float a = t0->a[fragID]; t0->a[fragID] = t1->a[fragID]; t1->a[fragID] = a; float z = t0->z[fragID]; t0->z[fragID] = t1->z[fragID]; t1->z[fragID] = z; float nx = t0->nx[fragID]; t0->nx[fragID] = t1->nx[fragID]; t1->nx[fragID] = nx; float ny = t0->ny[fragID]; t0->ny[fragID] = t1->ny[fragID]; t1->ny[fragID] = ny; float nz = t0->nz[fragID]; t0->nz[fragID] = t1->nz[fragID]; t1->nz[fragID] = nz; float ar = t0->ar[fragID]; t0->ar[fragID] = t1->ar[fragID]; t1->ar[fragID] = ar; float ag = t0->ag[fragID]; t0->ag[fragID] = t1->ag[fragID]; t1->ag[fragID] = ag; float ab = t0->ab[fragID]; t0->ab[fragID] = t1->ab[fragID]; t1->ab[fragID] = ab; uint32 pid = t0->pid[fragID]; t0->pid[fragID] = t1->pid[fragID]; t1->pid[fragID] = pid; uint32 gid = t0->gid[fragID]; t0->gid[fragID] = t1->gid[fragID]; t1->gid[fragID] = gid; uint32 iid = t0->iid[fragID]; t0->iid[fragID] = t1->iid[fragID]; t1->iid[fragID] = iid; } inline void sortAndBlendFragments(VaryingTile *uniform *uniform tileArray, uniform int32 numTiles, uniform int begin_frag, uniform int end_frag) { for (uniform int frag = begin_frag; frag < end_frag; ++frag) { #if 1 for (uniform int i = 1; i < numTiles; ++i) { for (uniform int j = i; j > 0; --j) { VaryingTile *uniform ta = tileArray[j]; VaryingTile *uniform tb = tileArray[j - 1]; if (ta->z[frag] < tb->z[frag]) break; swapFragments(ta, tb, frag); } } #endif vec3f acc_col = make_vec3f(0, 0, 0); float acc_alpha = 0.f; for (uniform int i = 0; i < numTiles; ++i) { VaryingTile *uniform tile = tileArray[i]; vec3f frag_col = make_vec3f(tile->r[frag], tile->g[frag], tile->b[frag]); float frag_alpha = tile->a[frag]; // Note: back-to-front blending acc_col = frag_col + (1.f - frag_alpha) * acc_col; acc_alpha = frag_alpha + (1.f - frag_alpha) * acc_alpha; } VaryingTile *uniform tile = tileArray[0]; tile->r[frag] = acc_col.x; tile->g[frag] = acc_col.y; tile->b[frag] = acc_col.z; tile->a[frag] = acc_alpha; // Since we blend back-to-front, the nearest depth sample is // on the last tile after sorting. tile->z[frag] = tileArray[numTiles - 1]->z[frag]; } } export void DFB_sortAndBlendFragments( VaryingTile *uniform *uniform tileArray, uniform int32 numTiles) { sortAndBlendFragments( tileArray, numTiles, 0, TILE_SIZE * TILE_SIZE / programCount); } OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/mpi/ospray/fb/DistributedFrameBufferShared.h000066400000000000000000000022311464752671100273210ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "fb/FrameBufferShared.h" #include "fb/TileShared.h" #ifdef __cplusplus #include "common/StructShared.h" namespace ispc { #endif // __cplusplus #ifdef OSPRAY_TARGET_SYCL float DFB_accumulateTile(const VaryingTile *uniform tile, VaryingTile *uniform final, VaryingTile *uniform accum, VaryingTile *uniform variance, uniform bool doAccumulation, uniform bool hasVarianceBuffer); void DFB_accumulateTileSimple(const VaryingTile *uniform tile, VaryingTile *uniform accum, VaryingTile *uniform variance); void DFB_accumulateAuxTile(const VaryingTile *uniform tile, void *uniform _final, VaryingTile *uniform accum); export uniform float DFB_computeErrorForTile( const uniform int *uniform const size_, // vec2i const VaryingTile *uniform accum, const VaryingTile *uniform variance, const uniform float accumID); void DFB_writeTile(const VaryingTile *tile, void *_color); void DFB_sortAndBlendFragments( VaryingTile *uniform *uniform tileArray, uniform int32 numTiles); #endif #ifdef __cplusplus } #endif // __cplusplus RenderKit-ospray-85af292/modules/mpi/ospray/fb/DistributedFrameBuffer_TileMessages.cpp000066400000000000000000000122161464752671100311760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DistributedFrameBuffer_TileMessages.h" #include "../common/Messaging.h" namespace ospray { std::shared_ptr makeWriteTileMessage( const ispc::Tile &tile, bool hasAux) { const size_t msgSize = hasAux ? sizeof(ispc::Tile) : sizeof(WriteTileMessage); auto msg = std::make_shared(msgSize + sizeof(int)); const static int header = WORKER_WRITE_TILE; std::memcpy(msg->data, &header, sizeof(int)); std::memcpy(msg->data + sizeof(int), &tile, msgSize); return msg; } void unpackWriteTileMessage( WriteTileMessage *msg, ispc::Tile &tile, bool hasAux) { const size_t msgSize = hasAux ? sizeof(ispc::Tile) : sizeof(WriteTileMessage); std::memcpy(&tile, reinterpret_cast(msg) + sizeof(int), msgSize); } size_t masterMsgSize( bool hasDepth, bool hasNormal, bool hasAlbedo, bool hasIDBuffers) { size_t msgSize = sizeof(MasterTileMessage_FB); // Normal and Albedo also imply Depth if (hasDepth || hasNormal || hasAlbedo) { msgSize += sizeof(float) * TILE_SIZE * TILE_SIZE; } if (hasNormal || hasAlbedo) { msgSize += 2 * sizeof(vec3f) * TILE_SIZE * TILE_SIZE; } // If any ID buffer is present we allocate space for all of them to be sent if (hasIDBuffers) { msgSize += 3 * sizeof(uint32) * TILE_SIZE * TILE_SIZE; } return msgSize; } MasterTileMessageBuilder::MasterTileMessageBuilder(bool hasDepth, bool hasNormal, bool hasAlbedo, bool hasIDBuffers, vec2i coords, float error) : hasDepth(hasDepth), hasNormal(hasNormal), hasAlbedo(hasAlbedo), hasIDBuffers(hasIDBuffers) { int command = MASTER_WRITE_TILE; const size_t msgSize = masterMsgSize(hasDepth, hasNormal, hasAlbedo, hasIDBuffers); // AUX also includes depth if (hasDepth || hasNormal || hasAlbedo) { command |= MASTER_TILE_HAS_DEPTH; } if (hasNormal || hasAlbedo) { command |= MASTER_TILE_HAS_AUX; } if (hasIDBuffers) { command |= MASTER_TILE_HAS_ID; } message = std::make_shared(msgSize); header = reinterpret_cast(message->data); header->command = command; header->coords = coords; header->error = error; } void MasterTileMessageBuilder::setColor(const vec4f *color) { vec4f *out = reinterpret_cast(message->data + sizeof(MasterTileMessage)); std::copy(color, color + TILE_SIZE * TILE_SIZE, out); } void MasterTileMessageBuilder::setDepth(const float *depth) { if (hasDepth) { float *out = reinterpret_cast( message->data + sizeof(MasterTileMessage) + colorBufferSize()); std::copy(depth, depth + TILE_SIZE * TILE_SIZE, out); } } void MasterTileMessageBuilder::setNormal(const vec3f *normal) { if (hasNormal) { vec3f *out = reinterpret_cast(message->data + sizeof(MasterTileMessage) + colorBufferSize() + depthBufferSize()); std::copy(normal, normal + TILE_SIZE * TILE_SIZE, out); } } void MasterTileMessageBuilder::setAlbedo(const vec3f *albedo) { if (hasAlbedo) { vec3f *out = reinterpret_cast(message->data + sizeof(MasterTileMessage) + colorBufferSize() + depthBufferSize() + normalBufferSize()); std::copy(albedo, albedo + TILE_SIZE * TILE_SIZE, out); } } void MasterTileMessageBuilder::setPrimitiveID(const uint32 *primID) { if (hasIDBuffers) { size_t offset = sizeof(MasterTileMessage) + colorBufferSize() + depthBufferSize() + normalBufferSize() + albedoBufferSize(); uint32 *out = reinterpret_cast(message->data + offset); std::copy(primID, primID + TILE_SIZE * TILE_SIZE, out); } } void MasterTileMessageBuilder::setObjectID(const uint32 *geomID) { if (hasIDBuffers) { size_t offset = sizeof(MasterTileMessage) + colorBufferSize() + depthBufferSize() + normalBufferSize() + albedoBufferSize() + sizeof(uint32) * TILE_SIZE * TILE_SIZE; uint32 *out = reinterpret_cast(message->data + offset); std::copy(geomID, geomID + TILE_SIZE * TILE_SIZE, out); } } void MasterTileMessageBuilder::setInstanceID(const uint32 *instID) { if (hasIDBuffers) { size_t offset = sizeof(MasterTileMessage) + colorBufferSize() + depthBufferSize() + normalBufferSize() + albedoBufferSize() + 2 * sizeof(uint32) * TILE_SIZE * TILE_SIZE; uint32 *out = reinterpret_cast(message->data + offset); std::copy(instID, instID + TILE_SIZE * TILE_SIZE, out); } } size_t MasterTileMessageBuilder::colorBufferSize() const { return sizeof(vec4f) * TILE_SIZE * TILE_SIZE; } size_t MasterTileMessageBuilder::depthBufferSize() const { return hasDepth || hasNormal || hasAlbedo ? sizeof(float) * TILE_SIZE * TILE_SIZE : 0; } size_t MasterTileMessageBuilder::normalBufferSize() const { return (hasNormal || hasAlbedo) ? sizeof(vec3f) * TILE_SIZE * TILE_SIZE : 0; } size_t MasterTileMessageBuilder::albedoBufferSize() const { return (hasNormal || hasAlbedo) ? sizeof(vec3f) * TILE_SIZE * TILE_SIZE : 0; } size_t MasterTileMessageBuilder::idBufferSize() const { return hasIDBuffers ? 3 * sizeof(uint32) * TILE_SIZE * TILE_SIZE : 0; } } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/fb/DistributedFrameBuffer_TileMessages.h000066400000000000000000000106701464752671100306450ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../common/Messaging.h" #include "fb/LocalFB.h" #include "fb/TileShared.h" namespace ospray { /*! color buffer and depth buffer on master */ enum COMMANDTAG { /*! command tag that identifies a CommLayer::message as a write tile command. this is a command using for sending a tile of new samples to another instance of the framebuffer (the one that actually owns that tile) for processing and 'writing' of that tile on that owner node. */ WORKER_WRITE_TILE = 1 << 1, /*! command tag used for sending 'final' tiles from the tile owner to the master frame buffer. Note that we *do* send a message back to the master even in cases where the master does not actually care about the pixel data - we still have to let the master know when we're done. */ MASTER_WRITE_TILE = 1 << 2, // Modifier to indicate the tile has depth values MASTER_TILE_HAS_DEPTH = 1 << 3, // Indicates that the tile has normal and/or albedo values MASTER_TILE_HAS_AUX = 1 << 4, // Indicates that the tile has ID buffer values MASTER_TILE_HAS_ID = 1 << 5, // abort rendering the current frame CANCEL_RENDERING = 1 << 6, // Worker updating us on tiles completed PROGRESS_MESSAGE = 1 << 7 }; struct TileMessage { int command{-1}; }; struct ProgressMessage : public TileMessage { uint64_t numCompleted; int frameID; }; struct MasterTileMessage : public TileMessage { vec2i coords; float error; }; /*! message sent to the master when a tile is finished. TODO: compress the color data */ struct MasterTileMessage_FB : public MasterTileMessage { vec4f color[TILE_SIZE * TILE_SIZE]; }; struct MasterTileMessage_FB_Depth : public MasterTileMessage_FB { float depth[TILE_SIZE * TILE_SIZE]; }; struct MasterTileMessage_FB_Depth_Aux : public MasterTileMessage_FB_Depth { vec3f normal[TILE_SIZE * TILE_SIZE]; vec3f albedo[TILE_SIZE * TILE_SIZE]; }; /*! message sent from one node's instance to another, to tell that instance to write that tile */ struct WriteTileMessage : public TileMessage { region2i region; // screen region that this corresponds to vec2i fbSize; // total frame buffer size, for the camera vec2f rcp_fbSize; int32 generation; int32 children; int32 sortOrder; int32 accumID; //!< how often has been accumulated into this tile float pad[4]; //!< padding to match the ISPC-side layout float r[TILE_SIZE * TILE_SIZE]; // 'red' component float g[TILE_SIZE * TILE_SIZE]; // 'green' component float b[TILE_SIZE * TILE_SIZE]; // 'blue' component float a[TILE_SIZE * TILE_SIZE]; // 'alpha' component float z[TILE_SIZE * TILE_SIZE]; // 'depth' component }; std::shared_ptr makeWriteTileMessage( const ispc::Tile &tile, bool hasAux); void unpackWriteTileMessage( WriteTileMessage *msg, ispc::Tile &tile, bool hasAux); size_t masterMsgSize( bool hasDepth, bool hasNormal, bool hasAlbedo, bool hasIDBuffers); /*! The message builder lets us abstractly fill messages of different * types, while keeping the underlying message structs POD so they're * easy to send around. */ class MasterTileMessageBuilder { bool hasDepth; bool hasNormal; bool hasAlbedo; bool hasIDBuffers; MasterTileMessage *header; public: std::shared_ptr message; MasterTileMessageBuilder(bool hasDepth, bool hasNormal, bool hasAlbedo, bool hasIDBuffers, vec2i coords, float error); void setColor(const vec4f *color); void setDepth(const float *depth); void setNormal(const vec3f *normal); void setAlbedo(const vec3f *albedo); void setPrimitiveID(const uint32 *primID); void setObjectID(const uint32 *geomID); void setInstanceID(const uint32 *instID); private: // Return the size in bytes of the color data in the message size_t colorBufferSize() const; // Return the size in bytes of the depth data in the message. Returns 0 if // depth is not being sent size_t depthBufferSize() const; // Return the size in bytes of the normal data in the message. Returns 0 if // normals are not being sent size_t normalBufferSize() const; // Return the size in bytes of the albedo data in the message. Returns 0 if // albedo is not being sent size_t albedoBufferSize() const; // Return the size in bytes of the ID data in the message. Returns 0 if // IDs are not being sent size_t idBufferSize() const; }; } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/fb/TileOperation.cpp000066400000000000000000000026131464752671100247200ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "TileOperation.h" #include "DistributedFrameBuffer.h" #ifndef OSPRAY_TARGET_SYCL #include "fb/DistributedFrameBuffer_ispc.h" #endif namespace ospray { using DFB = DistributedFrameBuffer; void TileOperation::attach(DistributedFrameBuffer *) {} TileDesc::TileDesc(const vec2i &begin, size_t tileID, size_t ownerID) : begin(begin), tileID(tileID), ownerID(ownerID) {} LiveTileOperation::LiveTileOperation( DFB *dfb, const vec2i &begin, size_t tileID, size_t ownerID) : TileDesc(begin, tileID, ownerID), dfb(dfb) {} void LiveTileOperation::accumulate(const ispc::Tile &tile) { // accumulate, compute the finished normalized colors, and compute the // error, but don't write the finished colors into the color buffer yet // because pixel ops might modify them later Note: also used for FB_NONE error = DFB_accumulateTile((const ispc::VaryingTile *)&tile, (ispc::VaryingTile *)&finished, (ispc::VaryingTile *)&accum, (ispc::VaryingTile *)&variance, dfb->doAccum, dfb->hasVarianceBuffer); if (dfb->hasNormalBuffer || dfb->hasAlbedoBuffer) { ispc::DFB_accumulateAuxTile((const ispc::VaryingTile *)&tile, (ispc::Tile *)&finished, (ispc::VaryingTile *)&accum); } } void LiveTileOperation::tileIsFinished() { dfb->tileIsFinished(this); } } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/fb/TileOperation.h000066400000000000000000000074451464752671100243750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "common/OSPCommon.h" #include "common/StructShared.h" #include "fb/TileShared.h" #include "rkcommon/math/range.h" #include "rkcommon/math/vec.h" using namespace ospray; using namespace rkcommon::math; namespace ospray { struct DistributedFrameBuffer; struct LiveTileOperation; // TODO: Probably should all be under mpi namespace as well /* Base class for tile operations which can be attached to a distributed * framebuffer. The attach method will be called multiple times on each * rank, to make an instance of the live tile operation for each tile owned * by the rank. * * The tileoperation will be kept associated with the specific renderFrame * call, and can track additional state as needed by the renderer. */ struct TileOperation { virtual ~TileOperation() = default; /* The attach method is called when the tile operation is first attached * to the framebuffer. */ virtual void attach(DistributedFrameBuffer *dfb); /* The makeTile method is called to make the live tile operation for each * live tile owned by the rank. */ virtual std::unique_ptr makeTile( DistributedFrameBuffer *dfb, const vec2i &tileBegin, size_t tileID, size_t ownerID) = 0; virtual std::string toString() const = 0; }; /* Base descriptor for a tile: its position in the frame buffer, * its ID and which rank actually owns the tile for running tile operations */ struct TileDesc { TileDesc(const vec2i &begin, size_t tileID, size_t ownerID); virtual ~TileDesc() = default; /*! returns whether this tile is one of this particular node's tiles */ virtual bool mine() const { return false; } vec2i begin; size_t tileID, ownerID; }; /* Base class for a tile operation which the current rank is responsible for * executing. Includes scratch space for storing results computed by the * tile operation */ struct LiveTileOperation : public TileDesc { LiveTileOperation(DistributedFrameBuffer *dfb, const vec2i &begin, size_t tileID, size_t ownerID); virtual ~LiveTileOperation() override = default; // Called at the beginning of each frame virtual void newFrame() = 0; bool mine() const override { return true; } /* Called for each Tile rendered locally or received over the * network for this image tile. */ virtual void process(const ispc::Tile &tile) = 0; /* Utility method provided to accumulate the finished tile data from the * passed tile into the "finished" tile data, which will be passed on to any * ImageOps or written to the framebuffer. * TODO: Maybe just manage this on the DFB side? */ void accumulate(const ispc::Tile &tile); /* Method to be called when the tile operation is finished and the computed * image written to the "finished" member of the struct */ void tileIsFinished(); DistributedFrameBuffer *dfb; // estimated variance of this tile float error{0.f}; // TODO: dynamically allocate to save memory when no ACCUM or VARIANCE // even more TODO: Tile contains much more data (e.g. AUX), but using only // the color buffer here ==> much wasted memory // also holds accumulated normal&albedo ispc::Tile __aligned(64) accum; ispc::Tile __aligned(64) variance; /* To be able to give the 'postaccum' pixel op a readily normalized tile we have to create a local copy (the tile stores only the accum value, and we cannot change this) */ // also holds normalized normal&albedo in AOS format ispc::Tile __aligned(64) finished; //! the rbga32-converted colors // TODO: dynamically allocate to save memory when only uint32 / I8 colors vec4f __aligned(64) color[TILE_SIZE * TILE_SIZE]; }; } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/mpi_offload_worker_main.cpp000066400000000000000000000007051464752671100264270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include #include #include #include "ospray/ospray.h" int main(int argc, const char **av) { std::vector args(av, av + argc); args.push_back("--osp:load-modules=mpi_offload"); args.push_back("--osp:device=mpiOffload"); argc = args.size(); ospInit(&argc, args.data()); return 0; } RenderKit-ospray-85af292/modules/mpi/ospray/render/000077500000000000000000000000001464752671100223245ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/ospray/render/DistributedLoadBalancer.cpp000066400000000000000000000553031464752671100275500ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DistributedLoadBalancer.h" #include #include #include #include #include "ObjectHandle.h" #include "WriteMultipleTileOperation.h" #include "camera/Camera.h" #include "common/DistributedWorld.h" #include "common/DynamicLoadBalancer.h" #include "common/MPICommon.h" #include "distributed/DistributedRenderer.h" #include "fb/DistributedFrameBuffer.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/tracing/Tracing.h" #include "rkcommon/utility/ArrayView.h" #include "rkcommon/utility/getEnvVar.h" namespace ospray { namespace mpi { using namespace mpicommon; using namespace rkcommon; DistributedLoadBalancer::DistributedLoadBalancer(ObjectHandle handle) : handle(handle) {} DistributedLoadBalancer::~DistributedLoadBalancer() { handle.free(); } std::pair DistributedLoadBalancer::renderFrame( FrameBuffer *_fb, Renderer *_renderer, Camera *camera, World *_world) { auto *dfb = dynamic_cast(_fb); if (!dfb) { throw std::runtime_error( "Distributed Load Balancer only supports DistributedFrameBuffer!"); } auto *world = dynamic_cast(_world); if (!world) { throw std::runtime_error( "Distributed Load Balancer only supports DistributedWorld!"); } auto *renderer = dynamic_cast(_renderer); if (!renderer) { if (world->allRegions.size() == 1) { renderFrameReplicated(dfb, _renderer, camera, world); return std::make_pair(devicert::AsyncEvent(), devicert::AsyncEvent()); } else { throw std::runtime_error( "Distributed rendering requires a distributed renderer!"); } } if (dfb->getLastRenderer() != renderer) { dfb->setTileOperation(renderer->tileOperation(), renderer); } RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("renderFrameDistributed", "DistributedLB")); dfb->startNewFrame(renderer->errorThreshold); void *perFrameData = renderer->beginFrame(dfb, world); const size_t numRegions = world->allRegions.size(); RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("determineTilesForFrame", "DistributedLB")); std::vector> regionTileIds(world->myRegionIds.size()); const vec2i numTiles = dfb->getGlobalNumTiles(); const vec2i fbSize = dfb->getNumPixels(); for (size_t i = 0; i < world->myRegionIds.size(); ++i) { const size_t id = world->myRegionIds[i]; const auto &r = world->allRegions[id]; box3f proj = camera->projectBox(r); box2f screenRegion(vec2f(proj.lower) * fbSize, vec2f(proj.upper) * fbSize); // Pad the region a bit screenRegion.lower = max(screenRegion.lower - TILE_SIZE, vec2f(0.f)); screenRegion.upper = min(screenRegion.upper + TILE_SIZE, vec2f(fbSize)); // Skip regions that are completely behind the camera if (proj.upper.z < 0.f) { continue; } box2i tileRegion; tileRegion.lower = screenRegion.lower / TILE_SIZE; tileRegion.upper = vec2i(std::ceil(screenRegion.upper.x / TILE_SIZE), std::ceil(screenRegion.upper.y / TILE_SIZE)); tileRegion.upper = min(tileRegion.upper, numTiles); for (int y = tileRegion.lower.y; y < tileRegion.upper.y; ++y) { for (int x = tileRegion.lower.x; x < tileRegion.upper.x; ++x) { const uint32_t tileIndex = x + y * numTiles.x; const auto &owners = world->regionOwners[id]; const size_t numRegionOwners = owners.size(); const size_t ownerRank = std::distance(owners.begin(), owners.find(workerRank())); // TODO: Can we do a better than round-robin over all tiles // assignment here? It could be that we end up not evenly dividing // the workload. const bool regionTileOwner = (tileIndex % numRegionOwners) == ownerRank; // If we're the owner and this tile isn't completed by adaptive // refinement, we need to render it if (regionTileOwner) { regionTileIds[i].push_back(tileIndex); } } } } // Set up the DFB sparse layers for each region we're rendering locally // We need one SparseFB layer in the DFB per region we're rendering locally dfb->setSparseFBLayerCount(world->myRegionIds.size()); for (size_t i = 0; i < world->myRegionIds.size(); ++i) { // Layer 0 is the base "background" tiles, regions are rendered to // layers 1..# regions + 1 auto *layer = dfb->getSparseFBLayer(i + 1); // Check if this layer already stores the tiles we want, and if so don't // reset it const utility::ArrayView layerTiles = layer->getTileIDs(); // TODO: it'd be nice if we had some other change tracking that would let us // know when we have different tiles rather than having to check the lists // of IDs against each other. // If this is a new FB, or the camera/scene has changed, we should set the // new tiles because they've probably changed. If nothing in the scene is // different from the previous render, then we don't need to set new tiles // because we're just accumulating. if (layerTiles.size() != regionTileIds[i].size() || !std::equal( layerTiles.begin(), layerTiles.end(), regionTileIds[i].begin())) { layer->setTiles(regionTileIds[i]); } } RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("renderLocalData", "DistributedLB"); }); #ifdef OSPRAY_TARGET_SYCL /* For GPU: Need further refactoring to run rendering async for multiple * region per rank configs. Right now this is serial to avoid a race condition * on the SYCL queue. */ tasking::serial_for(dfb->getSparseLayerCount(), [&](size_t layer) #else tasking::parallel_for(dfb->getSparseLayerCount(), [&](size_t layer) #endif { // Just render the background color and compute visibility information // for the tiles we own for layer "0" SparseFrameBuffer *sparseFb = dfb->getSparseFBLayer(layer); if (sparseFb->getNumTiles() == 0) { return; } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::beginEvent( "setupLayerRendering", "DistributedLB")); // Explicitly avoiding std::vector because we need to match ISPC's // memory layout const utility::ArrayView tileIDs = sparseFb->getTileIDs(); // We use uint8 instead of bool to avoid hitting UB with differing // "true" values used by ISPC and C++ devicert::BufferShared regionVisible( sparseFb->getISPCDevice().getDRTDevice(), numRegions * sparseFb->getNumTiles()); std::memset(regionVisible.sharedPtr(), 0, regionVisible.size()); // Compute visibility for the tasks we're rendering RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent( "computeRegionVisibility", "DistributedLB"); }); renderer->computeRegionVisibility(sparseFb, camera, world, regionVisible.sharedPtr(), perFrameData, sparseFb->getRenderTaskIDs()); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // If we're rendering the background tiles send them over now if (layer == 0) { RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::beginEvent( "sendLayer0Tiles", "DistributedLB")); tasking::parallel_for(sparseFb->getNumTiles(), [&](size_t i) { // Don't send anything if this tile was finished due to adaptive // refinement if (dfb->tileError(tileIDs[i]) <= renderer->errorThreshold) { return; } // Just generate the bgtile properties the same way as the SparseFB // does to avoid having to read them back to the host Tile bgtile; bgtile.fbSize = sparseFb->getNumPixels(); bgtile.rcp_fbSize = rcp(vec2f(sparseFb->getNumPixels())); bgtile.region = sparseFb->getTileRegion(tileIDs[i]); bgtile.accumID = 0; bgtile.sortOrder = std::numeric_limits::max(); bgtile.generation = 0; bgtile.children = 0; bgtile.accumID = dfb->getFrameID(); for (size_t r = 0; r < numRegions; ++r) { if (regionVisible[numRegions * i + r]) { ++bgtile.children; } } // Fill the tile with the background color // TODO: Should replace this with a smaller metadata message so we // don't need to send a full tile std::fill(bgtile.r, bgtile.r + TILE_SIZE * TILE_SIZE, renderer->bgColor.x); std::fill(bgtile.g, bgtile.g + TILE_SIZE * TILE_SIZE, renderer->bgColor.y); std::fill(bgtile.b, bgtile.b + TILE_SIZE * TILE_SIZE, renderer->bgColor.z); std::fill(bgtile.a, bgtile.a + TILE_SIZE * TILE_SIZE, renderer->bgColor.w); std::fill(bgtile.z, bgtile.z + TILE_SIZE * TILE_SIZE, std::numeric_limits::infinity()); dfb->setTile(bgtile); }); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } else { // If we're rendering a region, render it and send over the tile data RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::beginEvent("renderRegionData", "DistributedLB"); rkcommon::tracing::beginEvent("initRegionTaskIDs", "DistributedLB"); rkcommon::tracing::setCounter( "regionTileCount", sparseFb->getNumTiles()); }); sparseFb->beginFrame(); const size_t rid = world->myRegionIds[layer - 1]; RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("renderRegionTasks", "DistributedLB"); }); renderer->renderRegionTasks(sparseFb, camera, world, world->allRegions[rid], perFrameData, sparseFb->getRenderTaskIDs()); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent( "readbackRegionTiles", "DistributedLB"); }); const auto tiles = sparseFb->getTiles(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("sendRegionTiles", "DistributedLB"); }); tasking::parallel_for(tiles.size(), [&](size_t i) { if (!regionVisible[numRegions * i + rid] || dfb->tileError(tileIDs[i]) <= renderer->errorThreshold) { return; } Tile ®ionTile = tiles[i]; regionTile.generation = 1; regionTile.children = 0; regionTile.accumID = dfb->getFrameID(); dfb->setTile(regionTile); }); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::endEvent(); }); } }); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("waitUntilFinished", "DistributedLB"); }); dfb->waitUntilFinished(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("postProcess", "DistributedLB"); }); // TODO: We can start to pipeline the post processing here, // but needs support from the rest of the async tasking from // MPI tasks. Right now we just run on a separate thread. devicert::AsyncEvent event = dfb->postProcess(); event.wait(); dfb->setCompletedEvent(OSP_FRAME_FINISHED); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::endEvent(); }); return std::make_pair(devicert::AsyncEvent(), devicert::AsyncEvent()); } void DistributedLoadBalancer::renderFrameReplicated(DistributedFrameBuffer *dfb, Renderer *renderer, Camera *camera, DistributedWorld *world) { int enableStaticBalancer = 0; auto OSPRAY_STATIC_BALANCER = utility::getEnvVar("OSPRAY_STATIC_BALANCER"); enableStaticBalancer = OSPRAY_STATIC_BALANCER.value_or(0); RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("renderFrameReplicated", "DistributedLB")); std::shared_ptr tileOperation = nullptr; if (dfb->getLastRenderer() != renderer) { tileOperation = std::make_shared(); dfb->setTileOperation(tileOperation, renderer); } else { tileOperation = dfb->getTileOperation(); } RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("startNewFrame", "DistributedLB")); dfb->startNewFrame(renderer->errorThreshold); void *perFrameData = renderer->beginFrame(dfb, world); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("renderLocalTiles", "DistributedLB"); }); if (enableStaticBalancer) { renderFrameReplicatedStaticLB(dfb, renderer, camera, world, perFrameData); } else { renderFrameReplicatedDynamicLB(dfb, renderer, camera, world, perFrameData); } RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("waitUntilFinished", "DistributedLB"); }); dfb->waitUntilFinished(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("postProcess", "DistributedLB"); }); // TODO: We can start to pipeline the post processing here, // but needs support from the rest of the async tasking from // MPI tasks. Right now we just run on a separate thread. devicert::AsyncEvent event = dfb->postProcess(); event.wait(); dfb->setCompletedEvent(OSP_FRAME_FINISHED); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::endEvent(); }); } std::string DistributedLoadBalancer::toString() const { return "ospray::mpi::Distributed"; } void DistributedLoadBalancer::renderFrameReplicatedDynamicLB( DistributedFrameBuffer *dfb, Renderer *renderer, Camera *camera, DistributedWorld *world, void *perFrameData) { bool askedForWork = false; const int ALLTILES = dfb->getGlobalTotalTiles(); int NTILES = ALLTILES / workerSize(); // NOTE(jda) - If all tiles do not divide evenly among all worker ranks // (a.k.a. ALLTILES / worker.size has a remainder), then // some ranks will have one extra tile to do. Thus NTILES // is incremented if we are one of those ranks. if ((ALLTILES % workerSize()) > workerRank()) NTILES++; // Do not pass all tiles at once, this way if other ranks want to steal // work, they can // We target 1/3rd of tiles per-round by default to balance between executing // work locally and allowing work to be stolen for load balancing. // This can be overridden by the environment variable // OSPRAY_MPI_LB_TILES_PER_ROUND const float percentTilesPerRound = utility::getEnvVar("OSPRAY_MPI_LB_TILES_PER_ROUND") .value_or(0.33f); const int maxTilesPerRound = std::ceil(NTILES * percentTilesPerRound); const float minActiveTilesPercent = utility::getEnvVar("OSPRAY_MPI_LB_MIN_ACTIVE_TILES") .value_or(0.25f); const int minActiveTiles = (ALLTILES / workerSize()) * minActiveTilesPercent; // Avoid division by 0 for the case that this rank doesn't have any tiles int numRounds = 0; int tilesPerRound = 0; int remainTiles = 0; if (NTILES > 0) { numRounds = std::max(NTILES / maxTilesPerRound, 1); tilesPerRound = NTILES / numRounds; remainTiles = NTILES % numRounds; } int terminatedTiles = 0; auto dynamicLB = make_unique(handle, ALLTILES); mpicommon::barrier(dfb->getMPIGroup().comm).wait(); int totalActiveTiles = ALLTILES; // push current work to workQueue for (int i = 0; i < numRounds; i++) { Work myWork; myWork.ntasks = tilesPerRound; myWork.offset = i * tilesPerRound; myWork.ownerRank = workerRank(); dynamicLB->addWork(myWork); } // Extra round for any remainder tiles if (remainTiles > 0) { Work myWork; myWork.ntasks = remainTiles; myWork.offset = numRounds * tilesPerRound; myWork.ownerRank = workerRank(); dynamicLB->addWork(myWork); } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::beginEvent( "localRenderLoop", "DistributedLB,Dynamic")); const int sparseFbChannelFlags = dfb->getChannelFlags() & ~(OSP_FB_ACCUM | OSP_FB_VARIANCE); auto sparseFb = rkcommon::make_unique(dfb->getISPCDevice(), dfb->getNumPixels(), dfb->getColorBufferFormat(), sparseFbChannelFlags); sparseFb->setFrameID(dfb->getFrameID()); sparseFb->getSh()->super.targetFrames = dfb->getSh()->targetFrames; sparseFb->getSh()->accumulate = false; // accumulation happens later while (0 < totalActiveTiles) { Work currentWorkItem; if (0 < dynamicLB->getWorkSize()) { currentWorkItem = dynamicLB->getWorkItemFront(); askedForWork = false; } if (0 < currentWorkItem.ntasks) { RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::beginEvent( "initTaskTileIDs", "DistributedLB,Dynamic")); // Allocate a sparse framebuffer to hold the render output data std::vector taskTileIDs; taskTileIDs.reserve(currentWorkItem.ntasks); for (int i = 0; i < currentWorkItem.ntasks; ++i) { const int tileID = (i + currentWorkItem.offset) * workerSize() + currentWorkItem.ownerRank; // Only render tiles if they haven't reached the error threshold if (dfb->tileError(tileID) > renderer->errorThreshold) { taskTileIDs.push_back(tileID); } } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // If all the tiles we were assigned are already finished due to adaptive // termination we have nothing to render locally so just mark the tasks // complete if (!taskTileIDs.empty()) { RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::beginEvent( "setSparseFBTiles", "DistributedLB,Dynamic")); // Set the tiles and fill the right accumID for them sparseFb->setTiles(taskTileIDs); sparseFb->beginFrame(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("renderTasks", "DistributedLB,Dynamic"); }); devicert::AsyncEvent event = renderer->renderTasks(sparseFb.get(), camera, world, perFrameData, sparseFb->getRenderTaskIDs( renderer->errorThreshold, renderer->spp)); event.wait(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent( "readbackTiles", "DistributedLB,Dynamic"); }); // TODO: Now the tile setting happens as a bulk-sync operation after // rendering, because we still need to send them through the compositing // pipeline. The ISPC-side rendering code doesn't know about this and in // the future wouldn't be able to do it // One option with the Dynamic LB would be to at least ping-poing // sparseFb's, one is being rendered into while tiles from the previous // task set are sent out const utility::ArrayView tiles = sparseFb->getTiles(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("sendTiles", "DistributedLB,Dynamic"); }); tasking::parallel_for(tiles.size(), [&](size_t i) { Tile &tile = tiles[i]; tile.accumID = dfb->getFrameID(); dfb->setTile(tile); }); } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // Mark the set of tasks as complete dynamicLB->sendTerm(currentWorkItem.ntasks); terminatedTiles = terminatedTiles + currentWorkItem.ntasks; } if (0 < terminatedTiles) { dynamicLB->updateActiveTasks(terminatedTiles); } totalActiveTiles = dynamicLB->getActiveTasks(); terminatedTiles = 0; // if the total active tiles over all workers is more than some min, // request work if (currentWorkItem.ntasks <= 0 && minActiveTiles < totalActiveTiles && !askedForWork) { dynamicLB->requestWork(); askedForWork = true; } } RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); // We need to wait for the other ranks to finish here to keep our local DLB // alive to respond to any work requests that come in while other ranks // finish their final local set of tasks mpicommon::barrier(dfb->getMPIGroup().comm).wait(); } void DistributedLoadBalancer::renderFrameReplicatedStaticLB( DistributedFrameBuffer *dfb, Renderer *renderer, Camera *camera, DistributedWorld *world, void *perFrameData) { SparseFrameBuffer *ownedTilesFb = dfb->getSparseFBLayer(0); ownedTilesFb->setFrameID(dfb->getFrameID()); ownedTilesFb->getSh()->super.targetFrames = dfb->getSh()->targetFrames; // frame 0 is not accumulated ownedTilesFb->getSh()->accumulate = dfb->getFrameID(); // Note: these views are already in USM const utility::ArrayView tileIDs = ownedTilesFb->getTileIDs(); RKCOMMON_IF_TRACING_ENABLED( rkcommon::tracing::beginEvent("localRenderLoop", "DistributedLB,Static")); devicert::AsyncEvent event = renderer->renderTasks(ownedTilesFb, camera, world, perFrameData, ownedTilesFb->getRenderTaskIDs(renderer->errorThreshold, renderer->spp)); event.wait(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("readbackTiles", "DistributedLB,Static"); }); const utility::ArrayView tiles = ownedTilesFb->getTiles(); RKCOMMON_IF_TRACING_ENABLED({ rkcommon::tracing::endEvent(); rkcommon::tracing::beginEvent("sendTiles", "DistributedLB,Static"); }); // TODO: Now the tile setting happens as a bulk-sync operation after // rendering, because we still need to send them through the compositing // pipeline. The ISPC-side rendering code doesn't know about this and in the // future wouldn't be able to do it tasking::parallel_for(tiles.size(), [&](size_t i) { // Don't send anything if this tile was finished due to adaptive // refinement if (dfb->tileError(tileIDs[i]) <= renderer->errorThreshold) { return; } dfb->setTile(tiles[i]); }); RKCOMMON_IF_TRACING_ENABLED(rkcommon::tracing::endEvent()); } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/DistributedLoadBalancer.h000066400000000000000000000031061464752671100272070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef OSPRAY_TARGET_SYCL #include #endif #include "../fb/DistributedFrameBuffer.h" #include "ObjectHandle.h" #include "camera/Camera.h" #include "common/World.h" #include "render/LoadBalancer.h" namespace ospray { namespace mpi { struct DistributedWorld; /* The distributed load balancer manages both data and image * parallel distributed rendering, based on the renderer and * world configuration. Distributed renderers will use distributed * rendering, while a non-distributed renderer with a world with * one global region will give image-parallel rendering */ struct DistributedLoadBalancer : public TiledLoadBalancer { DistributedLoadBalancer(ObjectHandle handle); ~DistributedLoadBalancer() override; std::pair renderFrame( FrameBuffer *fb, Renderer *renderer, Camera *camera, World *world) override; void renderFrameReplicated(DistributedFrameBuffer *dfb, Renderer *renderer, Camera *camera, DistributedWorld *world); std::string toString() const override; private: void renderFrameReplicatedDynamicLB(DistributedFrameBuffer *dfb, Renderer *renderer, Camera *camera, DistributedWorld *world, void *perFrameData); void renderFrameReplicatedStaticLB(DistributedFrameBuffer *dfb, Renderer *renderer, Camera *camera, DistributedWorld *world, void *perFrameData); ObjectHandle handle; }; } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/ThreadedRenderTask.h000066400000000000000000000040321464752671100261770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include // ospray #include "DistributedLoadBalancer.h" #include "common/Future.h" #include "fb/FrameBuffer.h" namespace ospray { namespace mpi { /* An asynchronous render task which runs on a thread independent * of the tasking system's thread pool */ struct ThreadedRenderTask : public Future { ThreadedRenderTask(FrameBuffer *, const std::shared_ptr &, std::function fcn); ~ThreadedRenderTask() override; bool isFinished(OSPSyncEvent event = OSP_TASK_FINISHED) override; void wait(OSPSyncEvent event) override; void cancel() override; float getProgress() override; float getTaskDuration() override; private: Ref fb; std::shared_ptr loadBalancer; std::atomic taskDuration{0.f}; std::atomic finished; std::thread thread; }; // Inlined definitions ////////////////////////////////////////////////////// inline ThreadedRenderTask::ThreadedRenderTask(FrameBuffer *_fb, const std::shared_ptr &_loadBalancer, std::function fcn) : fb(_fb), loadBalancer(_loadBalancer), finished(false) { thread = std::thread([this, fcn]() { taskDuration = fcn(); finished = true; }); } inline ThreadedRenderTask::~ThreadedRenderTask() { if (thread.joinable()) { thread.join(); } } inline bool ThreadedRenderTask::isFinished(OSPSyncEvent event) { return finished == true || fb->getLatestCompleteEvent() >= event; } inline void ThreadedRenderTask::wait(OSPSyncEvent event) { if (event == OSP_TASK_FINISHED) { while (!finished) { std::this_thread::yield(); } } else fb->waitForEvent(event); } inline void ThreadedRenderTask::cancel() { fb->cancelFrame(); } inline float ThreadedRenderTask::getProgress() { return fb->getCurrentProgress(); } inline float ThreadedRenderTask::getTaskDuration() { return taskDuration.load(); } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/WriteMultipleTileOperation.cpp000066400000000000000000000124751464752671100303460ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "WriteMultipleTileOperation.h" #include "fb/DistributedFrameBuffer.h" #include "fb/DistributedFrameBufferShared.h" #ifndef OSPRAY_TARGET_SYCL #include "fb/DistributedFrameBuffer_ispc.h" #endif namespace ospray { using namespace rkcommon; /* LiveTileOperation for image-parallel rendering, where the same image tile * could optionally be rendered by multiple ranks. */ struct LiveWriteMultipleTile : public LiveTileOperation { LiveWriteMultipleTile(DistributedFrameBuffer *dfb, const vec2i &begin, size_t tileID, size_t ownerID, WriteMultipleTileOperation *parent); void newFrame() override; // accumulate into ACCUM and VARIANCE, and for last tile read-out void process(const ispc::Tile &tile) override; private: int maxAccumID = 0; size_t instances = 1; bool writeOnceTile = true; // defer accumulation to get correct variance estimate ispc::Tile bufferedTile; bool tileBuffered = false; WriteMultipleTileOperation *parent = nullptr; // serialize when multiple instances of this tile arrive at the same time std::mutex mutex; }; LiveWriteMultipleTile::LiveWriteMultipleTile(DistributedFrameBuffer *dfb, const vec2i &begin, size_t tileID, size_t ownerID, WriteMultipleTileOperation *parent) : LiveTileOperation(dfb, begin, tileID, ownerID), parent(parent) {} void LiveWriteMultipleTile::newFrame() { maxAccumID = 0; instances = parent->tileInstances[tileID]; writeOnceTile = instances <= 1; tileBuffered = false; } void LiveWriteMultipleTile::process(const ispc::Tile &tile) { if (writeOnceTile) { finished.region = tile.region; finished.fbSize = tile.fbSize; finished.rcp_fbSize = tile.rcp_fbSize; accumulate(tile); tileIsFinished(); return; } bool done = false; if (tile.accumID == 0) { finished.region = tile.region; finished.fbSize = tile.fbSize; finished.rcp_fbSize = tile.rcp_fbSize; const auto bytes = tile.region.size().y * (TILE_SIZE * sizeof(float)); memcpy(accum.z, tile.z, bytes); memcpy(finished.z, tile.z, bytes); } { std::lock_guard lock(mutex); maxAccumID = std::max(maxAccumID, tile.accumID); if (!tileBuffered && (tile.accumID & 1) == 0) { memcpy(&bufferedTile, &tile, sizeof(ispc::Tile)); tileBuffered = true; } else { ispc::DFB_accumulateTileSimple((const ispc::VaryingTile *)&tile, (ispc::VaryingTile *)&accum, (ispc::VaryingTile *)&variance); if (dfb->hasNormalBuf() || dfb->hasAlbedoBuf()) { ispc::DFB_accumulateAuxTile((const ispc::VaryingTile *)&tile, (ispc::Tile *)&finished, (ispc::VaryingTile *)&accum); } } done = --instances == 0; } if (done) { auto sz = tile.region.size(); if ((maxAccumID & 1) == 0) { // if maxAccumID is even, variance buffer is one accumulated tile // short, which leads to vast over-estimation of variance; thus // estimate variance now, when accum buffer is also one (the buffered) // tile short const float prevErr = DFB_computeErrorForTile(sz, (ispc::VaryingTile *)&accum, (ispc::VaryingTile *)&variance, maxAccumID - 1); // use maxAccumID for correct normalization // this is OK, because both accumIDs are even bufferedTile.accumID = maxAccumID; accumulate(bufferedTile); error = prevErr; } else { // correct normalization is with maxAccumID, which is odd here bufferedTile.accumID = maxAccumID; // but original bufferedTile.accumID is always even and thus won't be // accumulated into variance buffer DFB_accumulateTile((const ispc::VaryingTile *)&bufferedTile, (ispc::VaryingTile *)&finished, (ispc::VaryingTile *)&accum, (ispc::VaryingTile *)&variance, dfb->doAccumulation(), // disable accumulation of variance false); if (dfb->hasNormalBuf() || dfb->hasAlbedoBuf()) { ispc::DFB_accumulateAuxTile((const ispc::VaryingTile *)&bufferedTile, (ispc::Tile *)&finished, (ispc::VaryingTile *)&accum); } // but still need to update the error error = DFB_computeErrorForTile(sz, (ispc::VaryingTile *)&accum, (ispc::VaryingTile *)&variance, maxAccumID); } tileIsFinished(); } } WriteMultipleTileOperation::~WriteMultipleTileOperation() { if (mpiGroup.comm != MPI_COMM_NULL) { MPI_Comm_free(&mpiGroup.comm); } } void WriteMultipleTileOperation::attach(DistributedFrameBuffer *dfb) { if (mpiGroup.comm != MPI_COMM_NULL) { MPI_Comm_free(&mpiGroup.comm); } mpiGroup = mpicommon::worker.dup(); tileInstances.resize(dfb->getGlobalTotalTiles(), 1); } std::unique_ptr WriteMultipleTileOperation::makeTile( DistributedFrameBuffer *dfb, const vec2i &tileBegin, size_t tileID, size_t ownerID) { return make_unique( dfb, tileBegin, tileID, ownerID, this); } std::string WriteMultipleTileOperation::toString() const { return "ospray::WriteMultipleTileOperation"; } void WriteMultipleTileOperation::syncTileInstances() { mpicommon::bcast( tileInstances.data(), tileInstances.size(), MPI_INT, 0, mpiGroup.comm) .wait(); } } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/WriteMultipleTileOperation.h000066400000000000000000000013771464752671100300120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "../fb/TileOperation.h" #include "common/MPICommon.h" #include "rkcommon/containers/AlignedVector.h" namespace ospray { struct WriteMultipleTileOperation : public TileOperation { virtual ~WriteMultipleTileOperation() override; void attach(DistributedFrameBuffer *dfb) override; std::unique_ptr makeTile(DistributedFrameBuffer *dfb, const vec2i &tileBegin, size_t tileID, size_t ownerID) override; std::string toString() const override; void syncTileInstances(); rkcommon::containers::AlignedVector tileInstances; mpicommon::Group mpiGroup; }; } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/000077500000000000000000000000001464752671100246465ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/AlphaCompositeTileOperation.cpp000066400000000000000000000111411464752671100327570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "AlphaCompositeTileOperation.h" #include #include "fb/DistributedFrameBuffer.h" #ifndef OSPRAY_TARGET_SYCL #include "fb/DistributedFrameBuffer_ispc.h" #endif namespace ospray { struct BufferedTile { ispc::Tile tile; /*! determines order of this tile relative to other tiles. Tiles will get blended with the 'over' operator in increasing 'BufferedTile::sortOrder' value */ float sortOrder; }; /* LiveTileOperation for data-parallel or hybrid-parallel rendering, where * different (or partially shared) data is rendered on each rank */ struct LiveAlphaCompositeTile : public LiveTileOperation { LiveAlphaCompositeTile(DistributedFrameBuffer *dfb, const vec2i &begin, size_t tileID, size_t ownerID); void newFrame() override; void process(const ispc::Tile &tile) override; private: std::vector> bufferedTiles; int currentGeneration{0}; int expectedInNextGeneration{0}; int missingInCurrentGeneration{1}; std::mutex mutex; void reportCompositingError(const vec2i &tile); }; LiveAlphaCompositeTile::LiveAlphaCompositeTile(DistributedFrameBuffer *dfb, const vec2i &begin, size_t tileID, size_t ownerID) : LiveTileOperation(dfb, begin, tileID, ownerID) {} void LiveAlphaCompositeTile::newFrame() { std::lock_guard lock(mutex); currentGeneration = 0; expectedInNextGeneration = 0; missingInCurrentGeneration = 1; if (!bufferedTiles.empty()) { handleError(OSP_INVALID_OPERATION, std::to_string(mpicommon::workerRank()) + " is starting with buffered tiles!"); } } void LiveAlphaCompositeTile::process(const ispc::Tile &tile) { std::lock_guard lock(mutex); { auto addTile = rkcommon::make_unique(); std::memcpy(&addTile->tile, &tile, sizeof(tile)); bufferedTiles.push_back(std::move(addTile)); } if (tile.generation == currentGeneration) { --missingInCurrentGeneration; expectedInNextGeneration += tile.children; if (missingInCurrentGeneration < 0) { reportCompositingError(tile.region.lower); } while (missingInCurrentGeneration == 0 && expectedInNextGeneration > 0) { currentGeneration++; missingInCurrentGeneration = expectedInNextGeneration; expectedInNextGeneration = 0; for (uint32_t i = 0; i < bufferedTiles.size(); i++) { const BufferedTile *bt = bufferedTiles[i].get(); if (bt->tile.generation == currentGeneration) { --missingInCurrentGeneration; expectedInNextGeneration += bt->tile.children; } if (missingInCurrentGeneration < 0) { reportCompositingError(tile.region.lower); } } } } if (missingInCurrentGeneration < 0) { reportCompositingError(tile.region.lower); } if (missingInCurrentGeneration == 0) { // Sort for back-to-front blending // TODO: This is redundant with sortAndBlend. We should actually just do // this tile level sort, not sorting each pixel /* std::sort(bufferedTiles.begin(), bufferedTiles.end(), [](const std::unique_ptr &a, const std::unique_ptr &b) { return a->tile.sortOrder > b->tile.sortOrder; }); */ Tile **tileArray = STACK_BUFFER(Tile *, bufferedTiles.size()); std::transform(bufferedTiles.begin(), bufferedTiles.end(), tileArray, [](std::unique_ptr &t) { return &t->tile; }); ispc::DFB_sortAndBlendFragments( (ispc::VaryingTile **)tileArray, bufferedTiles.size()); finished.region = tile.region; finished.fbSize = tile.fbSize; finished.rcp_fbSize = tile.rcp_fbSize; accumulate(bufferedTiles[0]->tile); bufferedTiles.clear(); tileIsFinished(); } } void LiveAlphaCompositeTile::reportCompositingError(const vec2i &tile) { std::stringstream str; str << "negative missing on " << mpicommon::workerRank() << ", missingInCurrent = " << missingInCurrentGeneration << ", expectedInNext = " << expectedInNextGeneration << ", currentGeneration = " << currentGeneration << ", tile = " << tile; handleError(OSP_INVALID_OPERATION, str.str()); } std::unique_ptr AlphaCompositeTileOperation::makeTile( DistributedFrameBuffer *dfb, const vec2i &tileBegin, size_t tileID, size_t ownerID) { return make_unique(dfb, tileBegin, tileID, ownerID); } std::string AlphaCompositeTileOperation::toString() const { return "ospray::AlphaCompositeTileOperation"; } } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/AlphaCompositeTileOperation.h000066400000000000000000000007231464752671100324300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "../../fb/TileOperation.h" namespace ospray { struct AlphaCompositeTileOperation : public TileOperation { std::unique_ptr makeTile(DistributedFrameBuffer *dfb, const vec2i &tileBegin, size_t tileID, size_t ownerID) override; std::string toString() const override; }; } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRaycast.cpp000066400000000000000000000075211464752671100311700ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include #include #include #include #include "common/Data.h" #include "lights/AmbientLight.h" #include "lights/Light.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/utility/getEnvVar.h" #include "AlphaCompositeTileOperation.h" #include "DistributedRaycast.h" #include "common/DistributedWorld.h" #include "fb/DistributedFrameBuffer.h" // ispc exports #ifndef OSPRAY_TARGET_SYCL #include "render/distributed/DistributedRaycast_ispc.h" #else #include "common/FeatureFlags.ih" namespace ispc { SYCL_EXTERNAL void DistributedRaycast_renderRegionToTileTask(void *_self, void *_fb, void *_camera, void *_world, const void *_region, void *perFrameData, const void *_taskIDs, const int taskIndex0, const uniform FeatureFlagsHandler &ffh); } #endif namespace ospray { namespace mpi { using namespace std::chrono; using namespace mpicommon; // DistributedRaycastRenderer definitions ///////////////////////////////// DistributedRaycastRenderer::DistributedRaycastRenderer(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device), mpiGroup(mpicommon::worker.dup()) {} DistributedRaycastRenderer::~DistributedRaycastRenderer() { MPI_Comm_free(&mpiGroup.comm); } void DistributedRaycastRenderer::commit() { Renderer::commit(); getSh()->aoSamples = getParam("aoSamples", 0); getSh()->aoRadius = getParam("aoDistance", 1e20f); getSh()->shadowsEnabled = getParam("shadows", false); getSh()->volumeSamplingRate = getParam("volumeSamplingRate", 1.f); } std::shared_ptr DistributedRaycastRenderer::tileOperation() { return std::make_shared(); } #ifndef OSPRAY_TARGET_SYCL void DistributedRaycastRenderer::renderRegionTasks(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, const box3f ®ion, void *perFrameData, const utility::ArrayView &taskIDs) const { ispc::DistributedRaycast_renderRegionToTileTask(getSh(), fb->getSh(), camera->getSh(), world->getSh(), (ispc::box3f *)®ion, perFrameData, taskIDs.data(), taskIDs.size()); } #else void DistributedRaycastRenderer::renderRegionTasks(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, const box3f ®ion, void *perFrameData, const utility::ArrayView &taskIDs) const { auto *rendererSh = getSh(); auto *fbSh = fb->getSh(); auto *cameraSh = camera->getSh(); auto *worldSh = world->getSh(); const uint32_t *taskIDsPtr = taskIDs.data(); const size_t numTasks = taskIDs.size(); sycl::queue *queue = static_cast(device.getDRTDevice().getSyclQueuePtr()); auto event = queue->submit([&](sycl::handler &cgh) { FeatureFlags ff = world->getFeatureFlags(); ff |= featureFlags; ff |= fb->getFeatureFlags(); ff |= camera->getFeatureFlags(); cgh.set_specialization_constant(ff); cgh.parallel_for(fb->getDispatchRange(numTasks), [=](sycl::nd_item<3> taskIndex, sycl::kernel_handler kh) { const box3f regionCopy = region; if (taskIndex.get_global_id(0) < numTasks) { ispc::FeatureFlagsHandler ffh(kh); ispc::DistributedRaycast_renderRegionToTileTask(&rendererSh->super, fbSh, cameraSh, worldSh, (ispc::box3f *)®ionCopy, perFrameData, taskIDsPtr, taskIndex.get_global_id(0), ffh); } }); }); event.wait_and_throw(); } #endif std::string DistributedRaycastRenderer::toString() const { return "ospray::mpi::DistributedRaycastRenderer"; } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRaycast.h000066400000000000000000000035141464752671100306330ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include // ospray #include "../../common/DistributedWorld.h" #include "DistributedRenderer.h" #include "camera/PerspectiveCamera.h" #include "common/MPICommon.h" // ispc shared #include "DistributedRaycastShared.h" namespace ospray { namespace mpi { /* The distributed raycast renderer supports rendering distributed * geometry and volume data, assuming that the data distribution is suitable * for sort-last compositing. Specifically, the data must be organized * among nodes such that each nodes region is convex and disjoint from the * others. The renderer uses the 'regions' data set on the distributed world * from the MPIDistributedDevice to determine the number of tiles to * render and expect for compositing. */ struct DistributedRaycastRenderer : public AddStructShared { DistributedRaycastRenderer(api::ISPCDevice &device); virtual ~DistributedRaycastRenderer() override; void commit() override; std::string toString() const override; std::shared_ptr tileOperation() override; #ifndef OSPRAY_TARGET_SYCL void renderRegionTasks(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, const box3f ®ion, void *perFrameData, const utility::ArrayView &taskIDs) const override; #else void renderRegionTasks(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, const box3f ®ion, void *perFrameData, const utility::ArrayView &taskIDs) const override; #endif private: // The communicator to use for collectives in the renderer mpicommon::Group mpiGroup; }; } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRaycast.ispc000066400000000000000000000354511464752671100313470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "rkcommon/math/box.ih" #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/FeatureFlags.ih" #include "common/Instance.ih" #include "common/Intersect.ih" #include "common/VolumeIntervals.ih" #include "common/World.ih" #include "fb/FrameBufferDispatch.ih" #include "fb/RenderTaskDesc.ih" #include "math/random.ih" #include "math/sampling.ih" #include "render/Renderer.ih" #include "render/ScreenSample.ih" #include "render/materials/OBJ.ih" #include "render/scivis/surfaces.ih" #include "render/scivis/volumes.ih" #include "render/util.ih" #include "texture/Texture2D.ih" #include "volume/VolumetricModel.ih" #ifdef OSPRAY_ENABLE_VOLUMES #include "volume/Volume.ih" #include "volume/VolumetricModel.ih" #include "volume/transferFunction/LinearTransferFunction.ih" #include "volume/transferFunction/TransferFunctionDispatch.ih" #endif // c++ shared #include "DistributedRaycastShared.h" #include "common/DistributedWorldShared.h" #include "fb/FrameBufferShared.h" #include "fb/SparseFBShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE #ifdef OSPRAY_ENABLE_VOLUMES // The distributed raycast renderer uses its own volume interval integration // because we want to apply the jitter before offsetting our step size to stay // inside the region, not after. inline vec4f DRR_integrateVolumeInterval(const VolumeInterval &interval, Ray &ray, uniform float samplingRate, const uniform FeatureFlagsHandler &ffh) { const uniform FeatureFlags ff = getFeatureFlags(ffh); VolumetricModel *varying volModel = interval.volumetricModel; // Note: required to WA compiler dropping symbols on link incorrectly if (volModel == NULL) { LinearTransferFunction_get(NULL, 0.f); } Ray transformedRay = ray; AffineSpace3f instanceRcpXfm = interval.instance->rcp_xfm; transformRay(transformedRay, instanceRcpXfm); uniform uint8 intervalIteratorBuffer[VKL_MAX_INTERVAL_ITERATOR_SIZE]; vec3f color = make_vec3f(0.f); float alpha = 0.f; foreach_unique (vm in volModel) { Volume *uniform volume = vm->volume; float time = 0.5f; VKLIntervalIterator intervalIterator = vklInitIntervalIteratorV(&vm->vklIntervalContext, (varying vkl_vec3f *)&ray.org, (varying vkl_vec3f *)&ray.dir, (varying vkl_range1f *)&interval.interval, #ifndef OSPRAY_TARGET_SYCL & #endif time, (void *uniform)intervalIteratorBuffer #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ); VKLInterval interval; while (vklIterateIntervalV(intervalIterator, &interval #ifdef OSPRAY_TARGET_SYCL , ff.volume #endif ) && alpha < 0.99f) { const float nominalSamplingDt = interval.nominalDeltaT / samplingRate; // initial sub interval, based on our renderer-defined sampling rate // and the volume's nominal dt box1f subInterval = make_box1f(interval.tRange.lower, min(interval.tRange.lower + nominalSamplingDt, interval.tRange.upper)); while (subInterval.upper - subInterval.lower > 0.f && alpha < 0.99f) { transformedRay.t0 = subInterval.lower + (subInterval.upper - subInterval.lower); const float dt = subInterval.upper - subInterval.lower; // Get volume sample vec3f p = transformedRay.org + transformedRay.t0 * transformedRay.dir; const float sample = vklComputeSampleV(&volume->vklSampler, (const varying vkl_vec3f *uniform) & p #ifdef OSPRAY_TARGET_SYCL , 0, time, ff.volume #endif ); if (!isnan(sample)) { vec4f sampleColorOpacity = TransferFunction_dispatch_get(vm->transferFunction, sample); sampleColorOpacity.w = 1.f - pow(1.f - sampleColorOpacity.w * vm->densityScale, dt / interval.nominalDeltaT); const float clampedOpacity = clamp(sampleColorOpacity.w); color = color + ((1.f - alpha) * clampedOpacity * make_vec3f(sampleColorOpacity)); alpha = alpha + ((1.f - alpha) * clampedOpacity); } // compute next sub interval subInterval.lower = subInterval.upper; subInterval.upper = min(subInterval.lower + nominalSamplingDt, interval.tRange.upper); } } } return make_vec4f(color, alpha); } #endif inline float computeAO(const DistributedRaycastRenderer *uniform self, const FrameBuffer *uniform fb, const World *uniform world, const varying vec3i &sampleID, const varying DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { const uniform int &sampleCnt = self->aoSamples; const uniform int accumID = reduce_max(sampleID.z) * sampleCnt; // init TEA RNG // RandomTEA rng_state; varying RandomTEA *const uniform rng = &rng_state; RandomTEA_Constructor(rng, 0x290374, (fb->size.x * sampleID.y) + sampleID.x); const vec2f rot = RandomTEA_getFloats(rng); int hits = 0; const linear3f localToWorld = frame(dg.Ns); for (uniform int i = 0; i < sampleCnt; i++) { const vec2f halton = HaltonSequence_get2D(accumID + i); const vec2f r = CranleyPattersonRotation(halton, rot); const vec3f local_ao_dir = cosineSampleHemisphere(r); const vec3f ao_dir = localToWorld * local_ao_dir; if (dot(ao_dir, dg.Ns) < 0.05f) { // check below surface hits++; continue; } Ray ao_ray; setRay(ao_ray, dg.P, ao_dir, dg.epsilon, self->aoRadius); if (isOccluded(world, ao_ray, ffh)) hits++; } // the cosTheta of cosineSampleHemispherePDF and dot(shadingNormal, ao_dir) // cancel return 1.0f - (hits / (float)sampleCnt); } inline vec4f DRR_shadeSurface(const DistributedRaycastRenderer *uniform self, const FrameBuffer *uniform fb, const DistributedWorld *uniform world, const vec3i &sampleID, const Ray &ray, const DifferentialGeometry &dg, const uniform FeatureFlagsHandler &ffh) { // TODO: DRR should have its own support for OBJ material and lighting model vec3f surfaceColor = make_vec3f(dg.color); float opacity = 1.f; const OBJ *mat = (const OBJ *)dg.material; if (mat) { foreach_unique (m in mat) { surfaceColor = surfaceColor * m->Kd; opacity = m->d; if (valid(m->KdMap)) { vec4f kdFromMap = get4f(m->KdMap, dg); surfaceColor = surfaceColor * make_vec3f(kdFromMap); } } } // Just eyelight for now... const float eyeLightIntensity = absf(dot(dg.Ns, ray.dir)); vec3f color = surfaceColor * eyeLightIntensity; if (self->aoSamples > 0) { float ao = computeAO(self, fb, &world->super, sampleID, dg, ffh); color = color * ao; } return make_vec4f(color, opacity); #if 0 // TODO LIGHTS // Calculate shading for all lights for (uniform int i = 0; self->lights && i < self->numLights; i++) { const uniform Light *uniform l = self->lights[i]; const vec2f s = make_vec2f(0.0f); // sample center of area lights const Light_SampleRes light = l->sample(l, dg, s); // any potential contribution? if (reduce_max(light.weight) > 0.f) { float cosNL = dot(light.dir, info.shadingNormal); if (cosNL < 0.0f) continue; cosNL = abs(cosNL); const vec3f H = normalize(light.dir - ray.dir); const float cosNH = dot(H, info.shadingNormal); const vec3f specular = info.Ks * powf(cosNH, info.Ns); const vec3f diffuse = info.Kd * cosNL; const vec3f light_contrib = info.local_opacity * (diffuse + specular) * light.weight; if (self->shadowsEnabled) { const float max_contrib = reduce_max(light_contrib); if (max_contrib > self->super.minContribution) { vec3f P = dg.P; if (dot(dg.Ng, light.dir) < 0.0f) { P = P - (2.f * dg.epsilon) * dg.Ng; } Ray shadowRay; setRay(shadowRay, P, light.dir, 0.0f, light.dist, 0.5f); if (!isOccluded(model, shadowRay) && !(ghostModel && isOccluded(ghostModel, shadowRay))) { color = color + light_contrib; } } } else { color = color + light_contrib; } } } #endif } // TODO: Better separate geometry and volume code in this function inline void DRR_renderRegionSample(Renderer *uniform _self, SparseFB *uniform fb, DistributedWorld *uniform world, const box3f *uniform /*region*/, const vec2f ®ionInterval, void *uniform /*perFrameData*/, varying ScreenSample &sample, const uniform FeatureFlagsHandler &ffh) { DistributedRaycastRenderer *uniform self = (DistributedRaycastRenderer * uniform) _self; const uniform FeatureFlags ff = getFeatureFlags(ffh); Ray &geomRay = sample.ray; Ray volumeRay = sample.ray; traceRay(&world->super, geomRay, ffh); #ifdef OSPRAY_ENABLE_VOLUMES VolumeInterval volumeInterval; if (ff.volume) { traceVolumeRay(&world->super, volumeRay, volumeInterval); volumeInterval.interval.lower = max(volumeInterval.interval.lower, regionInterval.x); volumeInterval.interval.upper = min(volumeInterval.interval.upper, regionInterval.y); sample.z = min(geomRay.t, volumeInterval.interval.lower); } else #endif { sample.z = geomRay.t; } // TODO: Doesn't seem like much jittering happens with the volume integration vec4f outputColor = make_vec4f(0.f); while (outputColor.w < 0.99f) { const bool haveGeometryHit = ff.geometry ? hadHit(geomRay) && geomRay.t >= regionInterval.x && geomRay.t <= regionInterval.y : false; #ifdef OSPRAY_ENABLE_VOLUMES const bool haveVolumeHit = ff.volume ? hasInterval(volumeInterval) : false; const bool bothHit = haveGeometryHit && haveVolumeHit; const bool eitherHit = haveGeometryHit || haveVolumeHit; const bool volumeFirst = ff.volume ? volumeInterval.interval.lower < geomRay.t : false; #else const bool bothHit = false; const bool eitherHit = haveGeometryHit; #endif if (!eitherHit) { break; } vec4f volumeColor = make_vec4f(0.f); vec4f surfaceColor = make_vec4f(0.f); DifferentialGeometry dg; if (haveGeometryHit && ff.geometry) { postIntersect(&world->super, &self->super, dg, geomRay, sample.rayCone, DG_NG | DG_NS | DG_NORMALIZE | DG_FACEFORWARD | DG_COLOR | DG_TEXCOORD, ffh); surfaceColor = DRR_shadeSurface( self, &fb->super, world, sample.sampleID, geomRay, dg, ffh); } #ifdef OSPRAY_ENABLE_VOLUMES // Always just integrate the volume when it comes in front of the geometry if (haveVolumeHit && volumeFirst && ff.volume) { volumeInterval.interval.upper = min(geomRay.t, volumeInterval.interval.upper); // Keep the interval within the region volumeInterval.interval.lower = max(volumeInterval.interval.lower, regionInterval.x); volumeInterval.interval.upper = min(volumeInterval.interval.upper, regionInterval.y); // Offset the volume interval start to align to the same sampling steps // across each rank, and apply the same jitter for each pixel on all ranks float dt = 1.f /*was 'volModel->samplingStep*/ / self->volumeSamplingRate; float t0 = volumeInterval.interval.lower; volumeInterval.interval.lower = floor(t0 / dt) * dt; float jitter = Halton_sample2(sample.sampleID.z); int ix = sample.sampleID.x % 4; int iy = sample.sampleID.y % 4; int patternID = ix + 4 * iy; jitter += Halton_sample3(patternID); if (jitter > 1.f) { jitter -= 1.f; } volumeInterval.interval.lower += jitter * dt; if (volumeInterval.interval.lower < t0) { volumeInterval.interval.lower += dt; } // TODO: At edges when coloring all bricks the same I do still see // some edge/border artifacts setRay(volumeRay, volumeInterval.interval.lower, volumeInterval.interval.upper); volumeColor = DRR_integrateVolumeInterval( volumeInterval, volumeRay, self->volumeSamplingRate, ffh); } #endif vec4f blendedColor = make_vec4f(0.f); if (bothHit) { blendedColor = volumeColor + (1.0f - volumeColor.w) * surfaceColor; } else { if (haveGeometryHit) blendedColor = surfaceColor; else blendedColor = volumeColor; } outputColor = outputColor + (1.0f - outputColor.w) * blendedColor; if (haveGeometryHit) setRay(geomRay, geomRay.t + dg.epsilon, regionInterval.y + 0.0001f); else setRay(geomRay, geomRay.t, geomRay.t0); // Step the volume ray forwards as well volumeRay = geomRay; traceRay(&world->super, geomRay, ffh); #ifdef OSPRAY_ENABLE_VOLUMES if (ff.volume) { traceVolumeRay(&world->super, volumeRay, volumeInterval); } #endif } sample.rgb = make_vec3f(outputColor); sample.alpha = outputColor.w; } // Exported functions ///////////////////////////////////////////////////////// #define renderRegionSampleFn DRR_renderRegionSample #include "render/distributed/DistributedRendererRenderTaskFn.inl" #undef renderRegionSampleFn #ifdef OSPRAY_TARGET_SYCL SYCL_EXTERNAL void DistributedRaycast_renderRegionToTileTask( void *uniform _self, void *uniform _fb, void *uniform _camera, void *uniform _world, const void *uniform _region, void *uniform perFrameData, const void *uniform _taskIDs, const int taskIndex0, const uniform FeatureFlagsHandler &ffh) { Renderer *uniform self = (Renderer * uniform) _self; SparseFB *uniform fb = (SparseFB * uniform) _fb; Camera *uniform camera = (Camera * uniform) _camera; DistributedWorld *uniform world = (DistributedWorld * uniform) _world; const box3f *uniform region = (const box3f *uniform)_region; const uint32 *uniform taskIDs = (const uint32 *uniform)_taskIDs; DR_default_renderRegionToTile( self, fb, camera, world, region, perFrameData, taskIDs, taskIndex0, ffh); } #else export void DistributedRaycast_renderRegionToTileTask(void *uniform _self, void *uniform _fb, void *uniform _camera, void *uniform _world, void *uniform _region, void *uniform perFrameData, void *uniform _taskIDs, uniform uint32 numTasks) { Renderer *uniform self = (Renderer * uniform) _self; SparseFB *uniform fb = (SparseFB * uniform) _fb; Camera *uniform camera = (Camera * uniform) _camera; DistributedWorld *uniform world = (DistributedWorld * uniform) _world; const box3f *uniform region = (const box3f *uniform)_region; const uint32 *uniform taskIDs = (const uint32 *uniform)_taskIDs; uniform FeatureFlagsHandler ffh; launch[numTasks] DR_default_renderRegionToTile( self, fb, camera, world, region, perFrameData, taskIDs, ffh); sync; } #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRaycastShared.h000066400000000000000000000010411464752671100317530ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "render/RendererShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus struct DistributedRaycastRenderer { Renderer super; int aoSamples; float aoRadius; bool shadowsEnabled; float volumeSamplingRate; #ifdef __cplusplus DistributedRaycastRenderer() : aoSamples(0), aoRadius(1e20f), shadowsEnabled(false), volumeSamplingRate(1.f) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRenderer.cpp000066400000000000000000000105261464752671100313270ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "DistributedRenderer.h" #include "../../common/DistributedWorld.h" #include "common/Instance.h" #include "geometry/GeometricModel.h" // ispc exports #ifndef OSPRAY_TARGET_SYCL #include "render/distributed/DistributedRenderer_ispc.h" #else #include "common/FeatureFlags.ih" namespace ispc { SYCL_EXTERNAL void DR_default_computeRegionVisibility(Renderer *uniform self, SparseFB *uniform fb, Camera *uniform camera, DistributedWorld *uniform world, uint8 *uniform regionVisible, void *uniform perFrameData, const uint32 *uniform taskIDs, const int taskIndex0, const uniform FeatureFlagsHandler &ff); } #endif namespace ospray { namespace mpi { DistributedRenderer::DistributedRenderer(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device), mpiGroup(mpicommon::worker.dup()) {} DistributedRenderer::~DistributedRenderer() { MPI_Comm_free(&mpiGroup.comm); } void DistributedRenderer::computeRegionVisibility(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, uint8_t *regionVisible, void *perFrameData, const utility::ArrayView &taskIDs) const { #ifndef OSPRAY_TARGET_SYCL ispc::DistributedRenderer_computeRegionVisibility(getSh(), fb->getSh(), camera->getSh(), world->getSh(), regionVisible, perFrameData, taskIDs.data(), taskIDs.size()); #else auto *rendererSh = getSh(); auto *fbSh = fb->getSh(); auto *cameraSh = camera->getSh(); auto *worldSh = world->getSh(); const uint32_t *taskIDsPtr = taskIDs.data(); const size_t numTasks = taskIDs.size(); sycl::queue *queue = static_cast(device.getDRTDevice().getSyclQueuePtr()); auto event = queue->submit([&](sycl::handler &cgh) { FeatureFlags ff = world->getFeatureFlags(); ff.other = FFO_NONE; ff |= fb->getFeatureFlags(); ff |= camera->getFeatureFlags(); // Disable features we don't need for the region visibility computation ff.geometry = FFG_BOX; #ifdef OSPRAY_ENABLE_VOLUMES ff.volume = VKL_FEATURE_FLAGS_NONE; #endif cgh.set_specialization_constant(ff); cgh.parallel_for(fb->getDispatchRange(numTasks), [=](sycl::nd_item<3> taskIndex, sycl::kernel_handler kh) { if (taskIndex.get_global_id(0) < numTasks) { ispc::FeatureFlagsHandler ffh(kh); ispc::DR_default_computeRegionVisibility(rendererSh, fbSh, cameraSh, worldSh, regionVisible, perFrameData, taskIDsPtr, taskIndex.get_global_id(0), ffh); } }); }); event.wait_and_throw(); #endif } OSPPickResult DistributedRenderer::pick( FrameBuffer *fb, Camera *camera, World *world, const vec2f &screenPos) { OSPPickResult res; res.instance = nullptr; res.model = nullptr; res.primID = RTC_INVALID_GEOMETRY_ID; res.hasHit = false; int instID = RTC_INVALID_GEOMETRY_ID; int geomID = RTC_INVALID_GEOMETRY_ID; int primID = RTC_INVALID_GEOMETRY_ID; float depth = 1e20f; #ifndef OSPRAY_TARGET_SYCL // TODO for SYCL need to dispatch a kernel ispc::DistributedRenderer_pick(getSh(), fb->getSh(), camera->getSh(), world->getSh(), (const ispc::vec2f &)screenPos, (ispc::vec3f &)res.worldPosition[0], instID, geomID, primID, depth, res.hasHit); #else // Silence unused parameter warning (void)fb; (void)camera; (void)screenPos; #endif // Find the closest picked object globally, only the rank // with this object will report the pick float globalDepth = 1e20f; mpicommon::allreduce( &depth, &globalDepth, 1, MPI_FLOAT, MPI_MIN, mpiGroup.comm) .wait(); res.hasHit = globalDepth < 1e20f && globalDepth == depth; if (res.hasHit) { auto *instance = (*world->instances)[instID]; auto *group = instance->group.ptr; if (!group->geometricModels) { res.hasHit = false; return res; } auto *model = (*group->geometricModels)[geomID]; instance->refInc(); model->refInc(); res.instance = (OSPInstance)instance; res.model = (OSPGeometricModel)model; res.primID = static_cast(primID); } return res; } } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRenderer.h000066400000000000000000000036511464752671100307750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "camera/Camera.h" #include "fb/DistributedFrameBuffer.h" #include "fb/TileOperation.h" #include "render/Renderer.h" // ispc shared #include "render/RendererShared.h" namespace ospray { namespace mpi { struct DistributedWorld; struct RegionInfo { int numRegions = 0; box3f *regions = nullptr; uint8_t *regionVisible = nullptr; }; struct DistributedRenderer : public AddStructShared { DistributedRenderer(api::ISPCDevice &device); ~DistributedRenderer() override; void computeRegionVisibility(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, uint8_t *regionVisible, void *perFrameData, const utility::ArrayView &taskIDs) const; // Not used by distributed renderers devicert::AsyncEvent renderTasks(FrameBuffer *, Camera *, World *, void * /*perFrameData*/, const utility::ArrayView & /*taskIDs*/) const override { return devicert::AsyncEvent(); } #ifndef OSPRAY_TARGET_SYCL virtual void renderRegionTasks(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, const box3f ®ion, void *perFrameData, const utility::ArrayView &taskIDs) const = 0; #else virtual void renderRegionTasks(SparseFrameBuffer *fb, Camera *camera, DistributedWorld *world, const box3f ®ion, void *perFrameData, const utility::ArrayView &taskIDs) const = 0; #endif virtual std::shared_ptr tileOperation() = 0; // Picking in the distributed renderer needs to be clipped to the regions // specified to bound the local data OSPPickResult pick(FrameBuffer *fb, Camera *camera, World *world, const vec2f &screenPos) override; private: mpicommon::Group mpiGroup; }; } // namespace mpi } // namespace ospray RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRenderer.ispc000066400000000000000000000234151464752671100315040ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "OSPConfig.h" #include "fb/RenderTaskDesc.ih" #include "render/ScreenSample.ih" #include "rkcommon/math/vec.ih" #include "rkcommon/utility/random.ih" #include "camera/Camera.ih" #include "camera/CameraDispatch.ih" #include "common/FilterIntersect.ih" #include "common/Intersect.ih" #include "common/Ray.ih" #include "common/RayQueryContext.ih" #include "common/World.ih" #include "fb/RenderTaskDesc.ih" #include "fb/SparseFB.ih" #include "geometry/BoxesShared.h" #include "geometry/GeometryDispatch.ih" #include "math/random.ih" #include "render/ScreenSample.ih" #include "rkcommon/utility/random.ih" #include "texture/Texture2D.ih" // c++ shared #include "common/DistributedWorldShared.h" #include "fb/FrameBufferDispatch.ih" #include "fb/FrameBufferShared.h" #include "fb/SparseFBShared.h" #include "render/RendererShared.h" OSPRAY_BEGIN_ISPC_NAMESPACE struct RayQueryContextRegion { RTCRayQueryContext ectx; const FeatureFlagsHandler *uniform ffh; uint8 *regionVisible; }; RTC_SYCL_INDIRECTLY_CALLABLE unmasked void Regions_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args) { // make sure to set the mask if (!args->valid[programIndex]) { return; } // We never mark hits because we want to find all hits along the ray to get // all visible regions args->valid[programIndex] = 0; Boxes *uniform self = (Boxes * uniform) args->geometryUserPtr; varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; uniform int primID = args->primID; uniform box3f box = get_box3f(self->boxes, primID); // Note: not calling filterIntersectionBoth here because it will set the hit // on the ray, we don't want to record any hits so that we can find all // regions along the ray const Intersections isect = intersectBox(ray->org, ray->dir, box); if ((isect.entry.hit && isect.entry.t > ray->t0 && isect.entry.t <= ray->t) || (isect.exit.hit && isect.exit.t > ray->t0 && isect.exit.t <= ray->t)) { RayQueryContextRegion *uniform ctx = (RayQueryContextRegion * uniform) args->context; uint8 *uniform regionVisible = (uint8 * uniform) ctx->regionVisible; regionVisible[primID] = 0xff; } } #ifndef OSPRAY_TARGET_SYCL task #endif SYCL_EXTERNAL void DR_default_computeRegionVisibility(Renderer *uniform self, SparseFB *uniform fb, Camera *uniform camera, DistributedWorld *uniform world, uint8 *uniform regionVisible, void *uniform /*perFrameData*/, const uint32 *uniform taskIDs, #ifdef OSPRAY_TARGET_SYCL const int taskIndex0, #endif const uniform FeatureFlagsHandler &ffh) { ScreenSample screenSample; screenSample.z = inf; screenSample.alpha = 0.f; CameraSample cameraSample; uniform RenderTaskDesc taskDesc = FrameBuffer_dispatch_getRenderTaskDesc( &fb->super, taskIDs[taskIndex0], ffh); if (fb->super.cancelRender || isEmpty(taskDesc.region)) { return; } // Get the region visibility info for this tile uint8 *uniform tileRegionVisible = regionVisible + world->numRegions * SparseFB_getTileIndexForTask(fb, taskDesc.taskID); // Take fixed, consistent samples to determine if a region is really visible // for a tile. We can trace up to 5 rays, one through the center of the pixel // and one through each corner, or 4 (one through each corner), or just 1 // (through the middle). Tracing 5 against the boxes may be a bit much? It // shouldn't impact performance too badly, but is actually a lot of rays being // traced Alternatively we could just base this on the region projection, and // accept the more conservative bounds. This would require some benchmarking // to see where the scaling trade off hits of sending tiles we don't actually // need. // Right now just taking 1 sample, can benchmark this in the future and/or // refactor code further to use this result to do a scan/compaction on the // render task IDs to reduce tasks launched. Then the accumIDs can be sync'd // up again const uniform int nVisibilitySamples = 1; const uniform vec2f visibilitySamples[5] = {make_vec2f(0.5f, 0.5f), make_vec2f(0.0f, 0.0f), make_vec2f(1.0f, 0.0f), make_vec2f(0.0f, 1.0f), make_vec2f(1.0f, 1.0f)}; #ifdef OSPRAY_TARGET_SYCL for (int32 y = taskDesc.region.lower.y; y < taskDesc.region.upper.y; ++y) for (int32 x = taskDesc.region.lower.x; x < taskDesc.region.upper.x; ++x) { #else foreach_tiled (y = taskDesc.region.lower.y... taskDesc.region.upper.y, x = taskDesc.region.lower.x... taskDesc.region.upper.x) { #endif screenSample.sampleID.x = x; screenSample.sampleID.y = y; // set ray t value for early ray termination if we have a maximum depth // texture vec2f center = make_vec2f(screenSample.sampleID.x, screenSample.sampleID.y) + 0.5f; const float tMax = Renderer_getMaxDepth(self, center * fb->super.rcpSize, ffh); for (uniform uint32 s = 0; s < nVisibilitySamples; s++) { screenSample.sampleID.z = s; cameraSample.screen.x = (screenSample.sampleID.x + visibilitySamples[s].x) * fb->super.rcpSize.x; cameraSample.screen.y = (screenSample.sampleID.y + visibilitySamples[s].y) * fb->super.rcpSize.y; // no DoF or MB per default cameraSample.lens.x = 0.0f; cameraSample.lens.y = 0.0f; cameraSample.time = 0.5f; Camera_dispatch_initRay( camera, screenSample.ray, screenSample.rayCone, cameraSample, ffh); // take screen resolution (unnormalized coordinates), i.e., pixel size // into account screenSample.rayCone.dwdt *= fb->super.rcpSize.y; screenSample.rayCone.width *= fb->super.rcpSize.y; screenSample.ray.t = min(screenSample.ray.t, tMax); if (world->regionScene) { uniform RayQueryContextRegion context; rtcInitRayQueryContext(&context.ectx); context.ffh = &ffh; context.regionVisible = tileRegionVisible; uniform RTCIntersectArguments intersectArgs; rtcInitIntersectArguments(&intersectArgs); // Use a custom intersection function instead of a global filter // function, since global filter functions were removed in Embree4 intersectArgs.intersect = (RTCIntersectFunctionN)Regions_intersect_kernel; intersectArgs.flags = RTC_RAY_QUERY_FLAG_COHERENT; intersectArgs.feature_mask = (uniform RTCFeatureFlags)(RTC_FEATURE_FLAG_INSTANCE | RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS); intersectArgs.context = &context.ectx; rtcIntersectV(world->regionScene, (varying RTCRayHit * uniform) & screenSample.ray, &intersectArgs); } } } } #ifndef OSPRAY_TARGET_SYCL export void DistributedRenderer_computeRegionVisibility(void *uniform _self, void *uniform fb, void *uniform camera, void *uniform world, uint8 *uniform regionVisible, void *uniform perFrameData, void *uniform _taskIDs, uniform int numTasks) { Renderer *uniform self = (uniform Renderer * uniform) _self; const uint32 *uniform taskIDs = (const uint32 *uniform)_taskIDs; uniform FeatureFlagsHandler ffh; launch[numTasks] DR_default_computeRegionVisibility(self, (SparseFB * uniform) fb, (Camera * uniform) camera, (DistributedWorld * uniform) world, regionVisible, perFrameData, taskIDs, ffh); } #ifndef OSPRAY_TARGET_SYCL export void DistributedRenderer_pick(const void *uniform _self, const void *uniform _fb, const void *uniform _camera, const void *uniform _world, const uniform vec2f &screenPos, uniform vec3f &pos, uniform int32 &instID, uniform int32 &geomID, uniform int32 &primID, uniform float &depth, uniform int32 &hit) { uniform FeatureFlagsHandler ffh; const Renderer *uniform self = (const Renderer *uniform)_self; const FrameBuffer *uniform fb = (const FrameBuffer *uniform)_fb; const Camera *uniform camera = (const Camera *uniform)_camera; const DistributedWorld *uniform world = (const DistributedWorld *uniform)_world; CameraSample cameraSample; cameraSample.screen.x = screenPos.x; cameraSample.screen.y = screenPos.y; // use center of lens and shutter time cameraSample.lens.x = 0.0f; cameraSample.lens.y = 0.0f; cameraSample.time = 0.5f; Ray ray; RayCone rayCone; Camera_dispatch_initRay(camera, ray, rayCone, cameraSample, ffh); ray.t = min(ray.t, Renderer_getMaxDepth(self, cameraSample.screen, ffh)); // Clip the ray to each region this rank owns and trace the clipped ray to // find the picked object float closestHit = 1e20f; for (uniform int i = 0; i < world->numLocalRegions; ++i) { // Separate ray per-region to allow clipping by the region's bounds Ray regionRay = ray; regionRay.t = min(ray.t, closestHit); const Intersections isect = intersectBox(regionRay.org, regionRay.dir, world->localRegions[i]); if (isect.entry.t < isect.exit.t && isect.exit.t >= regionRay.t0 && isect.entry.t <= regionRay.t) { regionRay.t0 = isect.entry.t; regionRay.t = min(regionRay.t, isect.exit.t); traceRay(&world->super, regionRay, ffh); if (hadHit(regionRay)) { closestHit = regionRay.t; vec3f p = regionRay.org + regionRay.dir * regionRay.t; pos.x = extract(p.x, 0); pos.y = extract(p.y, 0); pos.z = extract(p.z, 0); hit = extract((int)(hadHit(regionRay)), 0); instID = extract(regionRay.instID, 0); geomID = extract(regionRay.geomID, 0); primID = extract(regionRay.primID, 0); depth = extract(regionRay.t, 0); } } } } #endif #endif OSPRAY_END_ISPC_NAMESPACE RenderKit-ospray-85af292/modules/mpi/ospray/render/distributed/DistributedRendererRenderTaskFn.inl000066400000000000000000000106241464752671100335750ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifndef OSPRAY_TARGET_SYCL task #endif static void DR_default_renderRegionToTile(Renderer *uniform self, SparseFB *uniform fb, Camera *uniform camera, DistributedWorld *uniform world, const box3f *uniform region, void *uniform perFrameData, const uint32 *uniform taskIDs, #ifdef OSPRAY_TARGET_SYCL const int taskIndex0, #endif const uniform FeatureFlagsHandler &ffh) { const uniform int32 spp = self->spp; ScreenSample screenSample; screenSample.z = inf; screenSample.alpha = 0.f; CameraSample cameraSample; uniform RenderTaskDesc taskDesc = FrameBuffer_dispatch_getRenderTaskDesc( &fb->super, taskIDs[taskIndex0], ffh); const uniform int startSampleID = fb->super.frameID * spp + 1; // Halton Sequence starts with 1 #ifdef OSPRAY_TARGET_SYCL #if 0 // Dummy top level print so that prints at lower levels of the kernel // will work See JIRA https://jira.devtools.intel.com/browse/XDEPS-4729 if (taskIndex0 == 0) { cl::sycl::ext::oneapi::experimental::printf(""); } #endif #endif if (isEmpty(taskDesc.region)) { return; } #ifdef OSPRAY_TARGET_SYCL for (int32 y = taskDesc.region.lower.y; y < taskDesc.region.upper.y; ++y) for (int32 x = taskDesc.region.lower.x; x < taskDesc.region.upper.x; ++x) { #else foreach_tiled (y = taskDesc.region.lower.y... taskDesc.region.upper.y, x = taskDesc.region.lower.x... taskDesc.region.upper.x) { #endif screenSample.sampleID.x = x; screenSample.sampleID.y = y; // set ray t value for early ray termination (from maximum depth texture) vec2f center = make_vec2f(screenSample.sampleID.x, screenSample.sampleID.y) + 0.5f; const float tMax = Renderer_getMaxDepth(self, center * fb->super.rcpSize, ffh); vec3f col = make_vec3f(0.f); float alpha = 0.f; vec3f normal = make_vec3f(0.f); vec3f albedo = make_vec3f(0.f); // TODO: same note on spp > 1 issues for (uniform int32 s = 0; s < spp; s++) { const float pixel_du = Halton_sample2(startSampleID + s); const float pixel_dv = CranleyPattersonRotation( Halton_sample3(startSampleID + s), 1.f / 6.f); screenSample.sampleID.z = startSampleID + s; cameraSample.screen.x = (screenSample.sampleID.x + pixel_du) * fb->super.rcpSize.x; cameraSample.screen.y = (screenSample.sampleID.y + pixel_dv) * fb->super.rcpSize.y; // no DoF or MB per default cameraSample.lens.x = 0.0f; cameraSample.lens.y = 0.0f; cameraSample.time = 0.5f; Camera_dispatch_initRay( camera, screenSample.ray, screenSample.rayCone, cameraSample, ffh); // take screen resolution (unnormalized coordinates), i.e., pixel size // into account screenSample.rayCone.dwdt *= fb->super.rcpSize.y; screenSample.rayCone.width *= fb->super.rcpSize.y; screenSample.ray.t = min(screenSample.ray.t, tMax); // TODO: We could store and use the region t intervals from when // we did the visibility test? Intersections isect = intersectBox(screenSample.ray.org, screenSample.ray.dir, *region); if (isect.entry.t < isect.exit.t && isect.exit.t >= screenSample.ray.t0 && isect.entry.t <= screenSample.ray.t) { const float regionEnter = max(isect.entry.t, screenSample.ray.t0); const float regionExit = min(isect.exit.t, screenSample.ray.t); screenSample.ray.t0 = regionEnter; screenSample.ray.t = regionExit; renderRegionSampleFn(self, fb, world, region, make_vec2f(regionEnter, regionExit), perFrameData, screenSample, ffh); col = col + screenSample.rgb; alpha += screenSample.alpha; normal = normal + screenSample.normal; albedo = albedo + screenSample.albedo; } } const float rspp = rcpf(spp); screenSample.rgb = col * rspp; screenSample.alpha = alpha * rspp; screenSample.normal = normal * rspp; screenSample.albedo = albedo * rspp; FrameBuffer_dispatch_accumulateSample( &fb->super, screenSample, taskDesc, ffh); } FrameBuffer_dispatch_completeTask(&fb->super, taskDesc, ffh); } RenderKit-ospray-85af292/modules/mpi/testing/000077500000000000000000000000001464752671100212055ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/testing/CMakeLists.txt000066400000000000000000000007641464752671100237540ustar00rootroot00000000000000## 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_gtest_utils MPI::MPI_CXX ) ospray_sign_target(ospMPIDistribTestSuite) install(TARGETS ospMPIDistribTestSuite DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps ) RenderKit-ospray-85af292/modules/mpi/testing/distributed_test_fixture.cpp000066400000000000000000000073121464752671100270430ustar00rootroot00000000000000// 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 RenderKit-ospray-85af292/modules/mpi/testing/distributed_test_fixture.h000066400000000000000000000022351464752671100265070ustar00rootroot00000000000000// 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 RenderKit-ospray-85af292/modules/mpi/testing/ospMPIDistribTestSuite.cpp000066400000000000000000000047411464752671100262610ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include "distributed_test_fixture.h" #include "rkcommon/utility/getEnvVar.h" OSPRayEnvironment *ospEnv; namespace MPIDistribOSPRayTestScenes { TEST_P(MPIFromOsprayTesting, test_scenes) { PerformRenderTest(); } #ifdef OSPRAY_ENABLE_VOLUMES INSTANTIATE_TEST_SUITE_P(MPIDistribTestScenesVolumes, MPIFromOsprayTesting, ::testing::Combine( ::testing::Values( "gravity_spheres_isosurface", "vdb_volume", "particle_volume"), ::testing::Values(1))); #endif 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; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = rkcommon::utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } { 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; } RenderKit-ospray-85af292/modules/mpi/tutorials/000077500000000000000000000000001464752671100215565ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/mpi/tutorials/CMakeLists.txt000066400000000000000000000065711464752671100243270ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 find_package(MPI REQUIRED) if (OSPRAY_ENABLE_APPS_TUTORIALS) # build ospTutorial, for demonstration and API testing add_executable(ospMPIDistribTutorial ${OSPRAY_RESOURCE} ospMPIDistribTutorial.c) target_link_libraries(ospMPIDistribTutorial PRIVATE ospray ${MPI_C_LIBRARIES}) target_include_directories(ospMPIDistribTutorial PRIVATE ${MPI_C_INCLUDE_DIRS}) install(TARGETS ospMPIDistribTutorial DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mpi ) ospray_sign_target(ospMPIDistribTutorial) # C++ version add_executable(ospMPIDistribTutorialCpp ${OSPRAY_RESOURCE} ospMPIDistribTutorial.cpp) target_link_libraries(ospMPIDistribTutorialCpp PRIVATE ospray rkcommon::rkcommon MPI::MPI_CXX ) target_compile_definitions(ospMPIDistribTutorialCpp PRIVATE OSPRAY_CPP_RKCOMMON_TYPES) install(TARGETS ospMPIDistribTutorialCpp DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mpi ) ospray_sign_target(ospMPIDistribTutorialCpp) # async version add_executable(ospMPIDistribTutorialAsync ${OSPRAY_RESOURCE} ospMPIDistribTutorialAsync.c) target_link_libraries(ospMPIDistribTutorialAsync PRIVATE ospray ${MPI_C_LIBRARIES}) target_include_directories(ospMPIDistribTutorialAsync PRIVATE ${MPI_C_INCLUDE_DIRS}) install(TARGETS ospMPIDistribTutorialAsync DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mpi ) ospray_sign_target(ospMPIDistribTutorialAsync) endif() if (OSPRAY_ENABLE_APPS_EXAMPLES) # prefer libGL over libOpenGl for better compatibility with SWR set(OpenGL_GL_PREFERENCE "LEGACY") find_package(OpenGL 2 REQUIRED) macro(ospray_create_mpi_tutorial tutorial_name) add_executable(${tutorial_name} ${OSPRAY_RESOURCE} ${ARGN}) target_link_libraries(${tutorial_name} PRIVATE mpi_tutorial_common) install(TARGETS ${tutorial_name} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mpi ) endmacro() # MPI Tutorial utilities library add_library(mpi_tutorial_common STATIC GLFWDistribOSPRayWindow.cpp ) target_include_directories(mpi_tutorial_common PRIVATE ${CMAKE_SOURCE_DIR}/apps/ospExamples/) target_link_libraries(mpi_tutorial_common PUBLIC rkcommon::rkcommon ospray ospray_imgui ${OPENGL_LIBRARIES} arcball_camera MPI::MPI_CXX ) target_compile_definitions(mpi_tutorial_common PUBLIC OSPRAY_CPP_RKCOMMON_TYPES) ospray_create_mpi_tutorial(ospMPIDistribTutorialSpheres ospMPIDistribTutorialSpheres.cpp ) ospray_sign_target(ospMPIDistribTutorialSpheres) ospray_create_mpi_tutorial(ospMPIDistribTutorialVolume ospMPIDistribTutorialVolume.cpp ) ospray_sign_target(ospMPIDistribTutorialVolume) ospray_create_mpi_tutorial(ospMPIDistribTutorialPartialRepl ospMPIDistribTutorialPartialRepl.cpp ) ospray_sign_target(ospMPIDistribTutorialPartialRepl) ospray_create_mpi_tutorial(ospMPIDistribTutorialReplicated ospMPIDistribTutorialReplicated.cpp ) ospray_sign_target(ospMPIDistribTutorialReplicated) target_link_libraries(ospMPIDistribTutorialReplicated PUBLIC ospray_testing ) ospray_create_mpi_tutorial(ospMPIDistributedExamples ospMPIDistributedExamples.cpp ) ospray_sign_target(ospMPIDistributedExamples) target_link_libraries(ospMPIDistributedExamples PUBLIC ospray_testing ) endif() RenderKit-ospray-85af292/modules/mpi/tutorials/GLFWDistribOSPRayWindow.cpp000066400000000000000000000266201464752671100265760ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "GLFWDistribOSPRayWindow.h" #include #include #include #include #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" using namespace ospray; using namespace rkcommon::math; GLFWDistribOSPRayWindow *GLFWDistribOSPRayWindow::activeWindow = nullptr; static bool g_quitNextFrame = false; WindowState::WindowState() : quit(false), cameraChanged(false), fbSizeChanged(false), spp(1), windowSize(0), eyePos(0.f), lookDir(0.f), upDir(0.f) {} GLFWDistribOSPRayWindow::GLFWDistribOSPRayWindow(const vec2i &windowSize, const box3f &worldBounds, cpp::World world, cpp::Renderer renderer) : windowSize(windowSize), worldBounds(worldBounds), world(world), renderer(renderer) { MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); if (mpiRank == 0) { if (activeWindow != nullptr) { throw std::runtime_error( "Cannot create more than one GLFWDistribOSPRayWindow!"); } activeWindow = this; // initialize GLFW if (!glfwInit()) { throw std::runtime_error("Failed to initialize GLFW!"); } glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); #ifdef __APPLE_ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); const char *glslVersion = "#version 150"; #else glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); const char *glslVersion = "#version 130"; #endif glfwWindow = glfwCreateWindow( windowSize.x, windowSize.y, "OSPRay Tutorial", NULL, NULL); if (!glfwWindow) { glfwTerminate(); throw std::runtime_error("Failed to create GLFW window!"); } // make the window's context current glfwMakeContextCurrent(glfwWindow); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO &io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; ImGui_ImplGlfw_InitForOpenGL(glfwWindow, false); // set GLFW callbacks glfwSetFramebufferSizeCallback( glfwWindow, [](GLFWwindow *, int newWidth, int newHeight) { activeWindow->reshape(vec2i{newWidth, newHeight}); }); glfwSetCursorPosCallback(glfwWindow, [](GLFWwindow *, double x, double y) { ImGuiIO &io = ImGui::GetIO(); if (!io.WantCaptureMouse) { activeWindow->motion(vec2f{float(x), float(y)}); } }); glfwSetKeyCallback( glfwWindow, [](GLFWwindow *, int key, int, int action, int) { if (action == GLFW_PRESS) { switch (key) { case GLFW_KEY_G: activeWindow->showUi = !(activeWindow->showUi); break; case GLFW_KEY_Q: g_quitNextFrame = true; break; } } }); // will chain our callbacks above ImGui_ImplGlfw_InstallCallbacks(glfwWindow); ImGui_ImplOpenGL3_Init(glslVersion); // set initial OpenGL state glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); // create OpenGL frame buffer texture glGenTextures(1, &framebufferTexture); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, framebufferTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // OSPRay setup // create the arcball camera model arcballCamera = std::unique_ptr( new ArcballCamera(worldBounds, windowSize)); // create camera camera = cpp::Camera("perspective"); camera.setParam("aspect", windowSize.x / float(windowSize.y)); camera.setParam("position", arcballCamera->eyePos()); camera.setParam("direction", arcballCamera->lookDir()); camera.setParam("up", arcballCamera->upDir()); camera.commit(); renderer.commit(); windowState.windowSize = windowSize; windowState.eyePos = arcballCamera->eyePos(); windowState.lookDir = arcballCamera->lookDir(); windowState.upDir = arcballCamera->upDir(); if (mpiRank == 0) { // trigger window reshape events with current window size glfwGetFramebufferSize( glfwWindow, &this->windowSize.x, &this->windowSize.y); reshape(this->windowSize); } } GLFWDistribOSPRayWindow::~GLFWDistribOSPRayWindow() { if (mpiRank == 0) { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(glfwWindow); glfwTerminate(); } } GLFWDistribOSPRayWindow *GLFWDistribOSPRayWindow::getActiveWindow() { return activeWindow; } cpp::World GLFWDistribOSPRayWindow::getWorld() { return world; } void GLFWDistribOSPRayWindow::setWorld(cpp::World newWorld) { world = newWorld; addObjectToCommit(world.handle()); } void GLFWDistribOSPRayWindow::resetAccumulation() { framebuffer.resetAccumulation(); } void GLFWDistribOSPRayWindow::registerDisplayCallback( std::function callback) { displayCallback = callback; } void GLFWDistribOSPRayWindow::registerImGuiCallback( std::function callback) { uiCallback = callback; } void GLFWDistribOSPRayWindow::mainLoop() { while (true) { MPI_Bcast(&windowState, sizeof(WindowState), MPI_BYTE, 0, MPI_COMM_WORLD); if (windowState.quit) { break; } // TODO: Actually render asynchronously, if we have MPI thread multiple // support startNewOSPRayFrame(); waitOnOSPRayFrame(); if (mpiRank == 0) { glfwPollEvents(); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); if (displayCallback) displayCallback(this); display(); windowState.quit = glfwWindowShouldClose(glfwWindow) || g_quitNextFrame; } } } void GLFWDistribOSPRayWindow::reshape(const vec2i &newWindowSize) { windowSize = newWindowSize; windowState.windowSize = windowSize; windowState.fbSizeChanged = true; // update camera arcballCamera->updateWindowSize(windowSize); // reset OpenGL viewport and orthographic projection glViewport(0, 0, windowSize.x, windowSize.y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, windowSize.x, 0.0, windowSize.y, -1.0, 1.0); } void GLFWDistribOSPRayWindow::motion(const vec2f &position) { static vec2f previousMouse(-1); const vec2f mouse(position.x, position.y); if (previousMouse != vec2f(-1)) { const bool leftDown = glfwGetMouseButton(glfwWindow, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS; const bool rightDown = glfwGetMouseButton(glfwWindow, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS; const bool middleDown = glfwGetMouseButton(glfwWindow, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS; const vec2f prev = previousMouse; bool cameraChanged = leftDown || rightDown || middleDown; if (leftDown) { const vec2f mouseFrom(clamp(prev.x * 2.f / windowSize.x - 1.f, -1.f, 1.f), clamp(prev.y * 2.f / windowSize.y - 1.f, -1.f, 1.f)); const vec2f mouseTo(clamp(mouse.x * 2.f / windowSize.x - 1.f, -1.f, 1.f), clamp(mouse.y * 2.f / windowSize.y - 1.f, -1.f, 1.f)); arcballCamera->rotate(mouseFrom, mouseTo); } else if (rightDown) { arcballCamera->zoom(mouse.y - prev.y); } else if (middleDown) { arcballCamera->pan(vec2f(mouse.x - prev.x, prev.y - mouse.y)); } if (cameraChanged) { windowState.cameraChanged = true; windowState.eyePos = arcballCamera->eyePos(); windowState.lookDir = arcballCamera->lookDir(); windowState.upDir = arcballCamera->upDir(); } } previousMouse = mouse; } void GLFWDistribOSPRayWindow::display() { // clock used to compute frame rate static auto displayStart = std::chrono::high_resolution_clock::now(); if (showUi && uiCallback) { ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize; ImGui::Begin( "Tutorial Controls (press 'g' to hide / show)", nullptr, flags); uiCallback(); ImGui::End(); } updateTitleBar(); static bool firstFrame = true; if (firstFrame || currentFrame.isReady()) { // display frame rate in window title auto displayEnd = std::chrono::high_resolution_clock::now(); auto durationMilliseconds = std::chrono::duration_cast( displayEnd - displayStart); latestFPS = 1000.f / float(durationMilliseconds.count()); // map OSPRay frame buffer, update OpenGL texture with its contents, then // unmap uint32_t *fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); glBindTexture(GL_TEXTURE_2D, framebufferTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windowSize.x, windowSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, fb); framebuffer.unmap(fb); // Start new frame and reset frame timing interval start displayStart = std::chrono::high_resolution_clock::now(); firstFrame = false; } // clear current OpenGL color buffer glClear(GL_COLOR_BUFFER_BIT); // render textured quad with OSPRay frame buffer contents glBegin(GL_QUADS); glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f); glTexCoord2f(0.f, 1.f); glVertex2f(0.f, windowSize.y); glTexCoord2f(1.f, 1.f); glVertex2f(windowSize.x, windowSize.y); glTexCoord2f(1.f, 0.f); glVertex2f(windowSize.x, 0.f); glEnd(); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(glfwWindow); } void GLFWDistribOSPRayWindow::startNewOSPRayFrame() { bool fbNeedsClear = false; auto handles = objectsToCommit.consume(); if (!handles.empty()) { for (auto &h : handles) ospCommit(h); fbNeedsClear = true; } if (windowState.fbSizeChanged) { windowState.fbSizeChanged = false; windowSize = windowState.windowSize; framebuffer = cpp::FrameBuffer( windowSize.x, windowSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); camera.setParam("aspect", windowSize.x / float(windowSize.y)); camera.commit(); fbNeedsClear = true; } if (windowState.cameraChanged) { windowState.cameraChanged = false; camera.setParam("aspect", windowSize.x / float(windowSize.y)); camera.setParam("position", windowState.eyePos); camera.setParam("direction", windowState.lookDir); camera.setParam("up", windowState.upDir); camera.commit(); fbNeedsClear = true; } if (fbNeedsClear) { resetAccumulation(); } currentFrame = framebuffer.renderFrame(renderer, camera, world); } void GLFWDistribOSPRayWindow::waitOnOSPRayFrame() { if (currentFrame.handle() != nullptr) { currentFrame.wait(OSP_FRAME_FINISHED); } } void GLFWDistribOSPRayWindow::addObjectToCommit(OSPObject obj) { objectsToCommit.push_back(obj); } void GLFWDistribOSPRayWindow::updateTitleBar() { std::stringstream windowTitle; windowTitle << "OSPRay: " << std::setprecision(3) << latestFPS << " fps"; if (latestFPS < 2.f) { float progress = currentFrame.progress(); windowTitle << " | "; int barWidth = 20; std::string progBar; progBar.resize(barWidth + 2); auto start = progBar.begin() + 1; auto end = start + progress * barWidth; std::fill(start, end, '='); std::fill(end, progBar.end(), '_'); *end = '>'; progBar.front() = '['; progBar.back() = ']'; windowTitle << progBar; } glfwSetWindowTitle(glfwWindow, windowTitle.str().c_str()); } RenderKit-ospray-85af292/modules/mpi/tutorials/GLFWDistribOSPRayWindow.h000066400000000000000000000053471464752671100262460ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "ArcballCamera.h" #include "rkcommon/containers/TransactionalBuffer.h" #include "rkcommon/math/box.h" #include "rkcommon/math/vec.h" // ospray #include "ospray/ospray.h" #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" struct WindowState { bool quit; bool cameraChanged; bool fbSizeChanged; int spp; rkcommon::math::vec2i windowSize; rkcommon::math::vec3f eyePos; rkcommon::math::vec3f lookDir; rkcommon::math::vec3f upDir; WindowState(); }; class GLFWDistribOSPRayWindow { public: GLFWDistribOSPRayWindow(const rkcommon::math::vec2i &windowSize, const rkcommon::math::box3f &worldBounds, ospray::cpp::World world, ospray::cpp::Renderer renderer); ~GLFWDistribOSPRayWindow(); static GLFWDistribOSPRayWindow *getActiveWindow(); ospray::cpp::World getWorld(); void setWorld(ospray::cpp::World newWorld); void resetAccumulation(); void registerDisplayCallback( std::function callback); void registerImGuiCallback(std::function callback); void mainLoop(); void addObjectToCommit(OSPObject obj); protected: void reshape(const rkcommon::math::vec2i &newWindowSize); void motion(const rkcommon::math::vec2f &position); void display(); void startNewOSPRayFrame(); void waitOnOSPRayFrame(); void updateTitleBar(); static GLFWDistribOSPRayWindow *activeWindow; rkcommon::math::vec2i windowSize; rkcommon::math::box3f worldBounds; ospray::cpp::World world = nullptr; ospray::cpp::Renderer renderer = nullptr; int mpiRank = -1; int mpiWorldSize = -1; // GLFW window instance GLFWwindow *glfwWindow = nullptr; // Arcball camera instance std::unique_ptr arcballCamera; // OSPRay objects managed by this class ospray::cpp::Camera camera = nullptr; ospray::cpp::FrameBuffer framebuffer = nullptr; ospray::cpp::Future currentFrame = nullptr; // List of OSPRay handles to commit before the next frame rkcommon::containers::TransactionalBuffer objectsToCommit; // OpenGL framebuffer texture GLuint framebufferTexture = 0; // optional registered display callback, called before every display() std::function displayCallback; // toggles display of ImGui UI, if an ImGui callback is provided bool showUi = true; // optional registered ImGui callback, called during every frame to build UI std::function uiCallback; // FPS measurement of last frame float latestFPS{0.f}; // The window state to be sent out over MPI to the other rendering processes WindowState windowState; }; RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorial.c000066400000000000000000000202071464752671100261370ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial how to use OSPRay and the * MPIDistributedDevice in a data-parallel application. * Each rank must specify the same render parameters, however the data * to render on each rank can differ for distributed rendering. In this * tutorial each rank renders a unique quad, which is colored by the rank. * * On Linux build it in the build_directory with: * mpicc -std=c99 ../modules/mpi/tutorials/ospMPIDistributedTutorial.c \ * -I ../ospray/include \ * -L . -lospray -Wl,-rpath,. \ * -o ospMPIDistributedTutorial * * Then run it with MPI on some number of processes * mpirun -n ./ospMPIDistributedTutorial * * The output image should show a sequence of quads, from dark to light blue */ #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include // helper function to write the rendered image as PPM file void writePPM( const char *fileName, int size_x, int size_y, const uint32_t *pixel) { FILE *file = fopen(fileName, "wb"); if (!file) { fprintf(stderr, "fopen('%s', 'wb') failed: %d", fileName, errno); return; } fprintf(file, "P6\n%i %i\n255\n", size_x, size_y); unsigned char *out = (unsigned char *)alloca(3 * size_x); for (int y = 0; y < size_y; y++) { const unsigned char *in = (const unsigned char *)&pixel[(size_y - 1 - y) * size_x]; for (int x = 0; x < size_x; x++) { out[3 * x + 0] = in[4 * x + 0]; out[3 * x + 1] = in[4 * x + 1]; out[3 * x + 2] = in[4 * x + 2]; } fwrite(out, 3 * size_x, sizeof(char), file); } fprintf(file, "\n"); fclose(file); } 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); // image size int imgSizeX = 1024; // width int imgSizeY = 768; // height // camera float cam_pos[] = {(mpiWorldSize + 1.f) / 2.f, 0.5f, -mpiWorldSize * 0.5f}; float cam_up[] = {0.f, 1.f, 0.f}; float cam_view[] = {0.0f, 0.f, 1.f}; // all ranks specify the same rendering parameters, with the exception of // the data to be rendered, which is distributed among the ranks // triangle mesh data float vertex[] = { mpiRank, 0.0f, 3.5f, mpiRank, 1.0f, 3.0f, 1.0f * (mpiRank + 1.f), 0.0f, 3.0f, 1.0f * (mpiRank + 1.f), 1.0f, 2.5f, }; float color[] = {0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f, 0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f, 0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f, 0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f}; int32_t index[] = {0, 1, 2, 1, 2, 3}; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device. This can also be done by passing --osp:mpi-distributed when // using ospInit, however if the user doesn't pass this argument your // application will likely not behave as expected ospLoadModule("mpi_distributed_cpu"); OSPDevice mpiDevice = ospNewDevice("mpiDistributed"); ospDeviceCommit(mpiDevice); ospSetCurrentDevice(mpiDevice); // create and setup camera OSPCamera camera = ospNewCamera("perspective"); ospSetFloat(camera, "aspect", imgSizeX / (float)imgSizeY); ospSetParam(camera, "position", OSP_VEC3F, cam_pos); ospSetParam(camera, "direction", OSP_VEC3F, cam_view); ospSetParam(camera, "up", OSP_VEC3F, cam_up); ospCommit(camera); // commit each object to indicate modifications are done // create and setup model and mesh OSPGeometry mesh = ospNewGeometry("mesh"); OSPData data = ospNewSharedData1D(vertex, OSP_VEC3F, 4); ospCommit(data); ospSetObject(mesh, "vertex.position", data); ospRelease(data); // we are done using this handle data = ospNewSharedData1D(color, OSP_VEC4F, 4); ospCommit(data); ospSetObject(mesh, "vertex.color", data); ospRelease(data); // we are done using this handle data = ospNewSharedData1D(index, OSP_VEC3UI, 2); ospCommit(data); ospSetObject(mesh, "index", data); ospRelease(data); // we are done using this handle ospCommit(mesh); // put the mesh into a model OSPGeometricModel model = ospNewGeometricModel(mesh); ospCommit(model); ospRelease(mesh); // put the model into a group (collection of models) OSPGroup group = ospNewGroup(); OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1); ospSetObject(group, "geometry", geometricModels); ospCommit(group); ospRelease(model); ospRelease(geometricModels); // put the group into an instance (give the group a world transform) OSPInstance instance = ospNewInstance(group); ospCommit(instance); ospRelease(group); // put the instance in the world OSPWorld world = ospNewWorld(); OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1); ospSetObject(world, "instance", instances); ospRelease(instance); ospRelease(instances); // In the distributed device we set a clipping region to clip to the data // owned uniquely by this rank which it should be rendering float regionBounds[] = {mpiRank, 0.f, 2.5f, 1.f * (mpiRank + 1.f), 1.f, 3.5f}; data = ospNewSharedData1D(regionBounds, OSP_BOX3F, 1); ospCommit(data); ospSetObject(world, "region", data); ospRelease(data); ospCommit(world); // create the mpi_raycast renderer (required for distributed rendering) OSPRenderer renderer = ospNewRenderer("mpiRaycast"); // create and setup light for Ambient Occlusion // TODO: Who gets the lights now? OSPLight light = ospNewLight("ambient"); ospCommit(light); OSPData lights = ospNewSharedData1D(&light, OSP_LIGHT, 1); ospCommit(lights); // complete setup of renderer ospSetFloat(renderer, "backgroundColor", 1.0f); // white, transparent ospSetObject(renderer, "light", lights); ospCommit(renderer); // create and setup framebuffer OSPFrameBuffer framebuffer = ospNewFrameBuffer(imgSizeX, imgSizeY, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); ospResetAccumulation(framebuffer); // Try picking an object OSPPickResult pickResult; ospPick(&pickResult, framebuffer, renderer, camera, world, 0.5f, 0.5f); if (pickResult.hasHit) { printf( "Rank %d: ospPick() center of screen --> [inst: %p, model: %p, prim: %u]\n", mpiRank, pickResult.instance, pickResult.model, pickResult.primID); ospRelease(pickResult.instance); ospRelease(pickResult.model); } else { printf("Rank %d: ospPick() center of screen did not hit\n", mpiRank); } // render one frame ospRenderFrameBlocking(framebuffer, renderer, camera, world); // on rank 0, access framebuffer and write its content as PPM file if (mpiRank == 0) { const uint32_t *fb = (uint32_t *)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("firstFrame.ppm", imgSizeX, imgSizeY, fb); ospUnmapFrameBuffer(fb, framebuffer); } // render 10 more frames, which are accumulated to result in a better // converged image for (int frames = 0; frames < 10; frames++) ospRenderFrameBlocking(framebuffer, renderer, camera, world); if (mpiRank == 0) { const uint32_t *fb = (uint32_t *)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("accumulatedFrame.ppm", imgSizeX, imgSizeY, fb); ospUnmapFrameBuffer(fb, framebuffer); } // final cleanups ospRelease(renderer); ospRelease(camera); ospRelease(lights); ospRelease(light); ospRelease(framebuffer); ospRelease(world); ospDeviceRelease(mpiDevice); ospShutdown(); MPI_Finalize(); return 0; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorial.cpp000066400000000000000000000145661464752671100265120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial how to use OSPRay and the * MPIDistributedDevice in a data-parallel application. * Each rank must specify the same render parameters, however the data * to render on each rank can differ for distributed rendering. In this * tutorial each rank renders a unique quad, which is colored by the rank. * * On Linux build it in the build_directory with: * mpicxx ../modules/mpi/tutorials/ospMPIDistributedTutorial.cpp \ * -I ../ospray/include -I ../components \ * -L . -lospray -lospray_common -Wl,-rpath,. \ * -o ospMPIDistributedTutorialCpp * * Then run it with MPI on some number of processes * mpirun -n ./ospMPIDistributedTutorialCpp * * The output image should show a sequence of quads, from dark to light blue */ #include #include #include #include #ifdef _WIN32 #define NOMINMAX #include #else #include #endif #include "rkcommon/math/box.h" #include "rkcommon/math/vec.h" #include "rkcommon/utility/SaveImage.h" #include "rkcommon/utility/getEnvVar.h" // Note: we define OSPRAY_CPP_RKCOMMON_TYPES in CMAke to use rkcommon types // natively through the C++ wrappers #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); // image size vec2i imgSize; imgSize.x = 1024; // width imgSize.y = 768; // height // camera vec3f cam_pos{(mpiWorldSize + 1.f) / 2.f, 0.5f, -mpiWorldSize * 0.5f}; vec3f cam_up{0.f, 1.f, 0.f}; vec3f cam_view{0.f, 0.f, 1.f}; // all ranks specify the same rendering parameters, with the exception of // the data to be rendered, which is distributed among the ranks // triangle mesh data vec3f vertex[] = {vec3f(mpiRank, 0.0f, 3.5f), vec3f(mpiRank, 1.0f, 3.0f), vec3f(1.0f * (mpiRank + 1.f), 0.0f, 3.0f), vec3f(1.0f * (mpiRank + 1.f), 1.0f, 2.5f)}; vec4f color[] = {vec4f(0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f), vec4f(0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f), vec4f(0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f), vec4f(0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f)}; vec3ui index[] = {vec3ui(0, 1, 2), vec3ui(1, 2, 3)}; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } // use scoped lifetimes of wrappers to release everything before ospShutdown() { cpp::Device mpiDevice("mpiDistributed"); mpiDevice.commit(); mpiDevice.setCurrent(); // create and setup camera cpp::Camera camera("perspective"); camera.setParam("aspect", imgSize.x / (float)imgSize.y); camera.setParam("position", cam_pos); camera.setParam("direction", cam_view); camera.setParam("up", cam_up); camera.commit(); // commit each object to indicate modifications are done // create and setup model and mesh cpp::Geometry mesh("mesh"); cpp::CopiedData data(vertex, 4); data.commit(); mesh.setParam("vertex.position", data); data = cpp::CopiedData(color, 4); data.commit(); mesh.setParam("vertex.color", data); data = cpp::CopiedData(index, 2); data.commit(); mesh.setParam("index", data); mesh.commit(); // put the mesh into a model cpp::GeometricModel model(mesh); model.commit(); // put the model into a group (collection of models) cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); // put the group into an instance (give the group a world transform) cpp::Instance instance(group); instance.commit(); cpp::World world; world.setParam("instance", cpp::CopiedData(instance)); // Specify the region of the world this rank owns box3f regionBounds( vec3f(mpiRank, 0.f, 2.5f), vec3f(1.f * (mpiRank + 1.f), 1.f, 3.5f)); world.setParam("region", cpp::CopiedData(regionBounds)); world.commit(); // create the mpi_raycast renderer (required for distributed rendering) cpp::Renderer renderer("mpiRaycast"); renderer.commit(); // create and setup framebuffer cpp::FrameBuffer framebuffer(imgSize.x, imgSize.y, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); framebuffer.clear(); ospray::cpp::PickResult res = framebuffer.pick(renderer, camera, world, 0.5f, 0.5f); if (res.hasHit) { std::cout << "Rank " << mpiRank << " picked geometry [instance: " << res.instance.handle() << ", model: " << res.model.handle() << ", primitive: " << res.primID << "]" << std::endl; } else { std::cout << "Rank " << mpiRank << " pick missed" << std::endl; } // render one frame framebuffer.renderFrame(renderer, camera, world); // on rank 0, access framebuffer and write its content as PPM file if (mpiRank == 0) { uint32_t *fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); rkcommon::utility::writePPM( "firstFrameCpp.ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); } // render 10 more frames, which are accumulated to result in a better // converged image for (int frames = 0; frames < 10; frames++) framebuffer.renderFrame(renderer, camera, world); if (mpiRank == 0) { uint32_t *fb = (uint32_t *)framebuffer.map(OSP_FB_COLOR); rkcommon::utility::writePPM( "accumulatedFrameCpp.ppm", imgSize.x, imgSize.y, fb); framebuffer.unmap(fb); } } ospShutdown(); MPI_Finalize(); return 0; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorialAsync.c000066400000000000000000000174231464752671100271430ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This is a small example tutorial how to use OSPRay and the * MPIDistributedDevice in a data-parallel application. * Each rank must specify the same render parameters, however the data * to render on each rank can differ for distributed rendering. In this * tutorial each rank renders a unique quad, which is colored by the rank. * * On Linux build it in the build_directory with: * mpicc -std=c99 ../modules/mpi/tutorials/ospMPIDistributedTutorialAsync.c \ * -I ../ospray/include \ * -L . -lospray -Wl,-rpath,. \ * -o ospMPIDistributedTutorialAsync * * Then run it with MPI on some number of processes * mpirun -n ./ospMPIDistributedTutorialAsync * * The output image should show a sequence of quads, from dark to light blue */ #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include // helper function to write the rendered image as PPM file void writePPM( const char *fileName, int size_x, int size_y, const uint32_t *pixel) { FILE *file = fopen(fileName, "wb"); if (!file) { fprintf(stderr, "fopen('%s', 'wb') failed: %d", fileName, errno); return; } fprintf(file, "P6\n%i %i\n255\n", size_x, size_y); unsigned char *out = (unsigned char *)alloca(3 * size_x); for (int y = 0; y < size_y; y++) { const unsigned char *in = (const unsigned char *)&pixel[(size_y - 1 - y) * size_x]; for (int x = 0; x < size_x; x++) { out[3 * x + 0] = in[4 * x + 0]; out[3 * x + 1] = in[4 * x + 1]; out[3 * x + 2] = in[4 * x + 2]; } fwrite(out, 3 * size_x, sizeof(char), file); } fprintf(file, "\n"); fclose(file); } 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); // image size int imgSizeX = 1024; // width int imgSizeY = 768; // height // camera float cam_pos[] = {(mpiWorldSize + 1.f) / 2.f, 0.5f, -mpiWorldSize * 0.5f}; float cam_up[] = {0.f, 1.f, 0.f}; float cam_view[] = {0.0f, 0.f, 1.f}; // all ranks specify the same rendering parameters, with the exception of // the data to be rendered, which is distributed among the ranks // triangle mesh data float vertex[] = { mpiRank, 0.0f, 3.5f, mpiRank, 1.0f, 3.0f, 1.0f * (mpiRank + 1.f), 0.0f, 3.0f, 1.0f * (mpiRank + 1.f), 1.0f, 2.5f, }; float color[] = {0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f, 0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f, 0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f, 0.0f, 0.0f, (mpiRank + 1.f) / mpiWorldSize, 1.0f}; int32_t index[] = {0, 1, 2, 1, 2, 3}; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device. ospLoadModule("mpi_distributed_cpu"); OSPDevice mpiDevice = ospNewDevice("mpiDistributed"); ospDeviceCommit(mpiDevice); ospSetCurrentDevice(mpiDevice); // create and setup camera OSPCamera camera = ospNewCamera("perspective"); ospSetFloat(camera, "aspect", imgSizeX / (float)imgSizeY); ospSetParam(camera, "position", OSP_VEC3F, cam_pos); ospSetParam(camera, "direction", OSP_VEC3F, cam_view); ospSetParam(camera, "up", OSP_VEC3F, cam_up); ospCommit(camera); // commit each object to indicate modifications are done // create and setup model and mesh OSPGeometry mesh = ospNewGeometry("mesh"); OSPData data = ospNewSharedData1D(vertex, OSP_VEC3F, 4); ospCommit(data); ospSetObject(mesh, "vertex.position", data); ospRelease(data); // we are done using this handle data = ospNewSharedData1D(color, OSP_VEC4F, 4); ospCommit(data); ospSetObject(mesh, "vertex.color", data); ospRelease(data); // we are done using this handle data = ospNewSharedData1D(index, OSP_VEC3UI, 2); ospCommit(data); ospSetObject(mesh, "index", data); ospRelease(data); // we are done using this handle ospCommit(mesh); // put the mesh into a model OSPGeometricModel model = ospNewGeometricModel(mesh); ospCommit(model); ospRelease(mesh); // put the model into a group (collection of models) OSPGroup group = ospNewGroup(); OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1); ospSetObject(group, "geometry", geometricModels); ospCommit(group); ospRelease(model); ospRelease(geometricModels); // put the group into an instance (give the group a world transform) OSPInstance instance = ospNewInstance(group); ospCommit(instance); ospRelease(group); // put the instance in the world OSPWorld world = ospNewWorld(); OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1); ospSetObject(world, "instance", instances); ospRelease(instance); ospRelease(instances); // In the distributed device we set a clipping region to clip to the data // owned uniquely by this rank which it should be rendering float regionBounds[] = {mpiRank, 0.f, 2.5f, 1.f * (mpiRank + 1.f), 1.f, 3.5f}; data = ospNewSharedData1D(regionBounds, OSP_BOX3F, 1); ospCommit(data); ospSetObject(world, "region", data); ospRelease(data); ospCommit(world); // create the mpi_raycast renderer (required for distributed rendering) OSPRenderer renderer = ospNewRenderer("mpiRaycast"); // create and setup light for Ambient Occlusion // TODO: Who gets the lights now? OSPLight light = ospNewLight("ambient"); ospCommit(light); OSPData lights = ospNewSharedData1D(&light, OSP_LIGHT, 1); ospCommit(lights); // complete setup of renderer ospSetFloat(renderer, "backgroundColor", 1.0f); // white, transparent ospSetObject(renderer, "light", lights); ospCommit(renderer); // create and setup framebuffer OSPFrameBuffer framebuffer = ospNewFrameBuffer(imgSizeX, imgSizeY, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); ospResetAccumulation(framebuffer); // render one frame OSPFuture result = ospRenderFrame(framebuffer, renderer, camera, world); int isFinished = ospIsReady(result, OSP_TASK_FINISHED); printf("status of 'result' is %i\n", isFinished); printf("waiting on frame to finish...\n"); ospWait(result, OSP_FRAME_FINISHED); printf("...done!\n"); printf("variance was %f\n", ospGetVariance(framebuffer)); ospRelease(result); // on rank 0, access framebuffer and write its content as PPM file if (mpiRank == 0) { const uint32_t *fb = (uint32_t *)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("firstFrame.ppm", imgSizeX, imgSizeY, fb); ospUnmapFrameBuffer(fb, framebuffer); } // render 10 more frames, which are accumulated to result in a better // converged image for (int frames = 0; frames < 10; frames++) ospRenderFrameBlocking(framebuffer, renderer, camera, world); if (mpiRank == 0) { const uint32_t *fb = (uint32_t *)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("accumulatedFrame.ppm", imgSizeX, imgSizeY, fb); ospUnmapFrameBuffer(fb, framebuffer); } // final cleanups ospRelease(renderer); ospRelease(camera); ospRelease(lights); ospRelease(light); ospRelease(framebuffer); ospRelease(world); ospDeviceRelease(mpiDevice); ospShutdown(); MPI_Finalize(); return 0; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorialPartialRepl.cpp000066400000000000000000000176111464752671100306440ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This larger example shows how to use the MPIDistributedDevice to write an * interactive rendering application, which shows a UI on rank 0 and uses * all ranks in the MPI world for data loading and rendering. This example * also shows how to leverage the support for partially replicated data * distributions in the MPIDistributedDevice, by sharing bricks of data, * and thus rendering work, between processes. Each pair of ranks will * generate the same data, thereby distributing the rendering workload * for the brick between them. */ #include #include #include #include #include #include "GLFWDistribOSPRayWindow.h" #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ospray/ospray_util.h" #include "rkcommon/utility/getEnvVar.h" using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; struct VolumeBrick { // the volume data itself cpp::Volume brick; cpp::VolumetricModel model; cpp::Group group; cpp::Instance instance; // the bounds of the owned portion of data box3f bounds; // the full bounds of the owned portion + ghost voxels box3f ghostBounds; }; static box3f worldBounds; // Generate the rank's local volume brick VolumeBrick makeLocalVolume(const int mpiRank, const int mpiWorldSize); 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); std::cout << "OSPRay rank " << mpiRank << "/" << mpiWorldSize << "\n"; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } { cpp::Device mpiDevice("mpiDistributed"); mpiDevice.commit(); mpiDevice.setCurrent(); // set an error callback to catch any OSPRay errors and exit the application ospDeviceSetErrorCallback( mpiDevice.handle(), [](void *, OSPError error, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; exit(error); }, nullptr); // every two ranks will share a volume brick to render, if we have an // odd number of ranks the last one will have its own brick const int sharedWorldSize = mpiWorldSize / 2 + mpiWorldSize % 2; // all ranks specify the same rendering parameters, with the exception of // the data to be rendered, which is distributed among the ranks VolumeBrick brick = makeLocalVolume(mpiRank / 2, sharedWorldSize); // create the "world" model which will contain all of our geometries cpp::World world; world.setParam("instance", cpp::CopiedData(brick.instance)); world.setParam("region", cpp::CopiedData(brick.bounds)); world.commit(); // create OSPRay renderer cpp::Renderer renderer("mpiRaycast"); // create and setup an ambient light cpp::Light ambientLight("ambient"); ambientLight.commit(); renderer.setParam("light", cpp::CopiedData(ambientLight)); // create a GLFW OSPRay window: this object will create and manage the // OSPRay frame buffer and camera directly auto glfwOSPRayWindow = std::unique_ptr(new GLFWDistribOSPRayWindow( vec2i{1024, 768}, worldBounds, world, renderer)); int spp = 1; int currentSpp = 1; if (mpiRank == 0) { glfwOSPRayWindow->registerImGuiCallback( [&]() { ImGui::SliderInt("pixelSamples", &spp, 1, 64); }); } glfwOSPRayWindow->registerDisplayCallback( [&](GLFWDistribOSPRayWindow *win) { // Send the UI changes out to the other ranks so we can synchronize // how many samples per-pixel we're taking MPI_Bcast(&spp, 1, MPI_INT, 0, MPI_COMM_WORLD); if (spp != currentSpp) { currentSpp = spp; renderer.setParam("pixelSamples", spp); win->addObjectToCommit(renderer.handle()); } }); // start the GLFW main loop, which will continuously render glfwOSPRayWindow->mainLoop(); } // cleanly shut OSPRay down ospShutdown(); MPI_Finalize(); return 0; } 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; } VolumeBrick makeLocalVolume(const int mpiRank, const int mpiWorldSize) { const vec3i grid = computeGrid(mpiWorldSize); const vec3i brickId(mpiRank % grid.x, (mpiRank / grid.x) % grid.y, mpiRank / (grid.x * grid.y)); // The bricks are 64^3 + 1 layer of ghost voxels on each axis const vec3i brickVolumeDims = vec3i(32); const vec3i brickGhostDims = vec3i(brickVolumeDims + 2); // The grid is over the [0, grid * brickVolumeDims] box worldBounds = box3f(vec3f(0.f), vec3f(grid * brickVolumeDims)); const vec3f brickLower = brickId * brickVolumeDims; const vec3f brickUpper = brickId * brickVolumeDims + brickVolumeDims; VolumeBrick brick; brick.bounds = box3f(brickLower, brickUpper); // we just put ghost voxels on all sides here, but a real application // would change which faces of each brick have ghost voxels dependent // on the actual data brick.ghostBounds = box3f(brickLower - vec3f(1.f), brickUpper + vec3f(1.f)); brick.brick = cpp::Volume("structuredRegular"); brick.brick.setParam("dimensions", brickGhostDims); // we use the grid origin to place this brick in the right position inside // the global volume brick.brick.setParam("gridOrigin", brick.ghostBounds.lower); // generate the volume data to just be filled with this rank's id const size_t nVoxels = brickGhostDims.x * brickGhostDims.y * brickGhostDims.z; std::vector volumeData(nVoxels, static_cast(mpiRank)); brick.brick.setParam("data", cpp::CopiedData(static_cast(volumeData.data()), vec3ul(brickVolumeDims))); brick.brick.commit(); brick.model = cpp::VolumetricModel(brick.brick); cpp::TransferFunction tfn("piecewiseLinear"); std::vector colors = {vec3f(0.f, 0.f, 1.f), vec3f(1.f, 0.f, 0.f)}; std::vector opacities = {0.05f, 1.f}; tfn.setParam("color", cpp::CopiedData(colors)); tfn.setParam("opacity", cpp::CopiedData(opacities)); // color the bricks by their rank, we pad the range out a bit to keep // any brick from being completely transparent range1f valueRange = range1f(0, mpiWorldSize); tfn.setParam("value", valueRange); tfn.commit(); brick.model.setParam("transferFunction", tfn); brick.model.setParam("samplingRate", 0.5f); brick.model.commit(); brick.group = cpp::Group(); brick.group.setParam("volume", cpp::CopiedData(brick.model)); brick.group.commit(); brick.instance = cpp::Instance(brick.group); brick.instance.commit(); return brick; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorialReplicated.cpp000066400000000000000000000075301464752671100305000ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This tutorial demonstrates how MPI-parallel applications can be * written which still render replicated data using the path tracer * for secondary effects. Applications can leverage MPI parallelism for * faster file I/O and load times when compared to the offload device. * However, such applications must be written to be aware of MPI while * the offload device behaves just like local rendering from the application's * perspective. */ #include #include #include #include #include #include "GLFWDistribOSPRayWindow.h" #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ospray/ospray_util.h" #include "ospray_testing.h" #include "rkcommon/utility/getEnvVar.h" using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; static std::string rendererType = "pathtracer"; static std::string builderType = "boxes"; void printHelp() { std::cout << R"description( usage: ./ospMPIDistribTutorialReplicated [-h | --help] [[-s | --scene] scene] [[r | --renderer] renderer_type] scenes: boxes cornell_box curves cylinders empty gravity_spheres_volume perlin_noise_volumes random_spheres streamlines subdivision_cube unstructured_volume )description"; } int main(int argc, char **argv) { for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "-h" || arg == "--help") { printHelp(); return 0; } else if (arg == "-r" || arg == "--renderer") { rendererType = argv[++i]; } else if (arg == "-s" || arg == "--scene") { builderType = argv[++i]; } } 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); std::cout << "OSPRay rank " << mpiRank << "/" << mpiWorldSize << "\n"; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } { cpp::Device mpiDevice("mpiDistributed"); mpiDevice.commit(); mpiDevice.setCurrent(); // set an error callback to catch any OSPRay errors and exit the application ospDeviceSetErrorCallback( mpiDevice.handle(), [](void *, OSPError error, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; exit(error); }, nullptr); auto builder = testing::newBuilder(builderType); testing::setParam(builder, "rendererType", rendererType); testing::commit(builder); auto world = testing::buildWorld(builder); testing::release(builder); world.commit(); cpp::Renderer renderer(rendererType); renderer.commit(); // create a GLFW OSPRay window: this object will create and manage the // OSPRay frame buffer and camera directly auto glfwOSPRayWindow = std::unique_ptr(new GLFWDistribOSPRayWindow( vec2i{1024, 768}, box3f(vec3f(-1.f), vec3f(1.f)), world, renderer)); // start the GLFW main loop, which will continuously render glfwOSPRayWindow->mainLoop(); } // cleanly shut OSPRay down ospShutdown(); MPI_Finalize(); return 0; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorialSpheres.cpp000066400000000000000000000161751464752671100300420ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This larger example shows how to use the MPIDistributedDevice to write an * interactive rendering application, which shows a UI on rank 0 and uses * all ranks in the MPI world for data loading and rendering. Each rank * generates a local sub-piece of spheres data, e.g., as if rendering some * large distributed dataset. */ #include #include #include #include #include #include #include "GLFWDistribOSPRayWindow.h" #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "rkcommon/utility/getEnvVar.h" using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; // Generate the rank's local spheres within its assigned grid cell, and // return the bounds of this grid cell cpp::Instance makeLocalSpheres( const int mpiRank, const int mpiWorldSize, box3f &bounds); 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); std::cout << "OSPRay rank " << mpiRank << "/" << mpiWorldSize << "\n"; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } { cpp::Device mpiDevice("mpiDistributed"); mpiDevice.commit(); mpiDevice.setCurrent(); // set an error callback to catch any OSPRay errors and exit the application ospDeviceSetErrorCallback( mpiDevice.handle(), [](void *, OSPError error, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; exit(error); }, nullptr); // all ranks specify the same rendering parameters, with the exception of // the data to be rendered, which is distributed among the ranks box3f regionBounds; cpp::Instance spheres = makeLocalSpheres(mpiRank, mpiWorldSize, regionBounds); // create the "world" model which will contain all of our geometries cpp::World world; world.setParam("instance", cpp::CopiedData(spheres)); /* * Note: We've taken care that all the generated spheres are completely * within the bounds, and we don't have ghost data or portions of speres * to clip off. Thus we actually don't need to set region at all in * this tutorial. Example: * world.setParam("region", cpp::CopiedData(regionBounds)); */ world.commit(); // create OSPRay renderer cpp::Renderer renderer("mpiRaycast"); // create and setup an ambient light std::array lights = { cpp::Light("ambient"), cpp::Light("distant")}; lights[0].commit(); lights[1].setParam("direction", vec3f(-1.f, -1.f, 0.5f)); lights[1].commit(); renderer.setParam("lights", cpp::CopiedData(lights)); renderer.setParam("aoSamples", 1); // create a GLFW OSPRay window: this object will create and manage the // OSPRay frame buffer and camera directly auto glfwOSPRayWindow = std::unique_ptr(new GLFWDistribOSPRayWindow( vec2i{1024, 768}, box3f(vec3f(-1.f), vec3f(1.f)), world, renderer)); int spp = 1; int currentSpp = 1; if (mpiRank == 0) { glfwOSPRayWindow->registerImGuiCallback( [&]() { ImGui::SliderInt("pixelSamples", &spp, 1, 64); }); } glfwOSPRayWindow->registerDisplayCallback( [&](GLFWDistribOSPRayWindow *win) { // Send the UI changes out to the other ranks so we can synchronize // how many samples per-pixel we're taking MPI_Bcast(&spp, 1, MPI_INT, 0, MPI_COMM_WORLD); if (spp != currentSpp) { currentSpp = spp; renderer.setParam("pixelSamples", spp); win->addObjectToCommit(renderer.handle()); } }); // start the GLFW main loop, which will continuously render glfwOSPRayWindow->mainLoop(); } // cleanly shut OSPRay down ospShutdown(); MPI_Finalize(); return 0; } 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; } cpp::Instance makeLocalSpheres( const int mpiRank, const int mpiWorldSize, box3f &bounds) { const float sphereRadius = 0.1; std::vector spheres(50); // To simulate loading a shared dataset all ranks generate the same // sphere data. std::random_device rd; std::mt19937 rng(rd()); const vec3i grid = computeGrid(mpiWorldSize); const vec3i brickId(mpiRank % grid.x, (mpiRank / grid.x) % grid.y, mpiRank / (grid.x * grid.y)); // The grid is over the [-1, 1] box const vec3f brickSize = vec3f(2.0) / vec3f(grid); const vec3f brickLower = brickSize * brickId - vec3f(1.f); const vec3f brickUpper = brickSize * brickId - vec3f(1.f) + brickSize; bounds.lower = brickLower; bounds.upper = brickUpper; // Generate spheres within the box padded by the radius, so we don't need // to worry about ghost bounds std::uniform_real_distribution distX( brickLower.x + sphereRadius, brickUpper.x - sphereRadius); std::uniform_real_distribution distY( brickLower.y + sphereRadius, brickUpper.y - sphereRadius); std::uniform_real_distribution distZ( brickLower.z + sphereRadius, brickUpper.z - sphereRadius); for (auto &s : spheres) { s.x = distX(rng); s.y = distY(rng); s.z = distZ(rng); } cpp::Geometry sphereGeom("sphere"); sphereGeom.setParam("radius", sphereRadius); sphereGeom.setParam("sphere.position", cpp::CopiedData(spheres)); sphereGeom.commit(); vec3f color(0.f, 0.f, (mpiRank + 1.f) / mpiWorldSize); cpp::Material material("obj"); material.setParam("kd", color); material.commit(); cpp::GeometricModel model(sphereGeom); model.setParam("material", material); model.commit(); cpp::Group group; group.setParam("geometry", cpp::CopiedData(model)); group.commit(); cpp::Instance instance(group); instance.commit(); return instance; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistribTutorialVolume.cpp000066400000000000000000000167221464752671100276760ustar00rootroot00000000000000// Copyright 2018 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This larger example shows how to use the MPIDistributedDevice to write an * interactive rendering application, which shows a UI on rank 0 and uses * all ranks in the MPI world for data loading and rendering. Each rank * generates a local sub-brick of volume data, as if rendering some * large distributed dataset. */ #include #include #include #include #include #include "GLFWDistribOSPRayWindow.h" #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ospray/ospray_util.h" #include "rkcommon/utility/getEnvVar.h" using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; struct VolumeBrick { // the volume data itself cpp::Volume brick; cpp::VolumetricModel model; cpp::Group group; cpp::Instance instance; // the bounds of the owned portion of data box3f bounds; // the full bounds of the owned portion + ghost voxels box3f ghostBounds; }; static box3f worldBounds; // Generate the rank's local volume brick VolumeBrick makeLocalVolume(const int mpiRank, const int mpiWorldSize); 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 mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); std::cout << "OSPRay rank " << mpiRank << "/" << mpiWorldSize << "\n"; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } { cpp::Device mpiDevice("mpiDistributed"); mpiDevice.commit(); mpiDevice.setCurrent(); // set an error callback to catch any OSPRay errors and exit the application ospDeviceSetErrorCallback( mpiDevice.handle(), [](void *, OSPError error, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; exit(error); }, nullptr); // all ranks specify the same rendering parameters, with the exception of // the data to be rendered, which is distributed among the ranks VolumeBrick brick = makeLocalVolume(mpiRank, mpiWorldSize); // create the "world" model which will contain all of our geometries cpp::World world; world.setParam("instance", cpp::CopiedData(brick.instance)); world.setParam("region", cpp::CopiedData(brick.bounds)); world.commit(); // create OSPRay renderer cpp::Renderer renderer("mpiRaycast"); // create and setup an ambient light cpp::Light ambientLight("ambient"); ambientLight.commit(); renderer.setParam("light", cpp::CopiedData(ambientLight)); // create a GLFW OSPRay window: this object will create and manage the // OSPRay frame buffer and camera directly auto glfwOSPRayWindow = std::unique_ptr(new GLFWDistribOSPRayWindow( vec2i{1024, 768}, worldBounds, world, renderer)); int spp = 1; int currentSpp = 1; if (mpiRank == 0) { glfwOSPRayWindow->registerImGuiCallback( [&]() { ImGui::SliderInt("pixelSamples", &spp, 1, 64); }); } glfwOSPRayWindow->registerDisplayCallback( [&](GLFWDistribOSPRayWindow *win) { // Send the UI changes out to the other ranks so we can synchronize // how many samples per-pixel we're taking MPI_Bcast(&spp, 1, MPI_INT, 0, MPI_COMM_WORLD); if (spp != currentSpp) { currentSpp = spp; renderer.setParam("pixelSamples", spp); win->addObjectToCommit(renderer.handle()); } }); // start the GLFW main loop, which will continuously render glfwOSPRayWindow->mainLoop(); } // cleanly shut OSPRay down ospShutdown(); MPI_Finalize(); return 0; } 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; } VolumeBrick makeLocalVolume(const int mpiRank, const int mpiWorldSize) { const vec3i grid = computeGrid(mpiWorldSize); const vec3i brickId(mpiRank % grid.x, (mpiRank / grid.x) % grid.y, mpiRank / (grid.x * grid.y)); // The bricks are 64^3 + 1 layer of ghost voxels on each axis const vec3i brickVolumeDims = vec3i(32); const vec3i brickGhostDims = vec3i(brickVolumeDims + 2); // The grid is over the [0, grid * brickVolumeDims] box worldBounds = box3f(vec3f(0.f), vec3f(grid * brickVolumeDims)); const vec3f brickLower = brickId * brickVolumeDims; const vec3f brickUpper = brickId * brickVolumeDims + brickVolumeDims; VolumeBrick brick; brick.bounds = box3f(brickLower, brickUpper); // we just put ghost voxels on all sides here, but a real application // would change which faces of each brick have ghost voxels dependent // on the actual data brick.ghostBounds = box3f(brickLower - vec3f(1.f), brickUpper + vec3f(1.f)); brick.brick = cpp::Volume("structuredRegular"); brick.brick.setParam("dimensions", brickGhostDims); // we use the grid origin to place this brick in the right position inside // the global volume brick.brick.setParam("gridOrigin", brick.ghostBounds.lower); // generate the volume data to just be filled with this rank's id const size_t nVoxels = brickGhostDims.x * brickGhostDims.y * brickGhostDims.z; std::vector volumeData(nVoxels, static_cast(mpiRank)); brick.brick.setParam("data", cpp::CopiedData(static_cast(volumeData.data()), vec3ul(brickVolumeDims))); brick.brick.commit(); brick.model = cpp::VolumetricModel(brick.brick); cpp::TransferFunction tfn("piecewiseLinear"); std::vector colors = {vec3f(0.f, 0.f, 1.f), vec3f(1.f, 0.f, 0.f)}; std::vector opacities = {0.05f, 1.f}; tfn.setParam("color", cpp::CopiedData(colors)); tfn.setParam("opacity", cpp::CopiedData(opacities)); // color the bricks by their rank, we pad the range out a bit to keep // any brick from being completely transparent range1f valueRange = range1f(0, mpiWorldSize); tfn.setParam("value", valueRange); tfn.commit(); brick.model.setParam("transferFunction", tfn); brick.model.setParam("samplingRate", 0.5f); brick.model.commit(); brick.group = cpp::Group(); brick.group.setParam("volume", cpp::CopiedData(brick.model)); brick.group.commit(); brick.instance = cpp::Instance(brick.group); brick.instance.commit(); return brick; } RenderKit-ospray-85af292/modules/mpi/tutorials/ospMPIDistributedExamples.cpp000066400000000000000000000130121464752671100273300ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* This example generates the same data on each rank so that we can build * off the existing OSPRay testing data generators, however each rank * specifies a subregion as its local domain to render the data as if it was * distributed. The scene to load can be passed as an argument to the * application */ #include #include #include #include #include #include "GLFWDistribOSPRayWindow.h" #include "ospray/ospray_cpp.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ospray/ospray_util.h" #include "ospray_testing.h" #include "rkcommon/utility/getEnvVar.h" using namespace ospray; using namespace rkcommon; using namespace rkcommon::math; bool computeDivisor(int x, int &divisor); // 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); 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; } std::string sceneName = "gravity_spheres_volume"; if (argc == 2) { sceneName = argv[1]; } int mpiRank = 0; int mpiWorldSize = 0; MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize); std::cout << "OSPRay rank " << mpiRank << "/" << mpiWorldSize << "\n"; // load the MPI module, and select the MPI distributed device. Here we // do not call ospInit, as we want to explicitly pick the distributed // device auto OSPRAY_MPI_DISTRIBUTED_GPU = utility::getEnvVar("OSPRAY_MPI_DISTRIBUTED_GPU").value_or(0); if (OSPRAY_MPI_DISTRIBUTED_GPU) { ospLoadModule("mpi_distributed_gpu"); } else { ospLoadModule("mpi_distributed_cpu"); } { cpp::Device mpiDevice("mpiDistributed"); mpiDevice.commit(); mpiDevice.setCurrent(); // set an error callback to catch any OSPRay errors and exit the application mpiDevice.setErrorCallback( [](void *, OSPError error, const char *errorDetails) { std::cerr << "OSPRay error: " << errorDetails << std::endl; exit(error); }); // Regions are assigned to ranks in 3D grid, determine which brick of the // grid is owned by this rank const vec3i distribGrid = computeGrid(mpiWorldSize); const vec3i distribBrickId(mpiRank % distribGrid.x, (mpiRank / distribGrid.x) % distribGrid.y, mpiRank / (distribGrid.x * distribGrid.y)); std::cout << "scene = " << sceneName << "\n"; auto builder = testing::newBuilder(sceneName); testing::setParam(builder, "rendererType", "scivis"); testing::commit(builder); auto group = testing::buildGroup(builder); const box3f worldBounds = group.getBounds(); cpp::Instance instance(group); instance.commit(); cpp::World world; world.setParam("instance", cpp::CopiedData(instance)); cpp::Light light("ambient"); light.setParam("visible", false); light.commit(); world.setParam("light", cpp::CopiedData(light)); // Determine the bounds of this rank's region in world space const vec3f distribBrickDims = worldBounds.size() / vec3f(distribGrid); box3f localRegion(distribBrickId * distribBrickDims + worldBounds.lower, distribBrickId * distribBrickDims + distribBrickDims + 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; } } // Set our region that represents the bounds of the local data we own on // this rank world.setParam("region", cpp::CopiedData(localRegion)); world.commit(); testing::release(builder); // create OSPRay renderer cpp::Renderer renderer("mpiRaycast"); // create a GLFW OSPRay window: this object will create and manage the // OSPRay frame buffer and camera directly auto glfwOSPRayWindow = std::unique_ptr(new GLFWDistribOSPRayWindow( vec2i{1024, 768}, worldBounds, world, renderer)); // start the GLFW main loop, which will continuously render glfwOSPRayWindow->mainLoop(); } // cleanly shut OSPRay down ospShutdown(); MPI_Finalize(); return 0; } 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; } RenderKit-ospray-85af292/modules/multiDevice/000077500000000000000000000000001464752671100212155ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/multiDevice/CMakeLists.txt000066400000000000000000000037661464752671100237710ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_dependent_option( OSPRAY_MODULE_MULTIDEVICE "Build the multidevice module" OFF OSPRAY_MODULE_CPU OFF ) if (NOT OSPRAY_MODULE_MULTIDEVICE) return() endif() rkcommon_configure_build_type() set(OSPRAY_MULTIDEVICE_HOST_SOURCES ${OSPRAY_RESOURCE} MultiDevice.cpp MultiDeviceLoadBalancer.cpp MultiDeviceModuleInit.cpp ) include_directories_ispc( ${PROJECT_SOURCE_DIR}/ospray/include ${PROJECT_SOURCE_DIR}/ospray ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${RKCOMMON_INCLUDE_DIRS} ${EMBREE_INCLUDE_DIRS} ) add_definitions_ispc( OSPRAY_BEGIN_ISPC_NAMESPACE= OSPRAY_END_ISPC_NAMESPACE= SYCL_EXTERNAL= OSPRAY_ENABLE_VOLUMES ) add_library(ospray_module_multidevice_cpu SHARED ${OSPRAY_MULTIDEVICE_HOST_SOURCES} ) target_link_libraries(ospray_module_multidevice_cpu PRIVATE rkcommon::rkcommon ospray_module_cpu ) target_include_directories(ospray_module_multidevice_cpu PUBLIC $ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # For ISPC module generated ispc headers ${PROJECT_BINARY_DIR}/ospray/ ) target_compile_definitions(ospray_module_multidevice_cpu PRIVATE OBJECTFACTORY_IMPORT ) ospray_install_library(ospray_module_multidevice_cpu lib) if (OSPRAY_MODULE_GPU) add_library(ospray_module_multidevice_gpu SHARED ${OSPRAY_MULTIDEVICE_HOST_SOURCES}) target_link_libraries(ospray_module_multidevice_gpu PRIVATE rkcommon::rkcommon ospray_module_gpu ) target_include_directories(ospray_module_multidevice_gpu PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # For ISPC module generated ispc headers ${PROJECT_BINARY_DIR}/ospray/ ) target_compile_definitions(ospray_module_multidevice_gpu PRIVATE OBJECTFACTORY_IMPORT ) ospray_install_library(ospray_module_multidevice_gpu lib) endif() RenderKit-ospray-85af292/modules/multiDevice/MultiDevice.cpp000066400000000000000000000421041464752671100241340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "MultiDevice.h" #include "MultiDeviceFrameBuffer.h" #include "MultiDeviceRenderTask.h" #include "camera/registration.h" #include "common/DeviceRTImpl.h" #include "fb/LocalFB.h" #include "fb/SparseFB.h" #include "fb/registration.h" #include "geometry/registration.h" #include "lights/registration.h" #include "render/LoadBalancer.h" #include "render/registration.h" #include "texture/registration.h" #include "volume/transferFunction/registration.h" #include "rkcommon/tasking/parallel_for.h" #include "rkcommon/tasking/tasking_system_init.h" #include "rkcommon/utility/CodeTimer.h" #include "rkcommon/utility/getEnvVar.h" #include "rkcommon/utility/multidim_index_sequence.h" namespace ospray { namespace api { ///////////////////////////////////////////////////////////////////////// // ManagedObject Implementation ///////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// void MultiDevice::commit() { Device::commit(); hostDevice.commit(); if (subdevices.empty()) { auto OSPRAY_NUM_SUBDEVICES = utility::getEnvVar("OSPRAY_NUM_SUBDEVICES"); int numSubdevices = OSPRAY_NUM_SUBDEVICES.value_or(getParam("numSubdevices", 1)); postStatusMsg(OSP_LOG_DEBUG) << "# of subdevices =" << numSubdevices; std::vector> subdeviceLoadBalancers; for (int i = 0; i < numSubdevices; ++i) { std::unique_ptr drtDevice = devicert::make_device_unique(i, debugMode); auto d = rkcommon::make_unique(std::move(drtDevice)); d->commit(); subdevices.emplace_back(std::move(d)); subdeviceLoadBalancers.push_back(subdevices.back()->loadBalancer); } loadBalancer = rkcommon::make_unique(subdeviceLoadBalancers); } } ///////////////////////////////////////////////////////////////////////// // Device Implementation //////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// int MultiDevice::loadModule(const char *name) { OSPError err = OSP_NO_ERROR; for (auto &d : subdevices) { auto e = d->loadModule(name); if (e != OSP_NO_ERROR) { err = (OSPError)e; } } return err; } // OSPRay Data Arrays /////////////////////////////////////////////////// static void multiDeviceObjectDeleter(const void *object, const void *) { memory::RefCount *o = (memory::RefCount *)object; o->refDec(); } OSPData MultiDevice::newSharedData(const void *sharedData, OSPDataType type, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback freeFunction, const void *userData) { MultiDeviceObject *o = new MultiDeviceObject; o->freeFunction = freeFunction; o->userData = userData; o->sharedData = sharedData; // Data arrays of OSPRay objects need to populate the corresponding subdevice // data arrays with the objects for that subdevice if (type & OSP_OBJECT) { for (size_t i = 0; i < subdevices.size(); ++i) { o->objects.push_back( (OSPObject) new Data(*subdevices[i], type, numItems)); } // A little lazy here, but using the Data object to just give me a view // + the index sequence iterator to use to step over the stride Data *multiData = new Data(hostDevice, sharedData, type, numItems, byteStride); o->sharedDataDirtyReference = multiData; index_sequence_3D seq(numItems); for (auto idx : seq) { MultiDeviceObject *mobj = *(MultiDeviceObject **)multiData->data(idx); retain((OSPObject)mobj); // Copy the subdevice object handles to the data arrays for each subdevice for (size_t i = 0; i < subdevices.size(); ++i) { Data *subdeviceData = (Data *)o->objects[i]; std::memcpy( subdeviceData->data(idx), &mobj->objects[i], sizeof(OSPObject)); } } } else { for (auto &d : subdevices) { o->refInc(); o->objects.push_back(d->newSharedData( sharedData, type, numItems, byteStride, multiDeviceObjectDeleter, o)); } } return (OSPData)o; } OSPData MultiDevice::newData(OSPDataType type, const vec3ul &numItems) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newData(type, numItems)); } return (OSPData)o; } void MultiDevice::copyData( const OSPData source, OSPData destination, const vec3ul &destinationIndex) { const MultiDeviceObject *srcs = (const MultiDeviceObject *)source; MultiDeviceObject *dsts = (MultiDeviceObject *)destination; for (size_t i = 0; i < subdevices.size(); ++i) { subdevices[i]->copyData( (OSPData)srcs->objects[i], (OSPData)dsts->objects[i], destinationIndex); } } // Renderable Objects /////////////////////////////////////////////////// OSPLight MultiDevice::newLight(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newLight(type)); } return (OSPLight)o; } OSPCamera MultiDevice::newCamera(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newCamera(type)); } return (OSPCamera)o; } OSPGeometry MultiDevice::newGeometry(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newGeometry(type)); } return (OSPGeometry)o; } OSPVolume MultiDevice::newVolume(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newVolume(type)); } return (OSPVolume)o; } OSPGeometricModel MultiDevice::newGeometricModel(OSPGeometry geom) { MultiDeviceObject *g = (MultiDeviceObject *)geom; MultiDeviceObject *o = new MultiDeviceObject; for (size_t i = 0; i < subdevices.size(); ++i) { OSPGeometry subdeviceObj = g ? (OSPGeometry)g->objects[i] : (OSPGeometry) nullptr; o->objects.push_back(subdevices[i]->newGeometricModel(subdeviceObj)); } return (OSPGeometricModel)o; } OSPVolumetricModel MultiDevice::newVolumetricModel(OSPVolume volume) { MultiDeviceObject *v = (MultiDeviceObject *)volume; MultiDeviceObject *o = new MultiDeviceObject; for (size_t i = 0; i < subdevices.size(); ++i) { OSPVolume subdeviceObj = v ? (OSPVolume)v->objects[i] : (OSPVolume) nullptr; o->objects.push_back(subdevices[i]->newVolumetricModel(subdeviceObj)); } return (OSPVolumetricModel)o; } // Model Meta-Data ////////////////////////////////////////////////////// OSPMaterial MultiDevice::newMaterial(const char *material_type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newMaterial(material_type)); } return (OSPMaterial)o; } OSPTransferFunction MultiDevice::newTransferFunction(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newTransferFunction(type)); } return (OSPTransferFunction)o; } OSPTexture MultiDevice::newTexture(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newTexture(type)); } return (OSPTexture)o; } // Instancing /////////////////////////////////////////////////////////// OSPGroup MultiDevice::newGroup() { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newGroup()); } return (OSPGroup)o; } OSPInstance MultiDevice::newInstance(OSPGroup group) { MultiDeviceObject *g = (MultiDeviceObject *)group; MultiDeviceObject *o = new MultiDeviceObject; for (size_t i = 0; i < subdevices.size(); ++i) { OSPGroup subdeviceObj = g ? (OSPGroup)g->objects[i] : (OSPGroup) nullptr; o->objects.push_back(subdevices[i]->newInstance(subdeviceObj)); } return (OSPInstance)o; } // Top-level Worlds ///////////////////////////////////////////////////// OSPWorld MultiDevice::newWorld() { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newWorld()); } return (OSPWorld)o; } box3f MultiDevice::getBounds(OSPObject obj) { MultiDeviceObject *o = (MultiDeviceObject *)obj; // Everything is replicated across the subdevices, so we // can just query the bounds from one of them return subdevices[0]->getBounds(o->objects[0]); } // Object + Parameter Lifetime Management /////////////////////////////// void MultiDevice::setObjectParam( OSPObject object, const char *name, OSPDataType type, const void *mem) { // If the type is an OSPObject, we need to find the per-subdevice objects // and set them appropriately MultiDeviceObject *o = (MultiDeviceObject *)object; if (type & OSP_OBJECT) { MultiDeviceObject *p = *(MultiDeviceObject **)mem; for (size_t i = 0; i < subdevices.size(); ++i) { subdevices[i]->setObjectParam(o->objects[i], name, type, &p->objects[i]); } } else { for (size_t i = 0; i < subdevices.size(); ++i) { subdevices[i]->setObjectParam(o->objects[i], name, type, mem); } } // Handle parameters for rowmajor framebuffer MultiDeviceFrameBuffer *fb = dynamic_cast(o); if (fb) { if (type & OSP_OBJECT) { MultiDeviceObject *p = *(MultiDeviceObject **)mem; hostDevice.setObjectParam( (OSPObject)fb->rowmajorFb.ptr, name, type, &p->objects[0]); } else { hostDevice.setObjectParam((OSPObject)fb->rowmajorFb.ptr, name, type, mem); } } } void MultiDevice::removeObjectParam(OSPObject object, const char *name) { MultiDeviceObject *o = (MultiDeviceObject *)object; for (size_t i = 0; i < subdevices.size(); ++i) { subdevices[i]->removeObjectParam(o->objects[i], name); } // Handle parameters for rowmajor framebuffer MultiDeviceFrameBuffer *fb = dynamic_cast(o); if (fb) hostDevice.removeObjectParam((OSPObject)fb->rowmajorFb.ptr, name); } void MultiDevice::commit(OSPObject object) { MultiDeviceObject *o = (MultiDeviceObject *)object; // Applications can change their shared buffer contents directly, // so shared arrays of objects have to do more to ensure that the // contents are up to date. Specifically the handles have to be // translated down to the subdevice specific handles correctly. if (o->sharedDataDirtyReference) { Data *multiData = o->sharedDataDirtyReference; const vec3ul &numItems = multiData->numItems; index_sequence_3D seq(numItems); for (auto idx : seq) { MultiDeviceObject *mobj = *(MultiDeviceObject **)multiData->data(idx); retain((OSPObject)mobj); // Copy the subdevice object handles to the data arrays for each subdevice for (size_t i = 0; i < subdevices.size(); ++i) { Data *subdeviceData = (Data *)o->objects[i]; std::memcpy( subdeviceData->data(idx), &mobj->objects[i], sizeof(OSPObject)); } } } for (size_t i = 0; i < subdevices.size(); ++i) { subdevices[i]->commit(o->objects[i]); } // Handle commits for rowmajor framebuffer MultiDeviceFrameBuffer *fb = dynamic_cast(o); if (fb) hostDevice.commit((OSPObject)fb->rowmajorFb.ptr); } void MultiDevice::release(OSPObject object) { memory::RefCount *o = (memory::RefCount *)object; MultiDeviceObject *mo = dynamic_cast(o); if (mo) { if (mo->sharedDataDirtyReference) { Data *multiData = mo->sharedDataDirtyReference; const vec3ul &numItems = multiData->numItems; index_sequence_3D seq(numItems); for (auto idx : seq) { MultiDeviceObject *mobj = *(MultiDeviceObject **)multiData->data(idx); mobj->refDec(); } } for (size_t i = 0; i < mo->objects.size(); ++i) { subdevices[i]->release(mo->objects[i]); } } o->refDec(); } void MultiDevice::retain(OSPObject object) { memory::RefCount *o = (memory::RefCount *)object; MultiDeviceObject *mo = dynamic_cast(o); if (mo) { for (size_t i = 0; i < mo->objects.size(); ++i) { subdevices[i]->retain(mo->objects[i]); } } o->refInc(); } // FrameBuffer Manipulation ///////////////////////////////////////////// OSPFrameBuffer MultiDevice::frameBufferCreate( const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) { MultiDeviceFrameBuffer *o = new MultiDeviceFrameBuffer(); o->rowmajorFb = new LocalFrameBuffer(hostDevice, size, mode, channels); // Need one refDec here for the local scope ref (see issue about Ref<>) o->rowmajorFb->refDec(); const vec2i totalTiles = divRoundUp(size, vec2i(TILE_SIZE)); for (size_t i = 0; i < subdevices.size(); ++i) { // Assign tiles round-robin among the subdevices std::vector tileIDs; for (uint32_t tid = 0; tid < totalTiles.long_product(); ++tid) { if (tid % subdevices.size() == i) { tileIDs.push_back(tid); } } FrameBuffer *fbi = new SparseFrameBuffer(*subdevices[i], size, mode, channels, tileIDs); o->objects.push_back((OSPFrameBuffer)fbi); } return (OSPFrameBuffer)o; } OSPImageOperation MultiDevice::newImageOp(const char *type) { // In principle we don't need multiple ImageOp objects, but as long as we do // not use objects reference counting in MultiDeviceObject we need them for // proper memory handling MultiDeviceObject *o = new MultiDeviceObject(); for (auto &d : subdevices) { o->objects.push_back(hostDevice.newImageOp(type)); } return (OSPImageOperation)o; } const void *MultiDevice::frameBufferMap( OSPFrameBuffer _fb, const OSPFrameBufferChannel channel) { MultiDeviceFrameBuffer *o = (MultiDeviceFrameBuffer *)_fb; return o->rowmajorFb->mapBuffer(channel); } void MultiDevice::frameBufferUnmap(const void *mapped, OSPFrameBuffer _fb) { MultiDeviceFrameBuffer *o = (MultiDeviceFrameBuffer *)_fb; o->rowmajorFb->unmap(mapped); } float MultiDevice::getVariance(OSPFrameBuffer _fb) { MultiDeviceFrameBuffer *o = (MultiDeviceFrameBuffer *)_fb; return o->rowmajorFb->getVariance(); } void MultiDevice::resetAccumulation(OSPFrameBuffer _fb) { MultiDeviceFrameBuffer *o = (MultiDeviceFrameBuffer *)_fb; o->rowmajorFb->clear(); for (size_t i = 0; i < subdevices.size(); ++i) { SparseFrameBuffer *fbi = (SparseFrameBuffer *)o->objects[i]; fbi->clear(); } } // Frame Rendering ////////////////////////////////////////////////////// OSPRenderer MultiDevice::newRenderer(const char *type) { MultiDeviceObject *o = new MultiDeviceObject; for (auto &d : subdevices) { o->objects.push_back(d->newRenderer(type)); } return (OSPRenderer)o; } OSPFuture MultiDevice::renderFrame(OSPFrameBuffer _framebuffer, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world) { MultiDeviceFrameBuffer *multiFb = (MultiDeviceFrameBuffer *)_framebuffer; multiFb->rowmajorFb->setCompletedEvent(OSP_NONE_FINISHED); for (size_t i = 0; i < multiFb->objects.size(); ++i) { SparseFrameBuffer *fbi = (SparseFrameBuffer *)multiFb->objects[i]; fbi->setCompletedEvent(OSP_NONE_FINISHED); } MultiDeviceObject *multiRenderer = (MultiDeviceObject *)_renderer; MultiDeviceObject *multiCamera = (MultiDeviceObject *)_camera; MultiDeviceObject *multiWorld = (MultiDeviceObject *)_world; retain((OSPObject)multiFb); retain((OSPObject)multiRenderer); retain((OSPObject)multiCamera); retain((OSPObject)multiWorld); auto *f = new MultiDeviceRenderTask(multiFb, [=]() { utility::CodeTimer timer; timer.start(); loadBalancer->renderFrame(multiFb, multiRenderer, multiCamera, multiWorld); timer.stop(); release((OSPObject)multiFb); release((OSPObject)multiRenderer); release((OSPObject)multiCamera); release((OSPObject)multiWorld); return timer.seconds(); }); return (OSPFuture)f; } int MultiDevice::isReady(OSPFuture _task, OSPSyncEvent event) { auto *task = (Future *)_task; return task->isFinished(event); } void MultiDevice::wait(OSPFuture _task, OSPSyncEvent event) { auto *task = (Future *)_task; task->wait(event); } void MultiDevice::cancel(OSPFuture _task) { auto *task = (Future *)_task; return task->cancel(); } float MultiDevice::getProgress(OSPFuture _task) { auto *task = (Future *)_task; return task->getProgress(); } float MultiDevice::getTaskDuration(OSPFuture _task) { auto *task = (Future *)_task; return task->getTaskDuration(); } OSPPickResult MultiDevice::pick(OSPFrameBuffer _fb, OSPRenderer _renderer, OSPCamera _camera, OSPWorld _world, const vec2f &screenPos) { MultiDeviceObject *multiFb = (MultiDeviceObject *)_fb; FrameBuffer *fb = (FrameBuffer *)multiFb->objects[0]; MultiDeviceObject *multiRenderer = (MultiDeviceObject *)_renderer; MultiDeviceObject *multiCamera = (MultiDeviceObject *)_camera; MultiDeviceObject *multiWorld = (MultiDeviceObject *)_world; // Data in the multidevice is all replicated, so we just run the pick on the // first subdevice return subdevices[0]->pick((OSPFrameBuffer)fb, (OSPRenderer)multiRenderer->objects[0], (OSPCamera)multiCamera->objects[0], (OSPWorld)multiWorld->objects[0], screenPos); } } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/multiDevice/MultiDevice.h000066400000000000000000000103021464752671100235740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "ISPCDevice.h" #include "MultiDeviceLoadBalancer.h" #include "MultiDeviceObject.h" #include "MultiDeviceRenderTask.h" // MultiDevice.h Implements the a multiplexor for other OSPRay devices which // this simply farms work out to in an image parallel fashion. namespace ospray { namespace api { struct MultiDevice : public Device { MultiDevice() = default; ///////////////////////////////////////////////////////////////////////// // ManagedObject Implementation ///////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// void commit() override; ///////////////////////////////////////////////////////////////////////// // Device Implementation //////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// int loadModule(const char *name) override; // OSPRay Data Arrays /////////////////////////////////////////////////// OSPData newSharedData(const void *sharedData, OSPDataType, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback, const void *userPtr) override; OSPData newData(OSPDataType, const vec3ul &numItems) override; void copyData(const OSPData source, OSPData destination, const vec3ul &destinationIndex) override; // Renderable Objects /////////////////////////////////////////////////// OSPLight newLight(const char *type) override; OSPCamera newCamera(const char *type) override; OSPGeometry newGeometry(const char *type) override; OSPVolume newVolume(const char *type) override; OSPGeometricModel newGeometricModel(OSPGeometry geom) override; OSPVolumetricModel newVolumetricModel(OSPVolume volume) override; // Model Meta-Data ////////////////////////////////////////////////////// OSPMaterial newMaterial(const char *material_type) override; OSPTransferFunction newTransferFunction(const char *type) override; OSPTexture newTexture(const char *type) override; // Instancing /////////////////////////////////////////////////////////// OSPGroup newGroup() override; OSPInstance newInstance(OSPGroup group) override; // Top-level Worlds ///////////////////////////////////////////////////// OSPWorld newWorld() override; box3f getBounds(OSPObject) override; // Object + Parameter Lifetime Management /////////////////////////////// void setObjectParam(OSPObject object, const char *name, OSPDataType type, const void *mem) override; void removeObjectParam(OSPObject object, const char *name) override; void commit(OSPObject object) override; void release(OSPObject _obj) override; void retain(OSPObject _obj) override; // FrameBuffer Manipulation ///////////////////////////////////////////// OSPFrameBuffer frameBufferCreate(const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) override; OSPImageOperation newImageOp(const char *type) override; const void *frameBufferMap( OSPFrameBuffer fb, const OSPFrameBufferChannel) override; void frameBufferUnmap(const void *mapped, OSPFrameBuffer fb) override; float getVariance(OSPFrameBuffer) override; void resetAccumulation(OSPFrameBuffer _fb) override; // Frame Rendering ////////////////////////////////////////////////////// OSPRenderer newRenderer(const char *type) override; OSPFuture renderFrame( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld) override; int isReady(OSPFuture, OSPSyncEvent) override; void wait(OSPFuture, OSPSyncEvent) override; void cancel(OSPFuture) override; float getProgress(OSPFuture) override; float getTaskDuration(OSPFuture) override; OSPPickResult pick( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, const vec2f &) override; private: std::unique_ptr loadBalancer; ISPCDevice hostDevice; std::vector> subdevices; }; extern "C" OSPError OSPRAY_DLLEXPORT ospray_module_init_multi( int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/); } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/multiDevice/MultiDeviceFrameBuffer.h000066400000000000000000000011551464752671100257070ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "MultiDeviceObject.h" #include "fb/LocalFB.h" namespace ospray { namespace api { /* The MultiDeviceFrameBuffer stores a SparseFB for each subdevice containing * the tiles the subdevice will render, along with a rowmajorFb that will be * exposed to the application. After rendering, the sparse framebuffers are * untiled into the rowmajorFb to return the rendered image to the app */ struct MultiDeviceFrameBuffer : MultiDeviceObject { Ref rowmajorFb; }; } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/multiDevice/MultiDeviceLoadBalancer.cpp000066400000000000000000000041441464752671100263660ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "MultiDeviceLoadBalancer.h" #include "MultiDevice.h" #include "fb/LocalFB.h" #include "fb/SparseFB.h" #include namespace ospray { MultiDeviceLoadBalancer::MultiDeviceLoadBalancer( const std::vector> &loadBalancers) : loadBalancers(loadBalancers) {} void MultiDeviceLoadBalancer::renderFrame( api::MultiDeviceFrameBuffer *framebuffer, api::MultiDeviceObject *renderer, api::MultiDeviceObject *camera, api::MultiDeviceObject *world) { framebuffer->rowmajorFb->beginFrame(); // Schedule rendering on all devices std::vector> events( framebuffer->objects.size()); for (uint32_t i = 0; i < framebuffer->objects.size(); i++) { SparseFrameBuffer *fbi = (SparseFrameBuffer *)framebuffer->objects[i]; Renderer *ri = (Renderer *)renderer->objects[i]; Camera *ci = (Camera *)camera->objects[i]; World *wi = (World *)world->objects[i]; if (fbi->getTileIDs().size() != 0) events[i] = loadBalancers[i]->renderFrame(fbi, ri, ci, wi); } // Wait for all devices to finish for (uint32_t i = 0; i < framebuffer->objects.size(); i++) { events[i].first.wait(); events[i].second.wait(); SparseFrameBuffer *fbi = (SparseFrameBuffer *)framebuffer->objects[i]; framebuffer->rowmajorFb->writeTiles(fbi); } framebuffer->rowmajorFb->setCompletedEvent(OSP_WORLD_RENDERED); // We need to call post-processing operations on fully compositioned // (rowmajorFb) frame buffer and wait for it to finish devicert::AsyncEvent event = framebuffer->rowmajorFb->postProcess(); event.wait(); for (uint32_t i = 0; i < framebuffer->objects.size(); i++) { SparseFrameBuffer *fbi = (SparseFrameBuffer *)framebuffer->objects[i]; fbi->setCompletedEvent(OSP_FRAME_FINISHED); } framebuffer->rowmajorFb->setCompletedEvent(OSP_FRAME_FINISHED); } std::string MultiDeviceLoadBalancer::toString() const { return "ospray::MultiDeviceLoadBalancer"; } } // namespace ospray RenderKit-ospray-85af292/modules/multiDevice/MultiDeviceLoadBalancer.h000066400000000000000000000015051464752671100260310ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "MultiDeviceFrameBuffer.h" #include "MultiDeviceObject.h" #include "render/LoadBalancer.h" #include "rkcommon/utility/ArrayView.h" namespace ospray { struct MultiDeviceLoadBalancer { MultiDeviceLoadBalancer( const std::vector> &loadBalancers); void renderFrame(api::MultiDeviceFrameBuffer *framebuffer, api::MultiDeviceObject *renderer, api::MultiDeviceObject *camera, api::MultiDeviceObject *world); std::string toString() const; private: // The subdevice load balancers that this multidevice load balancer will // distribute the rendering workload over std::vector> loadBalancers; }; } // namespace ospray RenderKit-ospray-85af292/modules/multiDevice/MultiDeviceModuleInit.cpp000066400000000000000000000020471464752671100261300ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // We don't want an instance of ObjectFactory static table in this library // so we have to include it with import define so the table will be imported // from 'ospray' library #include "common/ObjectFactory.h" #include "MultiDevice.h" #include "MultiDeviceLoadBalancer.h" #include "common/OSPCommon.h" extern "C" OSPError OSPRAY_DLLEXPORT #ifdef OSPRAY_TARGET_SYCL ospray_module_init_multidevice_gpu( #else ospray_module_init_multidevice_cpu( #endif int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/) { using namespace ospray; auto status = moduleVersionCheck(versionMajor, versionMinor); if (status == OSP_NO_ERROR) { // Run the ISPC module's initialization function as well to register local // types #ifdef OSPRAY_TARGET_SYCL status = ospLoadModule("gpu"); #else status = ospLoadModule("cpu"); #endif } if (status == OSP_NO_ERROR) { api::Device::registerType("multidevice"); } return status; } RenderKit-ospray-85af292/modules/multiDevice/MultiDeviceObject.h000066400000000000000000000014111464752671100247240ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/Data.h" namespace ospray { namespace api { // An object in the multidevice is just a container to hold // the handles to the actual objects of each subdevice struct MultiDeviceObject : public memory::RefCount { std::vector objects; OSPDeleterCallback freeFunction{nullptr}; const void *userData{nullptr}; const void *sharedData{nullptr}; // sharedDataDirtyReference is held temporarily to ensure consistency Data *sharedDataDirtyReference = nullptr; virtual ~MultiDeviceObject() override { delete sharedDataDirtyReference; if (freeFunction) freeFunction(userData, sharedData); } }; } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/multiDevice/MultiDeviceRenderTask.h000066400000000000000000000040471464752671100255700ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "MultiDeviceFrameBuffer.h" // ospray #include "common/Future.h" #include "fb/FrameBuffer.h" namespace ospray { namespace api { struct MultiDeviceRenderTask : public Future { MultiDeviceRenderTask(MultiDeviceFrameBuffer *fb, std::function fcn); ~MultiDeviceRenderTask() override; bool isFinished(OSPSyncEvent event = OSP_TASK_FINISHED) override; void wait(OSPSyncEvent event) override; void cancel() override; float getProgress() override; float getTaskDuration() override; private: Ref fb; std::atomic taskDuration{0.f}; std::atomic finished; std::thread thread; }; // Inlined definitions ////////////////////////////////////////////////////// inline MultiDeviceRenderTask::MultiDeviceRenderTask( MultiDeviceFrameBuffer *fb, std::function fcn) : fb(fb), finished(false) { thread = std::thread([this, fcn]() { taskDuration = fcn(); finished = true; }); } inline MultiDeviceRenderTask::~MultiDeviceRenderTask() { if (thread.joinable()) { thread.join(); } } inline bool MultiDeviceRenderTask::isFinished(OSPSyncEvent) { return finished == true; } inline void MultiDeviceRenderTask::wait(OSPSyncEvent) { if (thread.joinable()) { thread.join(); } } inline void MultiDeviceRenderTask::cancel() { for (size_t i = 0; i < fb->objects.size(); ++i) { FrameBuffer *fbi = (FrameBuffer *)fb->objects[i]; fbi->cancelFrame(); } } inline float MultiDeviceRenderTask::getProgress() { // The frame is done when all the subdevices are done, so the total progress // works out to be the average float progress = 0.0; for (size_t i = 0; i < fb->objects.size(); ++i) { FrameBuffer *fbi = (FrameBuffer *)fb->objects[i]; progress += fbi->getCurrentProgress(); } return progress / fb->objects.size(); } inline float MultiDeviceRenderTask::getTaskDuration() { return taskDuration.load(); } } // namespace api } // namespace ospray RenderKit-ospray-85af292/modules/pluggableGeometryExample/000077500000000000000000000000001464752671100237355ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/pluggableGeometryExample/CMakeLists.txt000066400000000000000000000014361464752671100265010ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # Define an option to enable/disable this module. # # Though not actually required we guard each module 'moduleName' with # a OSPRAY_MODULE_MODULENAME flag that enables/disables its building. # cmake_dependent_option( OSPRAY_MODULE_BILINEAR_PATCH "Build pluggable geometry example module (a Bilinear Patch)" OFF OSPRAY_MODULE_CPU OFF ) if (NOT OSPRAY_MODULE_BILINEAR_PATCH) return() endif() # build the actual new ospray geometry type. since this plug in # directly into the ospray core, we'll put it into a # '/ospray' subdirectory. # # This subdirectory will eventually build the # libospray_module_.so library that defiens the actual # core geometry type. # add_subdirectory(ospray) RenderKit-ospray-85af292/modules/pluggableGeometryExample/README.md000066400000000000000000000033211464752671100252130ustar00rootroot00000000000000PluggableGeometryExample: Module that demonstrates how to use the Module Concept to extend OSPRay with a new geometry type ========================================================================================================================== This module serves as a simple example of 1) how to define a new ospray geometry type and 'plug' this into ospray. In particular, how this geometry can use its "commit()" method to query data the user has added to it. 2) how to use embree and ispc to implement this geometry type's intersect() and postIntersect() functoins 3) how to do this through a 'module' that is dynamically loadable; and 4) how to use this module - and geometry - from within your own applications Using this example you should be able to write your own modules, with your own geometry types. For the purpose of this geometry we have chosen a intentionally very simple type of geometry - a bilinear patch. Notes: - Names matter. E.g., for ospray to find the module "myModuleName" the module _has_ to build a library of name libospray_module_myModuleName.so. Similarly, a module that wants to define a new geometry type "MyGeometry" _has_ to have a OSPRAY_REGISTER_GEOMETRY(WhatEverYouCallItInYourImplementation,MyGeometry) macro invocation in one of its cpp files. - This example only demonstrates how to write a _geometry_ type. It is similarly possible to write new renderers, new camera types, new volume types, etc. Running the Example =================== Build OSPRay (make sure that OSPRAY_MODULE_BILINEAR_PATCH is on!), then in your build directory, do a ./ospExampleViewer --sg:module bilinear_patches ../modules/pluggableGeometryExample/examples/shadows.patches --renderer pt RenderKit-ospray-85af292/modules/pluggableGeometryExample/examples/000077500000000000000000000000001464752671100255535ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/pluggableGeometryExample/examples/shadows.patches000066400000000000000000000003411464752671100305720ustar00rootroot00000000000000# a sample file of patches. any line that does not contain three # floats is ignored, and any set of four successive 3-float lines # form one bi-linear patch -1 -1 0 2 -1 0 -1 2 0 2 2 .1 0 0 -.02 1 0 -.02 0 1 -.02 1 1 -.1 RenderKit-ospray-85af292/modules/pluggableGeometryExample/examples/test1.patches000066400000000000000000000003561464752671100301700ustar00rootroot00000000000000# a sample file of patches. any line that does not contain three # floats is ignored, and any set of four successive 3-float lines # form one bi-linear patch 0 0 0 1 0 0 0 0 .1 1 1 .1 2 2 2 2 2 3 2 3 2 2 3 3 2 0 1 2 1 0 3 1 1 3 0 0 RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/000077500000000000000000000000001464752671100252525ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/CMakeLists.txt000066400000000000000000000041751464752671100300210ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # this subdirectory builds the actual ospray plugin into a library # "libospray_module_.so". # # This shared library can depend on libospray, but should _not_ assume # that it is living in the same address space as the application: When # running in MPI mode ospray will, upon encountering the # ospLoadModule(""), actually load and use this library on # every worker node (which will typically not run the application). As # such, the library should _not_ "commuincate" with the application # through global variables or globally defined functions, and instead # communicate solely through the ospNewGeometry(...), ospSet...(), # ospCommit(...) etc functionality provided by ospray. # build the actual shared library that defines the geometry. # # Note the name is important: In order for ospray to properly find and # initialize a module referenced by a call to # "ospLoadModule() this module _has_ to # # a) be called libospray_module_.so, and # b) contain a (extern C linkage) initialization routine named # OSPError ospray_module_init_(int16_t versionMajor, # int16_t versionMinor, int16_t versionPatch) # add_library(ospray_module_bilinear_patches SHARED) include_directories_ispc(${RKCOMMON_INCLUDE_DIRS}) # Required definitions for ISPC hybrid code for CPU add_definitions_ispc( -DOSPRAY_BEGIN_ISPC_NAMESPACE= -DOSPRAY_END_ISPC_NAMESPACE= -DSYCL_EXTERNAL= ) ispc_target_add_sources(ospray_module_bilinear_patches # the cpp file that contains all the plugin code - parsing # parameters in ospCommit(), creating and registering the object, # building accel structures, etc geometry/BilinearPatches.cpp # the ispc file that contains the plugins for all vector code - ie, # for ray-primitive intersection and 'postIntersect' (reporting info # on a previously computed ray-prim intersection) geometry/BilinearPatches.ispc # and finally, the module init code (not doing much, but must be there) moduleInit.cpp ) target_link_libraries(ospray_module_bilinear_patches PUBLIC ospray_module_cpu) RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/geometry/000077500000000000000000000000001464752671100271055ustar00rootroot00000000000000RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.cpp000066400000000000000000000034751464752671100326570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "BilinearPatches.h" // 'export'ed functions from the ispc file: #include "geometry/BilinearPatches_ispc.h" // ospray core: #include // _everything_ in the ospray core universe should _always_ be in the // 'ospray' namespace. namespace ospray { // though not required, it is good practice to put any module into // its own namespace (isnide of ospray:: ). Unlike for the naming of // library and init function, the naming for this namespace doesn't // particularlly matter. E.g., 'bilinearPatch', 'module_blp', // 'bilinar_patch' etc would all work equally well. namespace blp { BilinearPatches::BilinearPatches(api::ISPCDevice &device) : AddStructShared(device.getDRTDevice(), device, FFG_NONE) { getSh()->super.postIntersect = ispc::BilinearPatches_postIntersect_addr(); getSh()->super.intersect = ispc::BilinearPatches_intersect_addr(); } // commit - this is the function that parses all the parameters // that the app has proivded for this geometry. In this simple // example we're looking for a single parameter named 'patches', // which is supposed to contain a data array of all the patches' // control points. void BilinearPatches::commit() { patchesData = getParamDataT("vertices", true); if (!patchesData || !patchesData->compact()) throw std::runtime_error("BilinearPatches needs compact 'vertices' data!"); createEmbreeUserGeometry((RTCBoundsFunction)&ispc::BilinearPatches_bounds); getSh()->patchArray = (ispc::Patch *)patchesData->data(); getSh()->super.numPrimitives = numPrimitives(); postCreationInfo(patchesData->size()); } size_t BilinearPatches::numPrimitives() const { return patchesData->size() * sizeOf(patchesData->type) / sizeof(ispc::Patch); } } // namespace blp } // namespace ospray RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.h000066400000000000000000000054021464752671100323140ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray/geometry/BilinearPatches.h Defines a new ospray // geometry type (of name 'bilinear_patches'). Input to the geometry is // a single data array (named 'patches') that consists of for vec3fs // per patch. // ospcomon: vec3f, box3f, etcpp - generic helper stuff #include "rkcommon/math/box.h" #include "rkcommon/math/vec.h" // ospray: everything that's related to the ospray ray tracing core #include "geometry/Geometry.h" // ispc shared: header containing structures shared with ispc #include "BilinearPatchesShared.h" // _everything_ in the ospray core universe should _always_ be in the // 'ospray' namespace. namespace ospray { // though not required, it is good practice to put any module into // its own namespace (isnide of ospray:: ). Unlike for the naming of // library and init function, the naming for this namespace doesn't // particularlly matter. E.g., 'bilinearPatch', 'module_blp', // 'bilinar_patch' etc would all work equally well. namespace blp { // import rkcommon component - vec3f etc using namespace rkcommon; // a geometry type that implements (a set of) bi-linear // patches. This implements a new ospray geometry, and as such has // to // a) derive from ospray::Geometry // b) implement a 'commit()' message that parses the // parameters/data arrays that the app has specified as inputs // c) create an actual ospray geometry instance with the // proper intersect() and postIntersect() functions. // Note that how this class is called does not particularly matter; // all that matters is under which name it is registered in the cpp // file (see comments on OSPRAY_REGISTER_GEOMETRY) struct BilinearPatches : public AddStructShared { // data layout of a single patch. note we do not actually use // this class anywhere on the c++ side of this example, it is // only for illustrative purposes. The input data should come // as a data array of N such patches (we compute N // automatically based on the size of this array) // // struct Patch // { // vec3f controlPoint[2][2]; // }; BilinearPatches(api::ISPCDevice &); virtual ~BilinearPatches() override = default; // the commit() message that gets called upon the app calling // "ospCommit()" virtual void commit() override; virtual size_t numPrimitives() const override; protected: // the input data array. the data array contains a list of // patches, each of which consists of four vec3fs. Note in this // example we do not particularly care about whether this comes // as a plain array of floats (with 12 floats per patch), or as // a array of vec3fs. Ref> patchesData; }; } // namespace blp } // namespace ospray RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.ispc000066400000000000000000000144501464752671100330260ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "common/Ray.ih" #include "geometry/Geometry.ih" #include "rkcommon/math/LinearSpace.ih" #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" // c++ shared #include "BilinearPatchesShared.h" void BilinearPatches_postIntersect(const Geometry *uniform geometry, varying DifferentialGeometry &dg, const varying Ray &ray, uniform int64 flags) { const BilinearPatches *uniform self = (const BilinearPatches *uniform)geometry; dg.Ng = dg.Ns = normalize(ray.Ng); } // to be able to have embree build a data structure over us we have // to be able to tell it the bounding box for each primitimve. this // is the callback embree calls for querying the (uniform) bounding // box for a single given primitmive 'primID' export void BilinearPatches_bounds( const RTCBoundsFunctionArguments *uniform args) { uniform BilinearPatches *uniform self = (uniform BilinearPatches * uniform) args->geometryUserPtr; uniform int primID = args->primID; Patch *uniform patch = self->patchArray + primID; box3fa *uniform out = (box3fa * uniform) args->bounds_o; *out = box_extend(box_extend(box_extend(box_extend(make_box3fa_empty(), make_vec3f(patch->v00)), make_vec3f(patch->v01)), make_vec3f(patch->v10)), make_vec3f(patch->v11)); } bool recursiveBisection(varying Ray &ray, const uniform bool isOcclusionTest, const varying LinearSpace3f &frame, const uniform vec3f p00, const uniform vec3f p01, const uniform vec3f p10, const uniform vec3f p11, const uniform float u0, const uniform float u1, const uniform float v0, const uniform float v1, uniform int recursionsLeft) { // compute signs to x plane const float x0 = dot(p00 - ray.org, frame.vx); const float x1 = dot(p01 - ray.org, frame.vx); const float x2 = dot(p10 - ray.org, frame.vx); const float x3 = dot(p11 - ray.org, frame.vx); const float min_x = min(min(x0, x1), min(x2, x3)); if (min_x > 0.f) return false; const float max_x = max(max(x0, x1), max(x2, x3)); if (max_x < 0.f) return false; // compute signs to y plane const float y0 = dot(p00 - ray.org, frame.vy); const float y1 = dot(p01 - ray.org, frame.vy); const float y2 = dot(p10 - ray.org, frame.vy); const float y3 = dot(p11 - ray.org, frame.vy); const float min_y = min(min(y0, y1), min(y2, y3)); if (min_y > 0.f) return false; const float max_y = max(max(y0, y1), max(y2, y3)); if (max_y < 0.f) return false; // distance test const float t0 = dot(p00 - ray.org, frame.vz); const float t1 = dot(p01 - ray.org, frame.vz); const float t2 = dot(p10 - ray.org, frame.vz); const float t3 = dot(p11 - ray.org, frame.vz); // const float min_t = min(min(t0,t1),min(t2,t3)); // if (min_t > 0.f) return false; const float max_t = max(max(t0, t1), max(t2, t3)); if (max_t < 0.f) return false; const uniform float uc = 0.5f * (u0 + u1); const uniform float vc = 0.5f * (v0 + v1); if (recursionsLeft == 0) { const float t = 0.25 * (t0 + t1 + t2 + t3); if (t <= ray.t0 || t >= ray.t) return false; if (!isOcclusionTest) { ray.t = t; ray.u = uc; ray.v = vc; const vec3f pu0 = p00 + ray.u * (p01 - p00); const vec3f pu1 = p10 + ray.u * (p11 - p10); const vec3f pv0 = p00 + ray.v * (p10 - p00); const vec3f pv1 = p01 + ray.v * (p11 - p01); ray.Ng = cross(pu1 - pu0, pv1 - pv0); } return true; } else { const uniform vec3f p0c = 0.5f * (p01 + p00); const uniform vec3f p1c = 0.5f * (p11 + p10); const uniform vec3f pc0 = 0.5f * (p10 + p00); const uniform vec3f pc1 = 0.5f * (p11 + p01); const uniform vec3f pcc = 0.25f * (p00 + p01 + p10 + p11); bool hit = false; hit |= recursiveBisection(ray, isOcclusionTest, frame, p00, p0c, pc0, pcc, u0, uc, v0, vc, recursionsLeft - 1); hit |= recursiveBisection(ray, isOcclusionTest, frame, pc0, pcc, p10, p1c, u0, uc, vc, v1, recursionsLeft - 1); hit |= recursiveBisection(ray, isOcclusionTest, frame, p0c, p01, pcc, pc1, uc, u1, v0, vc, recursionsLeft - 1); hit |= recursiveBisection(ray, isOcclusionTest, frame, pcc, pc1, p1c, p11, uc, u1, vc, v1, recursionsLeft - 1); return hit; } } // this is the function callback the embree calls to compute a single // ray-primitive intersection. For sake of simplicity we'll use a very, // very simple recursive test here - this is neither fast nor elegant, // but does show that you can do mere arbitrary stuff in a ISPC kernel, // including 'true' recursion. void BilinearPatches_intersect_kernel( const RTCIntersectFunctionNArguments *uniform args, const uniform bool isOcclusionTest) { // make sure to set the mask if (!args->valid[programIndex]) return; uniform BilinearPatches *uniform self = (uniform BilinearPatches * uniform) args->geometryUserPtr; uniform unsigned int primID = args->primID; // this assumes that the args->rayhit is actually a pointer toa varying ray! varying Ray *uniform ray = (varying Ray * uniform) args->rayhit; Patch *uniform patch = self->patchArray + primID; // create a simple coordinate system with x and y directions // orthogonal to the ray const LinearSpace3f coordSys = frame(ray->dir); bool hit = recursiveBisection(*ray, isOcclusionTest, coordSys, patch->v00, patch->v01, patch->v10, patch->v11, 0.f, 1.f, 0.f, 1.f, /* number of bisections */ 10); if (hit) { if (isOcclusionTest) { ray->t = neg_inf; } else { ray->primID = primID; ray->geomID = args->geomID; ray->instID = args->context->instID[0]; } } } export void *uniform BilinearPatches_intersect_addr() { return BilinearPatches_intersect_kernel; } export void *uniform BilinearPatches_postIntersect_addr() { return BilinearPatches_postIntersect; } RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/geometry/BilinearPatchesShared.h000066400000000000000000000013511464752671100334420ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "geometry/GeometryShared.h" #ifdef __cplusplus namespace ispc { #endif // __cplusplus // input data for a single patch struct Patch { vec3f v00, v01, v10, v11; }; struct BilinearPatches { // inherit from "Geometry" class: since ISPC doesn't support // inheritance we simply put the "parent" class as the first // member; this way any typecast to the parent class will get the // right members (including 'virtual' function pointers, etc) Geometry super; size_t numPatches; Patch *patchArray; #ifdef __cplusplus BilinearPatches() : numPatches(0), patchArray(nullptr) {} }; } // namespace ispc #else }; #endif // __cplusplus RenderKit-ospray-85af292/modules/pluggableGeometryExample/ospray/moduleInit.cpp000066400000000000000000000045471464752671100301010ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /*! \file ospray/moduleInit \brief Defines the module initialization callback */ #include "geometry/BilinearPatches.h" #include "ospray/version.h" /*! _everything_ in the ospray core universe should _always_ be in the 'ospray' namespace. */ namespace ospray { /*! though not required, it is good practice to put any module into its own namespace (isnide of ospray:: ). Unlike for the naming of library and init function, the naming for this namespace doesn't particularlly matter. E.g., 'bilinearPatch', 'module_blp', 'bilinar_patch' etc would all work equally well. */ namespace blp { /*! the actual module initialization function. This function gets called exactly once, when the module gets first loaded through 'ospLoadModule'. Notes: a) this function does _not_ get called if the application directly links to libospray_module_ (which it shouldn't!). Modules should _always_ be loaded through ospLoadModule. b) it is _not_ valid for the module to do ospray _api_ calls inside such an intiailzatoin function. Ie, you can _not_ do a ospLoadModule("anotherModule") from within this function (but you could, of course, have this module dynamically link to the other one, and call its init function) c) in order for ospray to properly resolve that symbol, it _has_ to have extern C linkage, and it _has_ to correspond to name of the module and shared library containing this module (see comments regarding library name in CMakeLists.txt) */ extern "C" OSPError OSPRAY_DLLEXPORT ospray_module_init_bilinear_patches( int16_t versionMajor, int16_t versionMinor, int16_t /*versionPatch*/) { auto status = moduleVersionCheck(versionMajor, versionMinor); if (status == OSP_NO_ERROR) { /*! maybe one of the most important parts of this example: this function 'registers' the BilinearPatches class under the ospray geometry type name of 'bilinear_patches'. It is _this_ name that one can now (assuming the module has been loaded with ospLoadModule(), of course) create geometries with; i.e., OSPGeometry geom = ospNewGeometry("bilinear_patches") ; */ Geometry::registerType("bilinear_patches"); } return status; } } // namespace blp } // namespace ospray RenderKit-ospray-85af292/ospray/000077500000000000000000000000001464752671100166105ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/CMakeLists.txt000066400000000000000000000050341464752671100213520ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # ------------------------------------------------------- # Setup ospray include directories and source files # ------------------------------------------------------- set(OSPRAY_RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/ospray.rc) set(OSPRAY_RESOURCE ${OSPRAY_RESOURCE} PARENT_SCOPE) option(OSPRAY_ENABLE_PROFILING "Enable performance tracing" OFF ) set(OSPRAY_SOURCES ${OSPRAY_RESOURCE} api/API.cpp api/Device.cpp api/ospray_util_impl.cpp api/ospray_cpp_defs.cpp common/OSPCommon.cpp common/Managed.cpp fb/ImageOp.cpp include/ospray/ospray.h include/ospray/ospray_util.h include/ospray/OSPEnums.h include/ospray/ospray_cpp.h include/ospray/ospray_cpp/Camera.h include/ospray/ospray_cpp/Data.h include/ospray/ospray_cpp/FrameBuffer.h include/ospray/ospray_cpp/Geometry.h include/ospray/ospray_cpp/Light.h include/ospray/ospray_cpp/ManagedObject.h include/ospray/ospray_cpp/Material.h include/ospray/ospray_cpp/ImageOperation.h include/ospray/ospray_cpp/Renderer.h include/ospray/ospray_cpp/Texture.h include/ospray/ospray_cpp/TransferFunction.h include/ospray/ospray_cpp/Volume.h include/ospray/ospray_cpp/World.h ) # ------------------------------------------------------- # Install SDK headers # ------------------------------------------------------- get_subdirectories(SUBDIRS ${CMAKE_CURRENT_LIST_DIR}) foreach(dir ${SUBDIRS}) if (NOT "${dir}" STREQUAL include) install(DIRECTORY ${dir} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray/SDK COMPONENT devel FILES_MATCHING PATTERN *.h ) endif() endforeach() ############################################################## # Build the ospray library ############################################################## add_library(ospray SHARED ${OSPRAY_SOURCES}) target_link_libraries(ospray PUBLIC $) ospray_install_library(ospray lib ON) target_include_directories(ospray PUBLIC $ $ $ $ ) if (OSPRAY_ENABLE_PROFILING) target_compile_definitions(ospray PUBLIC RKCOMMON_ENABLE_PROFILING ) endif() ############################################################## # Configure find_package files ############################################################## include(${CMAKE_SOURCE_DIR}/cmake/ospray_cmake_config.cmake) RenderKit-ospray-85af292/ospray/api/000077500000000000000000000000001464752671100173615ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/api/API.cpp000066400000000000000000000517301464752671100205040ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "rkcommon/os/library.h" #include "rkcommon/utility/OnScopeExit.h" #include "rkcommon/utility/StringManip.h" #include "rkcommon/utility/getEnvVar.h" // ospray #include "Device.h" #include "common/OSPCommon.h" #include "include/ospray/ospray.h" #ifdef _WIN32 #include // for getpid #endif using ospray::api::currentDevice; using ospray::api::Device; using ospray::api::deviceIsSet; static_assert(sizeof(bool) == 1, "OSPRay's implementation assumes the size of 'bool' to be 1 byte."); /*! \file api.cpp implements the public ospray api functions by routing them to a respective \ref device */ #define THROW_IF_NULL(obj, name) \ if (obj == nullptr) \ throw std::runtime_error(std::string("null ") + name \ + std::string(" provided to ") + __FUNCTION__) // convenience macros for repeated use of the above #define THROW_IF_NULL_OBJECT(obj) THROW_IF_NULL(obj, "handle") #define THROW_IF_NULL_STRING(str) THROW_IF_NULL(str, "string") #define ASSERT_DEVICE() \ if (!deviceIsSet()) \ throw std::runtime_error( \ "no valid OSPRay device while calling an API function, likely" \ " either before calling ospInit() / ospNewDevice() plus ospSetCurrentDevice()," \ " or after calling ospShutdown() / ospDeviceRelease(); pid: " \ + std::to_string(getpid())) #define OSPRAY_CATCH_BEGIN \ try { \ auto *fcn_name_ = __PRETTY_FUNCTION__; \ rkcommon::utility::OnScopeExit guard([&]() { postTraceMsg(fcn_name_); }); #define OSPRAY_CATCH_END(a) \ } \ catch (const std::bad_alloc &) \ { \ handleError(OSP_OUT_OF_MEMORY, "OSPRay was unable to allocate memory"); \ return a; \ } \ catch (const std::exception &e) \ { \ handleError(OSP_UNKNOWN_ERROR, e.what()); \ return a; \ } \ catch (...) \ { \ handleError(OSP_UNKNOWN_ERROR, "an unrecognized exception was caught"); \ return a; \ } using namespace ospray; static inline void loadModulesFromEnvironmentVar() { auto OSPRAY_LOAD_MODULES = utility::getEnvVar("OSPRAY_LOAD_MODULES"); if (OSPRAY_LOAD_MODULES) { auto module_names = utility::split(OSPRAY_LOAD_MODULES.value(), ','); for (auto &name : module_names) loadLocalModule(name); } } /////////////////////////////////////////////////////////////////////////////// // OSPRay Initialization ////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPError ospInit(int *_ac, const char **_av) OSPRAY_CATCH_BEGIN { auto ¤tDevice = Device::current; if (currentDevice) { throw std::runtime_error("device already exists [ospInit() called twice?]"); } loadModulesFromEnvironmentVar(); if (_ac && _av) { for (int i = 1; i < *_ac;) { std::string av(_av[i]); if (rkcommon::utility::beginsWith(av, "--osp:load-modules")) { std::string modules = getArgString(av); if (modules == "") { throw std::runtime_error( "Invalid module name(s) provided to --osp:load-modules. Must be " "formatted as [,,...]"); } std::vector moduleList = rkcommon::utility::split(modules, ','); for (std::string &moduleName : moduleList) { loadLocalModule(moduleName); } removeArgs(*_ac, _av, i, 1); } else if (rkcommon::utility::beginsWith(av, "--osp:device=")) { // ALOK: explicitly checking with the equals sign so this does not get // clobbered by --osp:device-param std::string deviceName = getArgString(av); try { currentDevice = Device::createDevice(deviceName.c_str()); } catch (const std::runtime_error &) { throw std::runtime_error("Failed to create device of type '" + deviceName + "'! Perhaps you spelled the " "device name wrong or didn't link the " "library which defines the device?"); } removeArgs(*_ac, _av, i, 1); } else { // Ignore other arguments ++i; } } } // no device created on cmd line, yet, so default to ISPCDevice if (!deviceIsSet()) { auto OSPRAY_DEVICE = utility::getEnvVar("OSPRAY_DEVICE"); if (OSPRAY_DEVICE) { const auto &device_name = OSPRAY_DEVICE.value(); currentDevice = Device::createDevice(device_name.c_str()); } else { ospLoadModule("cpu"); currentDevice = Device::createDevice("cpu"); } } ospray::initFromCommandLine(_ac, &_av); currentDevice->commit(); currentDevice->refDec(); return OSP_NO_ERROR; } OSPRAY_CATCH_END(OSP_INVALID_OPERATION) extern "C" int64_t ospDeviceGetProperty( OSPDevice _device, OSPDeviceProperty _deviceProperty) OSPRAY_CATCH_BEGIN { auto *device = (Device *)_device; return device->getProperty(_deviceProperty); } OSPRAY_CATCH_END(0) extern "C" void ospShutdown() OSPRAY_CATCH_BEGIN { Device::current = nullptr; LibraryRepository::cleanupInstance(); } OSPRAY_CATCH_END() extern "C" OSPDevice ospNewDevice(const char *deviceType) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(deviceType); return (OSPDevice)Device::createDevice(deviceType); } OSPRAY_CATCH_END(nullptr) extern "C" void ospSetCurrentDevice(OSPDevice _device) OSPRAY_CATCH_BEGIN { auto *device = (Device *)_device; if ((device) && (!device->isCommitted())) { throw std::runtime_error("You must commit the device before using it!"); } Device::current = device; } OSPRAY_CATCH_END() extern "C" OSPDevice ospGetCurrentDevice() OSPRAY_CATCH_BEGIN { auto *ptr = Device::current.ptr; if (ptr) ptr->refInc(); return (OSPDevice)ptr; } OSPRAY_CATCH_END(nullptr) extern "C" void ospDeviceSetParam(OSPDevice _object, const char *id, OSPDataType type, const void *mem) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); THROW_IF_NULL_STRING(id); Device *object = (Device *)_object; switch (type) { case OSP_STRING: object->setParam(id, std::string((const char *)mem)); break; case OSP_INT: object->setParam(id, *(int *)mem); break; case OSP_UINT: object->setParam(id, *(uint32_t *)mem); break; case OSP_BOOL: object->setParam(id, *(bool *)mem); break; case OSP_VOID_PTR: object->setParam(id, *(void **)&mem); break; default: throw std::runtime_error("parameter type not handled for OSPDevice!"); }; } OSPRAY_CATCH_END() extern "C" void ospDeviceRemoveParam( OSPDevice _object, const char *id) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); THROW_IF_NULL_STRING(id); Device *object = (Device *)_object; object->removeParam(id); } OSPRAY_CATCH_END() extern "C" void ospDeviceSetStatusCallback(OSPDevice _object, OSPStatusCallback callback, void *userData) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); auto *device = (Device *)_object; if (callback == nullptr) { device->msg_fcn = [](void *, const char *) {}; device->statusUserData = nullptr; } else { device->msg_fcn = callback; device->statusUserData = userData; } } OSPRAY_CATCH_END() extern "C" void ospDeviceSetErrorCallback(OSPDevice _object, OSPErrorCallback callback, void *userData) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); auto *device = (Device *)_object; if (callback == nullptr) { device->error_fcn = [](void *, OSPError, const char *) {}; device->errorUserData = nullptr; } else { device->error_fcn = callback; device->errorUserData = userData; } } OSPRAY_CATCH_END() extern "C" OSPError ospDeviceGetLastErrorCode( OSPDevice _object) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); auto *device = (Device *)_object; return device->lastErrorCode; } OSPRAY_CATCH_END(OSP_NO_ERROR) extern "C" const char *ospDeviceGetLastErrorMsg( OSPDevice _object) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); auto *device = (Device *)_object; return device->lastErrorMsg.c_str(); } OSPRAY_CATCH_END(nullptr) extern "C" void ospDeviceCommit(OSPDevice _object) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); auto *object = (Device *)_object; object->commit(); } OSPRAY_CATCH_END() extern "C" void ospDeviceRelease(OSPDevice _object) OSPRAY_CATCH_BEGIN { auto *object = (Device *)_object; if (!object) return; object->refDec(); } OSPRAY_CATCH_END() extern "C" void ospDeviceRetain(OSPDevice _object) OSPRAY_CATCH_BEGIN { auto *object = (Device *)_object; if (!object) return; object->refInc(); } OSPRAY_CATCH_END() extern "C" OSPError ospLoadModule(const char *module_name) OSPRAY_CATCH_BEGIN { if (deviceIsSet()) { return (OSPError)currentDevice().loadModule(module_name); } else { return loadLocalModule(module_name); } } OSPRAY_CATCH_END(OSP_UNKNOWN_ERROR) /////////////////////////////////////////////////////////////////////////////// // OSPRay Data Arrays ///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPData ospNewSharedData(const void *sharedData, OSPDataType type, uint64_t numItems1, int64_t byteStride1, uint64_t numItems2, int64_t byteStride2, uint64_t numItems3, int64_t byteStride3, OSPDeleterCallback freeFunction, const void *userPtr) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); OSPData data = currentDevice().newSharedData(sharedData, type, ospray::vec3ul(numItems1, numItems2, numItems3), ospray::vec3l(byteStride1, byteStride2, byteStride3), freeFunction, userPtr); return data; } OSPRAY_CATCH_END(nullptr) extern "C" OSPData ospNewData(OSPDataType type, uint64_t numItems1, uint64_t numItems2, uint64_t numItems3) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); OSPData data = currentDevice().newData( type, ospray::vec3ul(numItems1, numItems2, numItems3)); return data; } OSPRAY_CATCH_END(nullptr) extern "C" void ospCopyData(const OSPData source, OSPData destination, uint64_t dstIdx1, uint64_t dstIdx2, uint64_t dstIdx3) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); currentDevice().copyData( source, destination, ospray::vec3ul(dstIdx1, dstIdx2, dstIdx3)); } OSPRAY_CATCH_END() /////////////////////////////////////////////////////////////////////////////// // Renderable Objects ///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPLight ospNewLight(const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); OSPLight light = currentDevice().newLight(_type); return light; } OSPRAY_CATCH_END(nullptr) extern "C" OSPCamera ospNewCamera(const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); OSPCamera camera = currentDevice().newCamera(_type); return camera; } OSPRAY_CATCH_END(nullptr) extern "C" OSPGeometry ospNewGeometry(const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); OSPGeometry geometry = currentDevice().newGeometry(_type); return geometry; } OSPRAY_CATCH_END(nullptr) extern "C" OSPVolume ospNewVolume(const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); OSPVolume volume = currentDevice().newVolume(_type); return volume; } OSPRAY_CATCH_END(nullptr) extern "C" OSPGeometricModel ospNewGeometricModel( OSPGeometry geom) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); OSPGeometricModel instance = currentDevice().newGeometricModel(geom); return instance; } OSPRAY_CATCH_END(nullptr) extern "C" OSPVolumetricModel ospNewVolumetricModel( OSPVolume volume) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); OSPVolumetricModel instance = currentDevice().newVolumetricModel(volume); return instance; } OSPRAY_CATCH_END(nullptr) /////////////////////////////////////////////////////////////////////////////// // Model Meta-Data //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPMaterial ospNewMaterial( const char *material_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(material_type); ASSERT_DEVICE(); auto material = currentDevice().newMaterial(material_type); return material; } OSPRAY_CATCH_END(nullptr) extern "C" OSPTransferFunction ospNewTransferFunction( const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); auto transferFunction = currentDevice().newTransferFunction(_type); return transferFunction; } OSPRAY_CATCH_END(nullptr) extern "C" OSPTexture ospNewTexture(const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); OSPTexture texture = currentDevice().newTexture(_type); return texture; } OSPRAY_CATCH_END(nullptr) /////////////////////////////////////////////////////////////////////////////// // Instancing ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPGroup ospNewGroup() OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); return currentDevice().newGroup(); } OSPRAY_CATCH_END(nullptr) extern "C" OSPInstance ospNewInstance(OSPGroup group) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); return currentDevice().newInstance(group); } OSPRAY_CATCH_END(nullptr) /////////////////////////////////////////////////////////////////////////////// // Top-level Worlds /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPWorld ospNewWorld() OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); return currentDevice().newWorld(); } OSPRAY_CATCH_END(nullptr) extern "C" OSPBounds ospGetBounds(OSPObject obj) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(obj); ASSERT_DEVICE(); box3f bounds = currentDevice().getBounds(obj); return (OSPBounds &)bounds; } OSPRAY_CATCH_END({}) /////////////////////////////////////////////////////////////////////////////// // Object + Parameter Lifetime Management ///////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" void ospSetParam(OSPObject _object, const char *id, OSPDataType type, const void *mem) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); THROW_IF_NULL_STRING(id); ASSERT_DEVICE(); currentDevice().setObjectParam(_object, id, type, mem); } OSPRAY_CATCH_END() extern "C" void ospRemoveParam( OSPObject _object, const char *id) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); THROW_IF_NULL_STRING(id); ASSERT_DEVICE(); currentDevice().removeObjectParam(_object, id); } OSPRAY_CATCH_END() extern "C" void ospCommit(OSPObject _object) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); ASSERT_DEVICE(); currentDevice().commit(_object); } OSPRAY_CATCH_END() extern "C" void ospRelease(OSPObject _object) OSPRAY_CATCH_BEGIN { if (!_object) return; ASSERT_DEVICE(); currentDevice().release(_object); } OSPRAY_CATCH_END() extern "C" void ospRetain(OSPObject _object) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(_object); ASSERT_DEVICE(); currentDevice().retain(_object); } OSPRAY_CATCH_END() /////////////////////////////////////////////////////////////////////////////// // FrameBuffer Manipulation /////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPFrameBuffer ospNewFrameBuffer(int size_x, int size_y, OSPFrameBufferFormat mode, uint32_t channels) OSPRAY_CATCH_BEGIN { ASSERT_DEVICE(); // remove OSP_FB_VARIANCE when OSP_FB_ACCUM is not present uint32_t ch = channels; if ((channels & OSP_FB_ACCUM) == 0) ch &= ~OSP_FB_VARIANCE; return currentDevice().frameBufferCreate(vec2i(size_x, size_y), mode, ch); } OSPRAY_CATCH_END(nullptr) extern "C" OSPImageOperation ospNewImageOperation( const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); int L = strlen(_type); char *type = STACK_BUFFER(char, L + 1); for (int i = 0; i <= L; i++) { char c = _type[i]; if (c == '-' || c == ':') c = '_'; type[i] = c; } OSPImageOperation op = currentDevice().newImageOp(type); return op; } OSPRAY_CATCH_END(nullptr) extern "C" const void *ospMapFrameBuffer( OSPFrameBuffer fb, OSPFrameBufferChannel channel) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(fb); ASSERT_DEVICE(); return currentDevice().frameBufferMap(fb, channel); } OSPRAY_CATCH_END(nullptr) extern "C" void ospUnmapFrameBuffer( const void *mapped, OSPFrameBuffer fb) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(fb); THROW_IF_NULL(mapped, "pointer"); ASSERT_DEVICE(); currentDevice().frameBufferUnmap(mapped, fb); } OSPRAY_CATCH_END() extern "C" float ospGetVariance(OSPFrameBuffer fb) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(fb); ASSERT_DEVICE(); return currentDevice().getVariance(fb); } OSPRAY_CATCH_END(inf) extern "C" void ospResetAccumulation(OSPFrameBuffer fb) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(fb); ASSERT_DEVICE(); currentDevice().resetAccumulation(fb); } OSPRAY_CATCH_END() /////////////////////////////////////////////////////////////////////////////// // Frame Rendering //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// extern "C" OSPRenderer ospNewRenderer(const char *_type) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_STRING(_type); ASSERT_DEVICE(); std::string type(_type); for (size_t i = 0; i < type.size(); i++) { if (type[i] == '-' || type[i] == ':') type[i] = '_'; } OSPRenderer renderer = currentDevice().newRenderer(type.c_str()); return renderer; } OSPRAY_CATCH_END(nullptr) extern "C" OSPFuture ospRenderFrame(OSPFrameBuffer fb, OSPRenderer renderer, OSPCamera camera, OSPWorld world) OSPRAY_CATCH_BEGIN { THROW_IF_NULL(fb, "framebuffer"); THROW_IF_NULL(renderer, "renderer"); THROW_IF_NULL(camera, "camera"); THROW_IF_NULL(world, "world"); ASSERT_DEVICE(); return currentDevice().renderFrame(fb, renderer, camera, world); } OSPRAY_CATCH_END(nullptr) extern "C" int ospIsReady(OSPFuture f, OSPSyncEvent event) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(f); ASSERT_DEVICE(); return currentDevice().isReady(f, event); } OSPRAY_CATCH_END(1) extern "C" void ospWait(OSPFuture f, OSPSyncEvent event) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(f); ASSERT_DEVICE(); if (event == OSP_NONE_FINISHED) return; currentDevice().wait(f, event); } OSPRAY_CATCH_END() extern "C" void ospCancel(OSPFuture f) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(f); ASSERT_DEVICE(); return currentDevice().cancel(f); } OSPRAY_CATCH_END() extern "C" float ospGetProgress(OSPFuture f) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(f); ASSERT_DEVICE(); return currentDevice().getProgress(f); } OSPRAY_CATCH_END(1.f) extern "C" float ospGetTaskDuration(OSPFuture f) OSPRAY_CATCH_BEGIN { THROW_IF_NULL_OBJECT(f); ASSERT_DEVICE(); return currentDevice().getTaskDuration(f); } OSPRAY_CATCH_END(0.f) extern "C" void ospPick(OSPPickResult *result, OSPFrameBuffer fb, OSPRenderer renderer, OSPCamera camera, OSPWorld world, float screenPos_x, float screenPos_y) OSPRAY_CATCH_BEGIN { THROW_IF_NULL(fb, "framebuffer"); THROW_IF_NULL(renderer, "renderer"); THROW_IF_NULL(camera, "camera"); THROW_IF_NULL(world, "world"); ASSERT_DEVICE(); if (!result) return; *result = currentDevice().pick( fb, renderer, camera, world, vec2f(screenPos_x, screenPos_y)); } OSPRAY_CATCH_END() RenderKit-ospray-85af292/ospray/api/Device.cpp000066400000000000000000000136361464752671100212750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray #include "Device.h" #include "rkcommon/os/library.h" #include "rkcommon/tasking/tasking_system_init.h" #include "rkcommon/utility/getEnvVar.h" namespace ospray { namespace api { // Helper functions /////////////////////////////////////////////////////////// template static inline void installStatusMsgFunc(Device &device, OSTREAM_T &stream) { device.msg_fcn = [&](void *, const char *msg) { stream << msg; }; } template static inline void installErrorMsgFunc(Device &device, OSTREAM_T &stream) { device.error_fcn = [&](void *, OSPError e, const char *msg) { stream << "OSPRAY ERROR [" << e << "]: " << msg << std::endl; }; } // Device definitions ///////////////////////////////////////////////////////// Device::FactoryMap Device::dfcns; Device *Device::createInstance(const char *type) { FactoryFcn fcn = dfcns[type]; if (fcn) { auto *obj = fcn(); if (obj != nullptr) return obj; } throw std::runtime_error("Could not find Device of type: '" + std::string(type) + "'. Make sure you have the correct OSPRay libraries linked and initialized."); } memory::IntrusivePtr Device::current; uint32_t Device::logLevel = OSP_LOG_NONE; Device *Device::createDevice(const char *type) { // NOTE(jda) - If a user is manually creating the device (i.e. not using // ospInit() to do it), then we need to check if there's a // valid library for core ospray in our main symbol lookup // table. auto &repo = *LibraryRepository::getInstance(); if (!repo.libraryExists("ospray_module_cpu") && type == std::string("cpu")) repo.add(reinterpret_cast(&createDevice), "ospray_module_cpu", {OSPRAY_VERSION_MAJOR, OSPRAY_VERSION_MINOR, OSPRAY_VERSION_PATCH}); return createInstance(type); } void Device::commit() { auto OSPRAY_DEBUG = utility::getEnvVar("OSPRAY_DEBUG"); debugMode = OSPRAY_DEBUG.value_or(getParam("debug", false)); auto OSPRAY_WARN = utility::getEnvVar("OSPRAY_WARN_AS_ERROR"); warningsAreErrors = OSPRAY_WARN.value_or(getParam("warnAsError", false)); auto OSPRAY_TRACE_API = utility::getEnvVar("OSPRAY_TRACE_API"); bool traceAPI = OSPRAY_TRACE_API.value_or(getParam("traceApi", false)); if (traceAPI && !apiTraceEnabled) { auto streamPtr = std::make_shared("ospray_api_trace.txt"); trace_fcn = [=](const char *message) { auto &stream = *streamPtr; stream << message << std::endl; }; } else if (!traceAPI) { trace_fcn = [](const char *) {}; } apiTraceEnabled = traceAPI; logLevel = (OSPLogLevel)getParam("logLevel", OSP_LOG_NONE); auto logLevelStr = utility::getEnvVar("OSPRAY_LOG_LEVEL").value_or(""); logLevel = logLevelFromString(logLevelStr).value_or(logLevel); auto OSPRAY_NUM_THREADS = utility::getEnvVar("OSPRAY_NUM_THREADS"); numThreads = OSPRAY_NUM_THREADS.value_or(getParam("numThreads", -1)); auto OSPRAY_LOG_OUTPUT = utility::getEnvVar("OSPRAY_LOG_OUTPUT"); auto dst = OSPRAY_LOG_OUTPUT.value_or(getParam("logOutput", "")); if (dst == "cout") installStatusMsgFunc(*this, std::cout); else if (dst == "cerr") installStatusMsgFunc(*this, std::cerr); else if (dst == "none") msg_fcn = [](void *, const char *) {}; auto OSPRAY_ERROR_OUTPUT = utility::getEnvVar("OSPRAY_ERROR_OUTPUT"); dst = OSPRAY_ERROR_OUTPUT.value_or(getParam("errorOutput", "")); if (dst == "cout") installErrorMsgFunc(*this, std::cout); else if (dst == "cerr") installErrorMsgFunc(*this, std::cerr); else if (dst == "none") error_fcn = [](void *, OSPError, const char *) {}; if (debugMode) { logLevel = OSP_LOG_DEBUG; numThreads = 1; installStatusMsgFunc(*this, std::cout); installErrorMsgFunc(*this, std::cerr); } threadAffinity = getParam("setAffinity", AUTO_DETECT); auto OSPRAY_SET_AFFINITY = utility::getEnvVar("OSPRAY_SET_AFFINITY"); if (OSPRAY_SET_AFFINITY) threadAffinity = OSPRAY_SET_AFFINITY.value(); tasking::initTaskingSystem(numThreads); disableMipMapGeneration = getParam("disableMipMapGeneration", false); committed = true; } bool Device::isCommitted() { return committed; } bool deviceIsSet() { return Device::current.ptr != nullptr; } Device ¤tDevice() { return *Device::current; } std::string generateEmbreeDeviceCfg(const Device &device) { std::stringstream embreeConfig; if (device.debugMode) embreeConfig << " verbose=2"; if (device.threadAffinity == api::Device::AFFINITIZE) embreeConfig << ",set_affinity=1"; else if (device.threadAffinity == api::Device::DEAFFINITIZE) embreeConfig << ",set_affinity=0"; return embreeConfig.str(); } int64_t Device::getProperty(const OSPDeviceProperty prop) { /* documented properties */ switch (prop) { case OSP_DEVICE_VERSION: return 10000 * OSPRAY_VERSION_MAJOR + 100 * OSPRAY_VERSION_MINOR + OSPRAY_VERSION_PATCH; case OSP_DEVICE_VERSION_MAJOR: return OSPRAY_VERSION_MAJOR; case OSP_DEVICE_VERSION_MINOR: return OSPRAY_VERSION_MINOR; case OSP_DEVICE_VERSION_PATCH: return OSPRAY_VERSION_PATCH; case OSP_DEVICE_SO_VERSION: return OSPRAY_SOVERSION; default: handleError(OSP_INVALID_ARGUMENT, "unknown readable property"); return 0; } } utility::Optional Device::logLevelFromString(const std::string &str) { utility::Optional retval; if (str == "none") retval = OSP_LOG_NONE; else if (str == "debug") retval = OSP_LOG_DEBUG; else if (str == "info") retval = OSP_LOG_INFO; else if (str == "warning") retval = OSP_LOG_WARNING; else if (str == "error") retval = OSP_LOG_ERROR; return retval; } } // namespace api OSPTYPEFOR_DEFINITION(api::Device *); } // namespace ospray RenderKit-ospray-85af292/ospray/api/Device.h000066400000000000000000000143741464752671100207420ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/memory/IntrusivePtr.h" #include "rkcommon/utility/Optional.h" #include "rkcommon/utility/ParameterizedObject.h" // ospray #include "common/DeviceRT.h" #include "common/OSPCommon.h" #include "ospray/version.h" // std #include /*! \file device.h Defines the abstract base class for OSPRay "devices" that implement the OSPRay API */ namespace ospray { namespace api { /*! abstract base class of all 'devices' that implement the ospray API */ struct OSPRAY_CORE_INTERFACE Device : public memory::RefCountedObject, public utility::ParameterizedObject { template static void registerType(const char *type) { dfcns[type] = &allocate_device; } static Device *createInstance(const char *type); /*! singleton that points to currently active device */ static memory::IntrusivePtr current; Device() = default; virtual ~Device() override = default; static Device *createDevice(const char *type); /*! gets a device property */ virtual int64_t getProperty(const OSPDeviceProperty prop); ///////////////////////////////////////////////////////////////////////// // Main virtual interface to accepting API calls ///////////////////////////////////////////////////////////////////////// // Modules ////////////////////////////////////////////////////////////// virtual int loadModule(const char *name) = 0; // OSPRay Data Arrays /////////////////////////////////////////////////// virtual OSPData newSharedData(const void *sharedData, OSPDataType, const vec3ul &numItems, const vec3l &byteStride, OSPDeleterCallback, const void *userPtr) = 0; virtual OSPData newData(OSPDataType, const vec3ul &numItems) = 0; virtual void copyData(const OSPData source, OSPData destination, const vec3ul &destinationIndex) = 0; // Renderable Objects /////////////////////////////////////////////////// virtual OSPLight newLight(const char *type) = 0; virtual OSPCamera newCamera(const char *type) = 0; virtual OSPGeometry newGeometry(const char *type) = 0; virtual OSPVolume newVolume(const char *type) = 0; virtual OSPGeometricModel newGeometricModel(OSPGeometry geom) = 0; virtual OSPVolumetricModel newVolumetricModel(OSPVolume volume) = 0; // Model Meta-Data ////////////////////////////////////////////////////// virtual OSPMaterial newMaterial(const char *material_type) = 0; virtual OSPTransferFunction newTransferFunction(const char *type) = 0; virtual OSPTexture newTexture(const char *type) = 0; // Instancing /////////////////////////////////////////////////////////// virtual OSPGroup newGroup() = 0; virtual OSPInstance newInstance(OSPGroup group) = 0; // Top-level Worlds ///////////////////////////////////////////////////// virtual OSPWorld newWorld() = 0; virtual box3f getBounds(OSPObject) = 0; // Object + Parameter Lifetime Management /////////////////////////////// virtual void setObjectParam(OSPObject object, const char *name, OSPDataType type, const void *mem) = 0; virtual void removeObjectParam(OSPObject object, const char *name) = 0; virtual void commit(OSPObject object) = 0; virtual void release(OSPObject _obj) = 0; virtual void retain(OSPObject _obj) = 0; // FrameBuffer Manipulation ///////////////////////////////////////////// virtual OSPFrameBuffer frameBufferCreate(const vec2i &size, const OSPFrameBufferFormat mode, const uint32 channels) = 0; virtual OSPImageOperation newImageOp(const char *type) = 0; virtual const void *frameBufferMap( OSPFrameBuffer fb, const OSPFrameBufferChannel) = 0; virtual void frameBufferUnmap(const void *mapped, OSPFrameBuffer fb) = 0; virtual float getVariance(OSPFrameBuffer) = 0; virtual void resetAccumulation(OSPFrameBuffer _fb) = 0; // Frame Rendering ////////////////////////////////////////////////////// virtual OSPRenderer newRenderer(const char *type) = 0; virtual OSPFuture renderFrame( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld) = 0; virtual int isReady(OSPFuture, OSPSyncEvent) = 0; virtual void wait(OSPFuture, OSPSyncEvent) = 0; virtual void cancel(OSPFuture) = 0; virtual float getProgress(OSPFuture) = 0; virtual float getTaskDuration(OSPFuture) = 0; virtual OSPPickResult pick( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, const vec2f &) { NOT_IMPLEMENTED; } ///////////////////////////////////////////////////////////////////////// // Helper/other functions and data members ///////////////////////////////////////////////////////////////////////// virtual void commit(); bool isCommitted(); static utility::Optional logLevelFromString(const std::string &str); int numThreads{-1}; bool debugMode{false}; bool disableMipMapGeneration{false}; enum OSP_THREAD_AFFINITY { DEAFFINITIZE = 0, AFFINITIZE = 1, AUTO_DETECT = 2 }; int threadAffinity{AUTO_DETECT}; // NOTE(jda) - Keep logLevel static because the device factory function // needs to have a valid value for the initial Device creation static uint32_t logLevel; bool warningsAreErrors{false}; std::function msg_fcn{ [](void *, const char *) {}}; void *statusUserData{nullptr}; std::function error_fcn{ [](void *, OSPError, const char *) {}}; void *errorUserData{nullptr}; std::function trace_fcn{[](const char *) {}}; OSPError lastErrorCode = OSP_NO_ERROR; std::string lastErrorMsg = "no error"; // no braced initializer for MSVC12 private: bool committed{false}; bool apiTraceEnabled{false}; using FactoryFcn = Device *(*)(); using FactoryMap = std::map; static FactoryMap dfcns; template static Device *allocate_device() { return new D; } }; // Shorthand functions to query current API device // OSPRAY_CORE_INTERFACE bool deviceIsSet(); OSPRAY_CORE_INTERFACE Device ¤tDevice(); OSPRAY_CORE_INTERFACE std::string generateEmbreeDeviceCfg(const Device &device); } // namespace api OSPTYPEFOR_SPECIALIZATION(api::Device *, OSP_DEVICE); } // namespace ospray RenderKit-ospray-85af292/ospray/api/ospray_cpp_defs.cpp000066400000000000000000000016051464752671100232470ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../common/OSPCommon.h" // ospray::cpp #include "ospray/ospray_cpp.h" namespace ospray { OSPTYPEFOR_DEFINITION(cpp::Camera); OSPTYPEFOR_DEFINITION(cpp::SharedData); OSPTYPEFOR_DEFINITION(cpp::CopiedData); OSPTYPEFOR_DEFINITION(cpp::FrameBuffer); OSPTYPEFOR_DEFINITION(cpp::Future); OSPTYPEFOR_DEFINITION(cpp::GeometricModel); OSPTYPEFOR_DEFINITION(cpp::Geometry); OSPTYPEFOR_DEFINITION(cpp::Group); OSPTYPEFOR_DEFINITION(cpp::ImageOperation); OSPTYPEFOR_DEFINITION(cpp::Instance); OSPTYPEFOR_DEFINITION(cpp::Light); OSPTYPEFOR_DEFINITION(cpp::Material); OSPTYPEFOR_DEFINITION(cpp::Renderer); OSPTYPEFOR_DEFINITION(cpp::Texture); OSPTYPEFOR_DEFINITION(cpp::TransferFunction); OSPTYPEFOR_DEFINITION(cpp::Volume); OSPTYPEFOR_DEFINITION(cpp::VolumetricModel); OSPTYPEFOR_DEFINITION(cpp::World); } // namespace ospray RenderKit-ospray-85af292/ospray/api/ospray_util_impl.cpp000066400000000000000000000110421464752671100234560ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray/ospray_cpp.h" #include "ospray/ospray_util.h" extern "C" { // OSPData helpers //////////////////////////////////////////////////////////// OSPData ospNewSharedData1D( const void *sharedData, OSPDataType type, uint64_t numItems) { return ospNewSharedData(sharedData, type, numItems, 0, 1, 0, 1, 0); } OSPData ospNewAssignedData1D(const void *sharedData, OSPDataType type, uint64_t numItems, OSPDeleterCallback freeFunction, const void *userPtr) { return ospNewSharedData( sharedData, type, numItems, 0, 1, 0, 1, 0, freeFunction, userPtr); } OSPData ospNewSharedData1DStride(const void *sharedData, OSPDataType type, uint64_t numItems, int64_t byteStride) { return ospNewSharedData(sharedData, type, numItems, byteStride, 1, 0, 1, 0); } OSPData ospNewSharedData2D(const void *sharedData, OSPDataType type, uint64_t numItems1, uint64_t numItems2) { return ospNewSharedData(sharedData, type, numItems1, 0, numItems2, 0, 1, 0); } OSPData ospNewSharedData2DStride(const void *sharedData, OSPDataType type, uint64_t numItems1, int64_t byteStride1, uint64_t numItems2, int64_t byteStride2) { return ospNewSharedData( sharedData, type, numItems1, byteStride1, numItems2, byteStride2, 1, 0); } OSPData ospNewSharedData3D(const void *sharedData, OSPDataType type, uint64_t numItems1, uint64_t numItems2, uint64_t numItems3) { return ospNewSharedData( sharedData, type, numItems1, 0, numItems2, 0, numItems3, 0); } OSPData ospNewData1D(OSPDataType type, uint64_t numItems) { return ospNewData(type, numItems, 1, 1); } OSPData ospNewData2D(OSPDataType type, uint64_t numItems1, uint64_t numItems2) { return ospNewData(type, numItems1, numItems2, 1); } void ospCopyData1D( const OSPData source, OSPData destination, uint64_t destinationIndex) { ospCopyData(source, destination, destinationIndex, 0, 0); } void ospCopyData2D(const OSPData source, OSPData destination, uint64_t destinationIndex1, uint64_t destinationIndex2) { ospCopyData(source, destination, destinationIndex1, destinationIndex2, 0); } // Parameter helpers //////////////////////////////////////////////////////// void ospSetString(OSPObject o, const char *id, const char *s) { ospSetParam(o, id, OSP_STRING, &s); } void ospSetObject(OSPObject o, const char *id, OSPObject other) { ospSetParam(o, id, OSP_OBJECT, &other); } void ospSetBool(OSPObject o, const char *id, int x) { ospSetParam(o, id, OSP_BOOL, &x); } void ospSetFloat(OSPObject o, const char *id, float x) { ospSetParam(o, id, OSP_FLOAT, &x); } void ospSetInt(OSPObject o, const char *id, int x) { ospSetParam(o, id, OSP_INT, &x); } void ospSetUInt(OSPObject o, const char *id, unsigned int x) { ospSetParam(o, id, OSP_UINT, &x); } void ospSetBox1f(OSPObject o, const char *id, float x, float y) { float v[] = {x, y}; ospSetParam(o, id, OSP_BOX1F, v); } void ospSetLinear2f( OSPObject o, const char *id, float x, float y, float z, float w) { float v[] = {x, y, z, w}; ospSetParam(o, id, OSP_LINEAR2F, v); } void ospSetVec2f(OSPObject o, const char *id, float x, float y) { float v[] = {x, y}; ospSetParam(o, id, OSP_VEC2F, v); } void ospSetVec3f(OSPObject o, const char *id, float x, float y, float z) { float v[] = {x, y, z}; ospSetParam(o, id, OSP_VEC3F, v); } void ospSetVec4f( OSPObject o, const char *id, float x, float y, float z, float w) { float v[] = {x, y, z, w}; ospSetParam(o, id, OSP_VEC4F, v); } void ospSetVec2i(OSPObject o, const char *id, int x, int y) { int v[] = {x, y}; ospSetParam(o, id, OSP_VEC2I, v); } void ospSetVec3i(OSPObject o, const char *id, int x, int y, int z) { int v[] = {x, y, z}; ospSetParam(o, id, OSP_VEC3I, v); } void ospSetVec4i(OSPObject o, const char *id, int x, int y, int z, int w) { int v[] = {x, y, z, w}; ospSetParam(o, id, OSP_VEC4I, v); } void ospSetObjectAsData( OSPObject o, const char *n, OSPDataType type, OSPObject p) { OSPData tmp = ospNewSharedData(&p, type, 1); OSPData data = ospNewData(type, 1); ospCopyData(tmp, data); ospSetParam(o, n, OSP_DATA, &data); ospRelease(tmp); ospRelease(data); } // Rendering helpers ////////////////////////////////////////////////////////// float ospRenderFrameBlocking( OSPFrameBuffer fb, OSPRenderer renderer, OSPCamera camera, OSPWorld world) { OSPFuture f = ospRenderFrame(fb, renderer, camera, world); ospWait(f, OSP_TASK_FINISHED); ospRelease(f); return ospGetVariance(fb); } } // extern "C" RenderKit-ospray-85af292/ospray/common/000077500000000000000000000000001464752671100201005ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/common/DeviceRT.h000066400000000000000000000401311464752671100217150ustar00rootroot00000000000000// Copyright 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "OSPCommon.h" // OSPRAY_CORE_INTERFACE #include // size_t #include #include // unique_ptr, shared_ptr #include // Forward declaractions for types used during kernel launching namespace ispc { struct Renderer; struct FrameBuffer; struct Camera; struct World; struct FrameBufferView; } // namespace ispc namespace ospray { struct FeatureFlags; namespace devicert { enum class Alloc { Host = 0, Device = 1, Shared = 2, Unknown = 3 }; // Renderer kernel type using RendererKernel = void (*)(void *, void *, const vec3ui &, void *, void *, void *, void *, const uint32_t *, const ospray::FeatureFlags &); #define DECLARE_RENDERER_KERNEL_LAUNCHER(kernel_name) \ namespace ispc { \ extern "C" { \ void kernel_name(void *, \ void *, \ const vec3ui &, \ void *, \ void *, \ void *, \ void *, \ const uint32_t *, \ const ospray::FeatureFlags &); \ } \ } // namespace ispc // FrameOp kernel type using FrameOpKernel = void (*)(void *, void *, const vec2ui &, const void *); #define DECLARE_FRAMEOP_KERNEL_LAUNCHER(kernel_name) \ namespace ispc { \ extern "C" { \ void kernel_name(void *, void *, const vec2ui &, const void *); \ } \ } // namespace ispc ///////////////////////////////////////////////////////////////////// // AsyncEvent interface // Async event interface for polymorphism struct DeviceImpl; struct OSPRAY_CORE_INTERFACE AsyncEventIfc { // Virtual destruction for polymorphism virtual ~AsyncEventIfc() = default; // Same interface as AsyncEvent virtual void wait() const = 0; virtual bool finished() const = 0; virtual float getDuration() const = 0; virtual void *getSyclEventPtr() = 0; // DeviceImpl class acts on this class friend struct DeviceImpl; }; // Copyable async event class struct OSPRAY_CORE_INTERFACE AsyncEvent { // Construction & destruction AsyncEvent() = default; AsyncEvent(std::shared_ptr ifc); // Wait for the event to complete void wait() const; // Return true if event finished bool finished() const; // Get event execution time float getDuration() const; // For code (e.g. OIDN) that is able to use SYCL without including it void *getSyclEventPtr(); private: std::shared_ptr ifc; }; inline AsyncEvent::AsyncEvent(std::shared_ptr ifc) : ifc(ifc) {} inline void AsyncEvent::wait() const { if (ifc) ifc->wait(); } inline bool AsyncEvent::finished() const { return ifc ? ifc->finished() : true; } inline float AsyncEvent::getDuration() const { return ifc ? ifc->getDuration() : 0.f; } inline void *AsyncEvent::getSyclEventPtr() { return ifc ? ifc->getSyclEventPtr() : nullptr; } ///////////////////////////////////////////////////////////////////// // Device interface // The class representing a compute device like CPU or GPU struct OSPRAY_CORE_INTERFACE Device { // Construction & polymorphic destruction Device(bool debug) : debug(debug) {} virtual ~Device() = default; // Allocate device local memory virtual void *deviceMalloc(std::size_t size) = 0; // Allocate device shared memory virtual void *sharedMalloc(std::size_t size) = 0; // Allocate host memory virtual void *hostMalloc(std::size_t size) = 0; // Release memory allocated with any of the above malloc functions virtual void free(void *ptr) = 0; // Get memory allocation type for given pointer virtual Alloc getPointerType(void *ptr) const = 0; // Wait for device to finish its pending work virtual void wait() = 0; // Create asynchronous event object virtual AsyncEvent createAsyncEvent() = 0; // Copy memory from/to and within the device virtual AsyncEvent memcpy(void *dest, const void *src, std::size_t size) = 0; // Launch a kernel on a device virtual AsyncEvent launchRendererKernel(const vec3ui &itemDims, RendererKernel kernel, ispc::Renderer *renderer, ispc::FrameBuffer *fb, ispc::Camera *camera, ispc::World *world, const uint32_t *taskIDs, const FeatureFlags &ff) = 0; virtual AsyncEvent launchFrameOpKernel(const vec2ui &itemDims, FrameOpKernel kernel, const ispc::FrameBufferView *fbv) = 0; // Launch a given task on a host using device queue ordering virtual AsyncEvent launchHostTask(const std::function &task) = 0; // For code (e.g. OIDN) that is able to use SYCL without including it virtual void *getSyclDevicePtr() = 0; virtual void *getSyclContextPtr() = 0; virtual void *getSyclQueuePtr() = 0; // Check if device is in debug mode bool isDebug() const; private: bool debug; }; inline bool Device::isDebug() const { return debug; } ///////////////////////////////////////////////////////////////////// // Device allocator template struct DeviceAllocator { using value_type = T; // Construction DeviceAllocator(Device &device, Alloc alloc) : device(device), alloc(alloc) {} template DeviceAllocator(const DeviceAllocator &other) : device(other.device), alloc(other.alloc) {} // Memory allocation and release T *allocate(std::size_t n, const void *hint = 0); void deallocate(T *p, std::size_t n); // Check if it is the same allocator bool operator==(const DeviceAllocator &other) const; bool operator!=(const DeviceAllocator &other) const; // Get device used for allocation Device &getDevice() const; private: Device &device; Alloc alloc; // Provide access to private data for the templated copy constructor template friend class DeviceAllocator; }; template T *DeviceAllocator::allocate(std::size_t n, const void *) { return static_cast((alloc == Alloc::Shared) ? device.sharedMalloc(n * sizeof(T)) : device.hostMalloc(n * sizeof(T))); } template void DeviceAllocator::deallocate(T *p, std::size_t) { device.free(p); } template bool DeviceAllocator::operator==(const DeviceAllocator &other) const { return &device == &other.device; } template bool DeviceAllocator::operator!=(const DeviceAllocator &other) const { return &device != &other.device; } template inline Device &DeviceAllocator::getDevice() const { return device; } ///////////////////////////////////////////////////////////////////// // Buffer in the device memory // Use it for data that needs the highest read/write performance on the device. // The buffer supports initialization from system (non-USM) memory. Preferably // should be used for all scene data that does not need to be updated from or // transferred back to the host. template struct BufferDevice { // Construct an uninitialized buffer in device memory BufferDevice(Device &device, std::size_t count); // Construct a buffer in device memory and initialize it with given vector BufferDevice(Device &device, const std::vector &v); // Construct a buffer in device memory and initialize it with raw memory BufferDevice(Device &device, T *data, std::size_t count); // Release device memory ~BufferDevice(); // Get device that was used for allocation Device &getDevice() const; // Get number of container elements size_t size() const; // Get device memory pointer T *devicePtr(); const T *devicePtr() const; private: Device &device; const size_t count; T *const ptr; }; template BufferDevice::BufferDevice(Device &device, std::size_t count) : device(device), count(count), ptr(static_cast(device.deviceMalloc(count * sizeof(T)))) {} template BufferDevice::BufferDevice(Device &device, const std::vector &v) : device(device), count(v.size()), ptr(static_cast(device.deviceMalloc(v.size() * sizeof(T)))) { // Schedule buffer copying and wait till completed so the input resource can // be released immediately AsyncEvent event = device.memcpy(ptr, v.data(), v.size() * sizeof(T)); event.wait(); } template BufferDevice::BufferDevice(Device &device, T *data, std::size_t count) : device(device), count(count), ptr(static_cast(device.deviceMalloc(count * sizeof(T)))) { // Schedule buffer copying and wait till completed so the input resource can // be released immediately AsyncEvent event = device.memcpy(ptr, data, count * sizeof(T)); event.wait(); } template BufferDevice::~BufferDevice() { device.free(ptr); } template inline Device &BufferDevice::getDevice() const { return device; } template inline size_t BufferDevice::size() const { return count; } template inline T *BufferDevice::devicePtr() { return ptr; } template inline const T *BufferDevice::devicePtr() const { return ptr; } template inline std::unique_ptr> make_buffer_device_unique( Args &&...args) { return std::unique_ptr>( new BufferDevice(std::forward(args)...)); } ///////////////////////////////////////////////////////////////////// // Buffer in the device memory with host memory shadow // For usages that need the highest read/write efficiency on the device, similar // to `BufferDevice`, but additionally the data has to be transferred from/to // host periodically, e.g. framebuffers. After construction and initialization // of the host/shadow buffer, an explicit call to copyToDevice() is required so // the data will be visible for the device. Beware, it may use pinned (not // pageable) memory on the host so it is not suitable for huge buffers. template struct BufferDeviceShadowed : public std::vector> { // Polymorfic destruction virtual ~BufferDeviceShadowed() = default; // Get the device that was used for allocation Device &getDevice() const; // Copy the host (shadow) buffer to the device AsyncEvent copyToDevice(); // Copy the device buffer to the host AsyncEvent copyToHost(); // Get host memory pointer T *hostPtr(); const T *hostPtr() const; // Get device memory pointer T *devicePtr(); const T *devicePtr() const; protected: // To be called by an implementation class BufferDeviceShadowed(Device &device, T *ptr, std::size_t count); BufferDeviceShadowed(Device &device, T *ptr, const std::vector &v); BufferDeviceShadowed(Device &device, T *ptr, T *data, std::size_t count); // Copy between device and shadow buffers virtual AsyncEvent memcpy(T *dest, const T *src, std::size_t count) = 0; // Common members for all implementations Device &device; T *const devPtr; }; template BufferDeviceShadowed::BufferDeviceShadowed( Device &device, T *ptr, std::size_t count) : std::vector>( DeviceAllocator(device, Alloc::Host)), device(device), devPtr(ptr) { std::vector>::resize( count); // TODO: since C++14 use vector(count, allocator) constructor } template BufferDeviceShadowed::BufferDeviceShadowed( Device &device, T *ptr, const std::vector &v) : std::vector>( v.begin(), v.end(), DeviceAllocator(device, Alloc::Host)), device(device), devPtr(ptr) {} template BufferDeviceShadowed::BufferDeviceShadowed( Device &device, T *ptr, T *data, std::size_t count) : std::vector>( data, data + count, DeviceAllocator(device, Alloc::Host)), device(device), devPtr(ptr) {} template Device &BufferDeviceShadowed::getDevice() const { return device; } template AsyncEvent BufferDeviceShadowed::copyToDevice() { return memcpy(devPtr, std::vector>::data(), std::vector>::size()); } template AsyncEvent BufferDeviceShadowed::copyToHost() { return memcpy(std::vector>::data(), devPtr, std::vector>::size()); } template inline T *BufferDeviceShadowed::hostPtr() { return std::vector>::data(); } template inline const T *BufferDeviceShadowed::hostPtr() const { return std::vector>::data(); } template inline T *BufferDeviceShadowed::devicePtr() { return devPtr ? devPtr : std::vector>::data(); } template inline const T *BufferDeviceShadowed::devicePtr() const { return devPtr ? devPtr : std::vector>::data(); } ///////////////////////////////////////////////////////////////////// // Buffer in the device shared memory // For all other usages where simplicity of use is more important than // performance. template struct BufferShared : public std::vector> { // Construct an uninitialized buffer in device shared memory BufferShared(Device &device, std::size_t count); // Construct a buffer in device shared memory and initialize it with given // vector BufferShared(Device &device, const std::vector &v); // Construct a buffer in device shared memory and initialize it with raw // memory BufferShared(Device &device, const T *data, std::size_t count); // Get device that was used for allocation Device &getDevice() const; // Get shared memory pointer T *sharedPtr(); const T *sharedPtr() const; }; template BufferShared::BufferShared(Device &device, std::size_t count) : std::vector>( DeviceAllocator(device, Alloc::Shared)) { std::vector>::resize( count); // TODO: since C++14 use vector(count, allocator) constructor } template BufferShared::BufferShared(Device &device, const std::vector &v) : std::vector>( v.begin(), v.end(), DeviceAllocator(device, Alloc::Shared)) {} template BufferShared::BufferShared(Device &device, const T *data, std::size_t count) : std::vector>( data, data + count, DeviceAllocator(device, Alloc::Shared)) {} template inline Device &BufferShared::getDevice() const { return std::vector>::get_allocator().getDevice(); } template inline T *BufferShared::sharedPtr() { return std::vector>::data(); } template inline const T *BufferShared::sharedPtr() const { return std::vector>::data(); } template inline std::unique_ptr> make_buffer_shared_unique( Args &&...args) { return std::unique_ptr>( new BufferShared(std::forward(args)...)); } } // namespace devicert // Convenience type aliases template using BufferDeviceUq = std::unique_ptr>; template using BufferDeviceShadowedUq = std::unique_ptr>; template using BufferSharedUq = std::unique_ptr>; } // namespace ospray RenderKit-ospray-85af292/ospray/common/ISPCMessages.h000066400000000000000000000015471464752671100225060ustar00rootroot00000000000000// Copyright 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ospray/OSPEnums.h" #ifndef ISPC #include #include namespace ospray { #endif typedef enum #if __cplusplus >= 201103L : uint32_t #endif { ISPC_MSG_SPHERES, ISPC_MSG_SHADING_CONTEXT, ISPC_MSG_MAX } ISPCMsgId; #ifdef ISPC extern "C" void postStatusMsg(uniform ISPCMsgId msgId, uniform OSPLogLevel postAtLogLevel = OSP_LOG_DEBUG); #else static std::array ispcMessages = { /* ISPC_MSG_SPHERES */ "#osp:Spheres_getAreas: Non-uniform scaling in instance " "transformation detected! Importance sampling for emissive " "materials and thus resulting image may be wrong.\n", /* ISPC_MSG_SHADING_CONTEXT */ "#osp:PT: out of memory for ShadingContext allocation!\n"}; } // namespace ospray #endif RenderKit-ospray-85af292/ospray/common/Library.h000066400000000000000000000003371464752671100216600ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/os/library.h" namespace ospray { using rkcommon::getSymbol; using rkcommon::loadLibrary; } // namespace ospray RenderKit-ospray-85af292/ospray/common/Managed.cpp000066400000000000000000000020521464752671100221370ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Managed.h" namespace ospray { ManagedObject::~ManagedObject() { try { std::for_each(params_begin(), params_end(), [&](std::shared_ptr &p) { auto ¶m = *p; if (param.data.valid() && param.data.is()) { auto *obj = param.data.get(); if (obj != nullptr) obj->refDec(); } }); } catch (const std::exception &e) { ospray::handleError(OSP_UNKNOWN_ERROR, e.what()); } } void ManagedObject::commit() {} std::string ManagedObject::toString() const { return "ospray::ManagedObject"; } void ManagedObject::checkUnused() { for (auto p = params_begin(); p != params_end(); ++p) { if (!(*p)->query) { postStatusMsg(OSP_LOG_WARNING) << toString() << ": found unused (or of wrong data type) parameter '" << (*p)->name << "'"; } } } box3f ManagedObject::getBounds() const { return box3f(empty); } OSPTYPEFOR_DEFINITION(ManagedObject *); } // namespace ospray RenderKit-ospray-85af292/ospray/common/Managed.h000066400000000000000000000071611464752671100216120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "rkcommon/utility/Any.h" #include "rkcommon/utility/Optional.h" #include "rkcommon/utility/ParameterizedObject.h" // ospray #include "./OSPCommon.h" // stl #include #include namespace ospray { struct Data; template struct DataT; struct OSPRAY_CORE_INTERFACE ManagedObject : public memory::RefCount, public utility::ParameterizedObject { using OSP_PTR = ManagedObject *; ManagedObject() = default; virtual ~ManagedObject() override; virtual void commit(); virtual std::string toString() const; template T getParam(const char *name, T valIfNotFound = T()); template T *getParamObject(const char *name, T *valIfNotFound = nullptr); template inline utility::Optional getOptParam(const char *name); void checkUnused(); virtual box3f getBounds() const; // Data members // OSPDataType managedObjectType{OSP_OBJECT}; private: template inline bool checkObjType(T, OSPDataType); }; OSPTYPEFOR_SPECIALIZATION(ManagedObject *, OSP_OBJECT); // Inlined ManagedObject definitions //////////////////////////////////////// template inline T ManagedObject::getParam(const char *name, T valIfNotFound) { static_assert(!std::is_convertible::value, "Use getParamObject<> for Obj parameters"); return ParameterizedObject::getParam(name, valIfNotFound); } template inline T *ManagedObject::getParamObject(const char *name, T *valIfNotFound) { static_assert(std::is_convertible::value, "Can only get objects derived from ManagedObject"); Param *const p = findParam(name); if (!p) return valIfNotFound; const bool prevQ = p->query; // objects are always set as ManagedObject*, retrieve as such auto *obj = ParameterizedObject::getParam( name, (ManagedObject *)valIfNotFound); if (obj && obj->managedObjectType == OSPTypeFor::value) return (T *)obj; // last resort, e.g. for Texture2D if (dynamic_cast(obj)) return (T *)obj; // reset query status if object is of incorrect type p->query = prevQ; return valIfNotFound; } template inline bool ManagedObject::checkObjType(T, OSPDataType) { return true; }; template <> inline bool ManagedObject::checkObjType(ManagedObject *o, OSPDataType t) { return o->managedObjectType == t; }; template inline utility::Optional ManagedObject::getOptParam(const char *name) { utility::Optional retval; Param *param = findParam(name); // objects are always set as ManagedObject*, retrieve as such using S = typename std::conditional::value, ManagedObject *, T>::type; if (param && param->data.is()) { const auto &val = param->data.get(); if (checkObjType(val, OSPTypeFor::value)) { retval = (T)val; param->query = true; } } return retval; } } // namespace ospray // Specializations for ISPCDevice ///////////////////////////////////////////// namespace rkcommon { namespace utility { template <> inline void ParameterizedObject::Param::set( const ospray::ManagedObject::OSP_PTR &object) { using OSP_PTR = ospray::ManagedObject::OSP_PTR; if (object) object->refInc(); if (data.is()) { auto *existingObj = data.get(); if (existingObj != nullptr) existingObj->refDec(); } data = object; } } // namespace utility } // namespace rkcommon RenderKit-ospray-85af292/ospray/common/OSPCommon.cpp000066400000000000000000000572731464752671100224340ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // must be first #define OSPRAY_RKCOMMON_DEFINITIONS #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ISPCMessages.h" #include "OSPCommon.h" #include "api/Device.h" #include "rkcommon/containers/AlignedVector.h" #include "rkcommon/utility/StringManip.h" #include #include namespace ospray { /*! 64-bit malloc. allows for alloc'ing memory larger than 4GB */ extern "C" void *malloc64(size_t size) { return alignedMalloc(size); } /*! 64-bit malloc. allows for alloc'ing memory larger than 4GB */ extern "C" void free64(void *ptr) { alignedFree(ptr); } namespace { using TLSPool = containers::AlignedVector; thread_local std::vector tlsStack; thread_local size_t topIndex = 0; // TLS stack top index } // namespace extern "C" void *pushTLS(size_t size) { // Grow stack topIndex++; if (topIndex > tlsStack.size()) tlsStack.resize(topIndex); // Grow pool TLSPool &tp = tlsStack[topIndex - 1]; tp.resize(size); return tp.data(); } extern "C" void *reallocTLS(void *ptr, size_t size) { // Silence 'unused variable' warning (void)ptr; // Grow pool TLSPool &tp = tlsStack[topIndex - 1]; assert(ptr == tp.data()); tp.resize(size); return tp.data(); } extern "C" void popTLS(void *ptr) { // Silence 'unused variable' warning (void)ptr; // Lower stack pointer assert(topIndex > 0); assert(ptr == tlsStack[topIndex - 1].data()); topIndex--; } WarnOnce::WarnOnce(const std::string &s, uint32_t postAtLogLevel) : s(s) { postStatusMsg(postAtLogLevel) << "Warning: " << s << " (only reporting first occurrence)"; } std::string getArgString(const std::string &s) { std::vector tokens = rkcommon::utility::split(s, '='); if (tokens.size() < 2) { std::stringstream ss; ss << "Invalid format for command-line argument " << s << ". Should be formatted --osp:="; postStatusMsg(ss, OSP_LOG_WARNING); return ""; } else { return tokens.back(); } } int getArgInt(const std::string &s) { std::string value = getArgString(s); try { return std::stoi(value); } catch (...) { // std::invalid_argument or std::out_of_range std::stringstream ss; ss << "Invalid value '" << value << "' in command-line argument " << s << ". Should be an integer"; postStatusMsg(ss, OSP_LOG_WARNING); return 0; } } void initFromCommandLine(int *_ac, const char ***_av) { using namespace rkcommon::utility; auto &device = ospray::api::Device::current; if (_ac && _av) { int &ac = *_ac; auto &av = *_av; // If we have any device-params those must be set first to avoid // initializing the device in an invalid or partial state bool hadDeviceParams = false; for (int i = 1; i < ac;) { if (std::strncmp(av[i], "--osp:device-params", 19) == 0) { hadDeviceParams = true; std::string parmesan = getArgString(av[i]); std::vector parmList = split(parmesan, ','); for (std::string &p : parmList) { std::vector kv = split(p, ':'); if (kv.size() != 2) { postStatusMsg( "Invalid parameters provided for --osp:device-params. " "Must be formatted as :[,:,...]"); } else { device->setParam(kv[0], kv[1]); } } removeArgs(ac, av, i, 1); } else { ++i; } } if (hadDeviceParams) { device->commit(); } for (int i = 1; i < ac;) { std::string param = av[i]; // flag-style arguments if (param == "--osp:debug") { device->setParam("debug", true); device->setParam("logOutput", std::string("cout")); device->setParam("errorOutput", std::string("cerr")); removeArgs(ac, av, i, 1); } else if (param == "--osp:warn-as-error") { device->setParam("warnAsError", true); removeArgs(ac, av, i, 1); } else if (param == "--osp:verbose") { device->setParam("logLevel", OSP_LOG_INFO); device->setParam("logOutput", std::string("cout")); device->setParam("errorOutput", std::string("cerr")); removeArgs(ac, av, i, 1); } else if (param == "--osp:vv") { device->setParam("logLevel", OSP_LOG_DEBUG); device->setParam("logOutput", std::string("cout")); device->setParam("errorOutput", std::string("cerr")); removeArgs(ac, av, i, 1); } // arguments taking required values else if (beginsWith(param, "--osp:log-level")) { std::string str = getArgString(param); auto level = api::Device::logLevelFromString(str); device->setParam("logLevel", level.value_or(0)); removeArgs(ac, av, i, 1); } else if (beginsWith(param, "--osp:log-output")) { std::string dst = getArgString(param); if (dst == "cout" || dst == "cerr") { device->setParam("logOutput", dst); } else { std::stringstream ss; ss << "Invalid output '" << dst << "' provided for --osp:log-output. Must be 'cerr' or 'cout'"; postStatusMsg(ss); } removeArgs(ac, av, i, 1); } else if (beginsWith(param, "--osp:error-output")) { std::string dst = getArgString(param); if (dst == "cout" || dst == "cerr") { device->setParam("errorOutput", dst); } else { std::stringstream ss; ss << "Invalid output '" << dst << "' provided for --osp:error-output. Must be 'cerr' or 'cout'"; postStatusMsg(ss); } removeArgs(ac, av, i, 1); } else if (beginsWith(param, "--osp:num-threads")) { int nt = std::max(1, getArgInt(param)); device->setParam("numThreads", nt); removeArgs(ac, av, i, 1); } else if (beginsWith(param, "--osp:set-affinity")) { int val = getArgInt(param); if (val == 0 || val == 1) { device->setParam("setAffinity", val); } else { postStatusMsg( "Invalid value provided for --osp:set-affinity. " "Must be 0 or 1"); } removeArgs(ac, av, i, 1); } else { // silently ignore other arguments i++; } // ALOK: apply changes so that error messages and warnings during // initialization might appear for the user. Without this, any errors in // parsing will never be shown, even if the user sets the log output // stream, log level, etc. They still may not be shown if the output is // not set, however device->commit(); } } } size_t sizeOf(OSPDataType type) { switch (type) { case OSP_VOID_PTR: case OSP_OBJECT: case OSP_CAMERA: case OSP_DATA: case OSP_DEVICE: case OSP_FRAMEBUFFER: case OSP_FUTURE: case OSP_GEOMETRIC_MODEL: case OSP_GEOMETRY: case OSP_GROUP: case OSP_IMAGE_OPERATION: case OSP_INSTANCE: case OSP_LIGHT: case OSP_MATERIAL: case OSP_RENDERER: case OSP_TEXTURE: case OSP_TRANSFER_FUNCTION: case OSP_VOLUME: case OSP_VOLUMETRIC_MODEL: case OSP_WORLD: case OSP_STRING: return sizeof(void *); case OSP_BOOL: return sizeof(bool); case OSP_CHAR: return sizeof(int8); case OSP_UCHAR: return sizeof(uint8); case OSP_VEC2UC: return sizeof(vec2uc); case OSP_VEC3UC: return sizeof(vec3uc); case OSP_VEC4UC: return sizeof(vec4uc); case OSP_VEC2C: return sizeof(vec2c); case OSP_VEC3C: return sizeof(vec3c); case OSP_VEC4C: return sizeof(vec4c); case OSP_SHORT: return sizeof(int16); case OSP_VEC2S: return sizeof(vec2s); case OSP_VEC3S: return sizeof(vec3s); case OSP_VEC4S: return sizeof(vec4s); case OSP_USHORT: return sizeof(uint16); case OSP_VEC2US: return sizeof(vec2us); case OSP_VEC3US: return sizeof(vec3us); case OSP_VEC4US: return sizeof(vec4us); case OSP_INT: return sizeof(int32); case OSP_VEC2I: return sizeof(vec2i); case OSP_VEC3I: return sizeof(vec3i); case OSP_VEC4I: return sizeof(vec4i); case OSP_UINT: return sizeof(uint32); case OSP_VEC2UI: return sizeof(vec2ui); case OSP_VEC3UI: return sizeof(vec3ui); case OSP_VEC4UI: return sizeof(vec4ui); case OSP_LONG: return sizeof(int64); case OSP_VEC2L: return sizeof(vec2l); case OSP_VEC3L: return sizeof(vec3l); case OSP_VEC4L: return sizeof(vec4l); case OSP_ULONG: return sizeof(uint64); case OSP_VEC2UL: return sizeof(vec2ul); case OSP_VEC3UL: return sizeof(vec3ul); case OSP_VEC4UL: return sizeof(vec4ul); case OSP_HALF: return sizeof(uint16); case OSP_VEC2H: return sizeof(vec2us); case OSP_VEC3H: return sizeof(vec3us); case OSP_VEC4H: return sizeof(vec4us); case OSP_FLOAT: return sizeof(float); case OSP_VEC2F: return sizeof(vec2f); case OSP_VEC3F: return sizeof(vec3f); case OSP_VEC4F: return sizeof(vec4f); case OSP_DOUBLE: return sizeof(double); case OSP_VEC2D: return sizeof(vec2d); case OSP_VEC3D: return sizeof(vec3d); case OSP_VEC4D: return sizeof(vec4d); case OSP_BOX1I: return sizeof(box1i); case OSP_BOX2I: return sizeof(box2i); case OSP_BOX3I: return sizeof(box3i); case OSP_BOX4I: return sizeof(box4i); case OSP_BOX1F: return sizeof(box1f); case OSP_BOX2F: return sizeof(box2f); case OSP_BOX3F: return sizeof(box3f); case OSP_BOX4F: return sizeof(box4f); case OSP_LINEAR2F: return sizeof(linear2f); case OSP_LINEAR3F: return sizeof(linear3f); case OSP_AFFINE2F: return sizeof(affine2f); case OSP_AFFINE3F: return sizeof(affine3f); case OSP_QUATF: return sizeof(quatf); case OSP_UNKNOWN: return 0; } std::stringstream error; error << __FILE__ << ":" << __LINE__ << ": unknown OSPDataType " << (int)type; throw std::runtime_error(error.str()); } OSPDataType typeOf(const char *string) { if (string == nullptr) return (OSP_UNKNOWN); if (strcmp(string, "bool") == 0) return (OSP_BOOL); if (strcmp(string, "char") == 0) return (OSP_CHAR); if (strcmp(string, "half") == 0) return (OSP_HALF); if (strcmp(string, "float") == 0) return (OSP_FLOAT); if (strcmp(string, "double") == 0) return (OSP_DOUBLE); if (strcmp(string, "vec2h") == 0) return (OSP_VEC2H); if (strcmp(string, "vec3h") == 0) return (OSP_VEC3H); if (strcmp(string, "vec4h") == 0) return (OSP_VEC4H); if (strcmp(string, "vec2f") == 0) return (OSP_VEC2F); if (strcmp(string, "vec3f") == 0) return (OSP_VEC3F); if (strcmp(string, "vec4f") == 0) return (OSP_VEC4F); if (strcmp(string, "vec2d") == 0) return (OSP_VEC2D); if (strcmp(string, "vec3d") == 0) return (OSP_VEC3D); if (strcmp(string, "vec4d") == 0) return (OSP_VEC4D); if (strcmp(string, "int") == 0) return (OSP_INT); if (strcmp(string, "vec2i") == 0) return (OSP_VEC2I); if (strcmp(string, "vec3i") == 0) return (OSP_VEC3I); if (strcmp(string, "vec4i") == 0) return (OSP_VEC4I); if (strcmp(string, "uchar") == 0) return (OSP_UCHAR); if (strcmp(string, "vec2uc") == 0) return (OSP_VEC2UC); if (strcmp(string, "vec3uc") == 0) return (OSP_VEC3UC); if (strcmp(string, "vec4uc") == 0) return (OSP_VEC4UC); if (strcmp(string, "vec2c") == 0) return (OSP_VEC2C); if (strcmp(string, "vec3c") == 0) return (OSP_VEC3C); if (strcmp(string, "vec4c") == 0) return (OSP_VEC4C); if (strcmp(string, "short") == 0) return (OSP_SHORT); if (strcmp(string, "vec2s") == 0) return (OSP_VEC2S); if (strcmp(string, "vec3s") == 0) return (OSP_VEC3S); if (strcmp(string, "vec4s") == 0) return (OSP_VEC4S); if (strcmp(string, "ushort") == 0) return (OSP_USHORT); if (strcmp(string, "vec2us") == 0) return (OSP_VEC2US); if (strcmp(string, "vec3us") == 0) return (OSP_VEC3US); if (strcmp(string, "vec4us") == 0) return (OSP_VEC4US); if (strcmp(string, "uint") == 0) return (OSP_UINT); if (strcmp(string, "uint2") == 0) return (OSP_VEC2UI); if (strcmp(string, "uint3") == 0) return (OSP_VEC3UI); if (strcmp(string, "uint4") == 0) return (OSP_VEC4UI); return (OSP_UNKNOWN); } std::string stringFor(OSPDataType type) { switch (type) { case OSP_VOID_PTR: return "void_ptr"; case OSP_OBJECT: return "object"; case OSP_CAMERA: return "camera"; case OSP_DATA: return "data"; case OSP_DEVICE: return "device"; case OSP_FRAMEBUFFER: return "framebuffer"; case OSP_FUTURE: return "future"; case OSP_GEOMETRIC_MODEL: return "geometric_model"; case OSP_GEOMETRY: return "geometry"; case OSP_GROUP: return "group"; case OSP_IMAGE_OPERATION: return "image_operation"; case OSP_INSTANCE: return "instance"; case OSP_LIGHT: return "light"; case OSP_MATERIAL: return "material"; case OSP_RENDERER: return "renderer"; case OSP_TEXTURE: return "texture"; case OSP_TRANSFER_FUNCTION: return "transfer_function"; case OSP_VOLUME: return "volume"; case OSP_VOLUMETRIC_MODEL: return "volumetric_model"; case OSP_WORLD: return "world"; case OSP_STRING: return "string"; case OSP_BOOL: return "bool"; case OSP_CHAR: return "char"; case OSP_UCHAR: return "uchar"; case OSP_VEC2UC: return "vec2uc"; case OSP_VEC3UC: return "vec3uc"; case OSP_VEC4UC: return "vec4uc"; case OSP_VEC2C: return "vec2c"; case OSP_VEC3C: return "vec3c"; case OSP_VEC4C: return "vec4c"; case OSP_SHORT: return "short"; case OSP_VEC2S: return "vec2s"; case OSP_VEC3S: return "vec3s"; case OSP_VEC4S: return "vec4s"; case OSP_USHORT: return "ushort"; case OSP_VEC2US: return "vec2us"; case OSP_VEC3US: return "vec3us"; case OSP_VEC4US: return "vec4us"; case OSP_INT: return "int"; case OSP_VEC2I: return "vec2i"; case OSP_VEC3I: return "vec3i"; case OSP_VEC4I: return "vec4i"; case OSP_UINT: return "uint"; case OSP_VEC2UI: return "vec2ui"; case OSP_VEC3UI: return "vec3ui"; case OSP_VEC4UI: return "vec4ui"; case OSP_LONG: return "long"; case OSP_VEC2L: return "vec2l"; case OSP_VEC3L: return "vec3l"; case OSP_VEC4L: return "vec4l"; case OSP_ULONG: return "ulong"; case OSP_VEC2UL: return "vec2ul"; case OSP_VEC3UL: return "vec3ul"; case OSP_VEC4UL: return "vec4ul"; case OSP_HALF: return "half"; case OSP_VEC2H: return "vec2h"; case OSP_VEC3H: return "vec3h"; case OSP_VEC4H: return "vec4h"; case OSP_FLOAT: return "float"; case OSP_VEC2F: return "vec2f"; case OSP_VEC3F: return "vec3f"; case OSP_VEC4F: return "vec4f"; case OSP_VEC2D: return "vec2d"; case OSP_VEC3D: return "vec3d"; case OSP_VEC4D: return "vec4d"; case OSP_DOUBLE: return "double"; case OSP_BOX1I: return "box1i"; case OSP_BOX2I: return "box2i"; case OSP_BOX3I: return "box3i"; case OSP_BOX4I: return "box4i"; case OSP_BOX1F: return "box1f"; case OSP_BOX2F: return "box2f"; case OSP_BOX3F: return "box3f"; case OSP_BOX4F: return "box4f"; case OSP_LINEAR2F: return "linear2f"; case OSP_LINEAR3F: return "linear3f"; case OSP_AFFINE2F: return "affine2f"; case OSP_AFFINE3F: return "affine3f"; case OSP_QUATF: return "quatf"; case OSP_UNKNOWN: return "unknown"; } std::stringstream error; error << __FILE__ << ":" << __LINE__ << ": undefined OSPDataType " << (int)type; throw std::runtime_error(error.str()); } std::string stringFor(OSPTextureFormat format) { switch (format) { case OSP_TEXTURE_RGBA8: return "rgba8"; case OSP_TEXTURE_SRGBA: return "srgba"; case OSP_TEXTURE_RGBA32F: return "rgba32f"; case OSP_TEXTURE_RGB8: return "rgb8"; case OSP_TEXTURE_SRGB: return "srgb"; case OSP_TEXTURE_RGB32F: return "rgb32f"; case OSP_TEXTURE_R8: return "r8"; case OSP_TEXTURE_L8: return "l8"; case OSP_TEXTURE_RA8: return "ra8"; case OSP_TEXTURE_LA8: return "la8"; case OSP_TEXTURE_R32F: return "r32f"; case OSP_TEXTURE_RA32F: return "ra32f"; case OSP_TEXTURE_RGBA16: return "rgba16"; case OSP_TEXTURE_RGB16: return "rgb16"; case OSP_TEXTURE_RA16: return "ra16"; case OSP_TEXTURE_R16: return "r16"; case OSP_TEXTURE_RGBA16F: return "rgba16f"; case OSP_TEXTURE_RGB16F: return "rgb16f"; case OSP_TEXTURE_RA16F: return "ra16f"; case OSP_TEXTURE_R16F: return "r16f"; case OSP_TEXTURE_FORMAT_INVALID: return "invalid"; } std::stringstream error; error << __FILE__ << ":" << __LINE__ << ": undefined OSPTextureFormat " << (int)format; throw std::runtime_error(error.str()); } size_t sizeOf(OSPTextureFormat format) { switch (format) { case OSP_TEXTURE_RGBA8: case OSP_TEXTURE_SRGBA: return sizeof(uint32); case OSP_TEXTURE_RGBA32F: return sizeof(vec4f); case OSP_TEXTURE_RGB8: case OSP_TEXTURE_SRGB: return sizeof(vec3uc); case OSP_TEXTURE_RGB32F: return sizeof(vec3f); case OSP_TEXTURE_RA32F: return sizeof(vec2f); case OSP_TEXTURE_R8: case OSP_TEXTURE_L8: return sizeof(uint8); case OSP_TEXTURE_RA8: case OSP_TEXTURE_LA8: return sizeof(vec2uc); case OSP_TEXTURE_R32F: return sizeof(float); case OSP_TEXTURE_RGBA16: case OSP_TEXTURE_RGBA16F: return sizeof(vec4us); case OSP_TEXTURE_RGB16: case OSP_TEXTURE_RGB16F: return sizeof(vec3us); case OSP_TEXTURE_RA16: case OSP_TEXTURE_RA16F: return sizeof(vec2us); case OSP_TEXTURE_R16: case OSP_TEXTURE_R16F: return sizeof(uint16); case OSP_TEXTURE_FORMAT_INVALID: return 0; } std::stringstream error; error << __FILE__ << ":" << __LINE__ << ": unknown OSPTextureFormat " << (int)format; throw std::runtime_error(error.str()); } size_t sizeOf(OSPFrameBufferFormat format) { size_t bytes = 0; switch (format) { case OSP_FB_RGBA8: case OSP_FB_SRGBA: bytes = sizeof(uint32_t); break; case OSP_FB_RGBA32F: bytes = sizeof(vec4f); break; default: break; } return bytes; } uint32_t logLevel() { return ospray::api::Device::current->logLevel; } OSPError loadLocalModule(const std::string &name) { std::string libName = "ospray_module_" + name; try { loadLibrary(reinterpret_cast(&loadLocalModule), libName, {OSPRAY_VERSION_MAJOR, OSPRAY_VERSION_MINOR, OSPRAY_VERSION_PATCH}); } catch (const std::exception &e) { handleError(OSP_INVALID_OPERATION, e.what()); return OSP_INVALID_OPERATION; } catch (...) { return OSP_INVALID_OPERATION; } std::string initSymName = "ospray_module_init_" + name; void *initSym = getSymbol(initSymName); if (!initSym) { handleError(OSP_INVALID_OPERATION, "Could not find module initializer " + initSymName); unloadLibrary(libName); return OSP_INVALID_OPERATION; } auto initMethod = (OSPError(*)(int16_t, int16_t, int16_t))initSym; auto err = initMethod( OSPRAY_VERSION_MAJOR, OSPRAY_VERSION_MINOR, OSPRAY_VERSION_PATCH); if (err != OSP_NO_ERROR) { handleError(err, "Initialization of module " + name + " failed"); unloadLibrary(libName); } return err; } StatusMsgStream postStatusMsg(uint32_t postAtLogLevel) { return StatusMsgStream(postAtLogLevel); } extern "C" void postStatusMsg(uint32_t msgId, uint32_t postAtLogLevel) { assert(msgId < ISPC_MSG_MAX); postStatusMsg(ispcMessages[msgId], postAtLogLevel); } void postStatusMsg(const std::stringstream &msg, uint32_t postAtLogLevel) { postStatusMsg(msg.str(), postAtLogLevel); } void postStatusMsg(const std::string &msg, uint32_t postAtLogLevel) { if (!api::deviceIsSet()) return; auto level = logLevel(); if (level == OSP_LOG_NONE) return; auto &device = *api::Device::current; if (level <= postAtLogLevel) { bool logAsError = (device.warningsAreErrors && postAtLogLevel == OSP_LOG_WARNING) || postAtLogLevel == OSP_LOG_ERROR; if (logAsError) handleError(OSP_UNKNOWN_ERROR, msg + '\n'); else api::Device::current->msg_fcn( api::Device::current->statusUserData, (msg + '\n').c_str()); } } void handleError(OSPError e, const std::string &message) { if (api::deviceIsSet()) { auto &device = api::currentDevice(); device.lastErrorCode = e; device.lastErrorMsg = "#ospray: " + message; device.error_fcn(device.errorUserData, e, message.c_str()); } else { // NOTE: No device, but something should still get printed for the user to // debug the calling application. std::cerr << "#ospray: INVALID device --> " << message << std::endl; } } void postTraceMsg(const std::string &message) { if (api::deviceIsSet()) { auto &device = api::currentDevice(); device.trace_fcn(message.c_str()); } } size_t translatedHash(size_t v) { static std::map id_translation; auto itr = id_translation.find(v); if (itr == id_translation.end()) { static size_t newIndex = 0; id_translation[v] = newIndex; return newIndex++; } else { return id_translation[v]; } } OSPTYPEFOR_DEFINITION(void *); OSPTYPEFOR_DEFINITION(char *); OSPTYPEFOR_DEFINITION(const char *); OSPTYPEFOR_DEFINITION(const char[]); OSPTYPEFOR_DEFINITION(bool); OSPTYPEFOR_DEFINITION(char); OSPTYPEFOR_DEFINITION(unsigned char); OSPTYPEFOR_DEFINITION(short); OSPTYPEFOR_DEFINITION(unsigned short); OSPTYPEFOR_DEFINITION(int); OSPTYPEFOR_DEFINITION(unsigned int); OSPTYPEFOR_DEFINITION(long); OSPTYPEFOR_DEFINITION(unsigned long); OSPTYPEFOR_DEFINITION(long long); OSPTYPEFOR_DEFINITION(unsigned long long); OSPTYPEFOR_DEFINITION(float); OSPTYPEFOR_DEFINITION(double); OSPTYPEFOR_DEFINITION(OSPObject); OSPTYPEFOR_DEFINITION(OSPCamera); OSPTYPEFOR_DEFINITION(OSPData); OSPTYPEFOR_DEFINITION(OSPFrameBuffer); OSPTYPEFOR_DEFINITION(OSPFuture); OSPTYPEFOR_DEFINITION(OSPGeometricModel); OSPTYPEFOR_DEFINITION(OSPGeometry); OSPTYPEFOR_DEFINITION(OSPGroup); OSPTYPEFOR_DEFINITION(OSPImageOperation); OSPTYPEFOR_DEFINITION(OSPInstance); OSPTYPEFOR_DEFINITION(OSPLight); OSPTYPEFOR_DEFINITION(OSPMaterial); OSPTYPEFOR_DEFINITION(OSPRenderer); OSPTYPEFOR_DEFINITION(OSPTexture); OSPTYPEFOR_DEFINITION(OSPTransferFunction); OSPTYPEFOR_DEFINITION(OSPVolume); OSPTYPEFOR_DEFINITION(OSPVolumetricModel); OSPTYPEFOR_DEFINITION(OSPWorld); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2UC); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3UC); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4UC); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2C); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3C); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4C); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2I); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3I); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4I); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2UI); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3UI); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4UI); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2L); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3L); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4L); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2UL); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3UL); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4UL); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2H); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3H); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4H); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2F); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3F); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4F); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC2D); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC3D); OSPDIMENSIONALITYOF_DEFINITION(OSP_VEC4D); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX1I); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX2I); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX3I); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX4I); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX1F); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX2F); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX3F); OSPDIMENSIONALITYOF_DEFINITION(OSP_BOX4F); } // namespace ospray RenderKit-ospray-85af292/ospray/common/OSPCommon.h000066400000000000000000000164451464752671100220750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef _WIN32 // ----------- windows only ----------- typedef unsigned long long id_t; #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES #endif #include #include #ifdef _M_X64 typedef long long ssize_t; #else typedef int ssize_t; #endif #else // ----------- NOT windows ----------- #include "unistd.h" #endif #include "rkcommon/math/AffineSpace.h" #include "rkcommon/memory/RefCount.h" #include "rkcommon/memory/malloc.h" // ospray #include "ospray/ospray.h" #include "ospray/ospray_cpp/ext/rkcommon.h" #include "ospray/version.h" // std #include // for int64_t etc #include #include // NOTE(jda) - This one file is shared between the core OSPRay library and the // ispc module...thus we have to define 2 different EXPORTS macros // here. This needs to be split between the libraries! #ifdef _WIN32 #ifdef ospray_EXPORTS #define OSPRAY_INTERFACE __declspec(dllexport) #else #define OSPRAY_INTERFACE __declspec(dllimport) #endif #define OSPRAY_DLLEXPORT __declspec(dllexport) #else #define OSPRAY_INTERFACE #define OSPRAY_DLLEXPORT #endif #define OSPRAY_CORE_INTERFACE OSPRAY_INTERFACE #ifdef _WIN32 #if defined(ospray_module_cpu_EXPORTS) || defined(ospray_module_gpu_EXPORTS) #define OSPRAY_MODULE_ISPC_INTERFACE __declspec(dllexport) #else #define OSPRAY_MODULE_ISPC_INTERFACE __declspec(dllimport) #endif #define OSPRAY_MODULE_ISPC_DLLEXPORT __declspec(dllexport) #else #define OSPRAY_MODULE_ISPC_INTERFACE #define OSPRAY_MODULE_ISPC_DLLEXPORT #endif #define OSPRAY_SDK_INTERFACE OSPRAY_MODULE_ISPC_INTERFACE //! main namespace for all things ospray (for internal code) namespace ospray { using namespace rkcommon; using namespace rkcommon::math; using namespace rkcommon::memory; /*! basic types */ using int64 = std::int64_t; using uint64 = std::uint64_t; using int32 = std::int32_t; using uint32 = std::uint32_t; using int16 = std::int16_t; using uint16 = std::uint16_t; using int8 = std::int8_t; using uint8 = std::uint8_t; using index_t = std::int64_t; // Argument parsing functions std::string getArgString(const std::string &s); int getArgInt(const std::string &s); void initFromCommandLine(int *ac = nullptr, const char ***av = nullptr); extern "C" { /*! 64-bit malloc. allows for alloc'ing memory larger than 4GB */ OSPRAY_CORE_INTERFACE void *malloc64(size_t size); /*! 64-bit malloc. allows for alloc'ing memory larger than 4GB */ OSPRAY_CORE_INTERFACE void free64(void *ptr); /*! Thread Local Storage functions */ OSPRAY_CORE_INTERFACE void *pushTLS(size_t size); OSPRAY_CORE_INTERFACE void *reallocTLS(void *ptr, size_t size); OSPRAY_CORE_INTERFACE void popTLS(void *ptr); } OSPRAY_CORE_INTERFACE OSPDataType typeOf(const char *string); inline OSPDataType typeOf(const std::string &s) { return typeOf(s.c_str()); } OSPRAY_CORE_INTERFACE std::string stringFor(OSPDataType); OSPRAY_CORE_INTERFACE std::string stringFor(OSPTextureFormat); inline bool isObjectType(OSPDataType type) { return type & OSP_OBJECT; } OSPRAY_CORE_INTERFACE size_t sizeOf(OSPDataType); OSPRAY_CORE_INTERFACE size_t sizeOf(OSPTextureFormat); OSPRAY_CORE_INTERFACE size_t sizeOf(OSPFrameBufferFormat); OSPRAY_CORE_INTERFACE OSPError loadLocalModule(const std::string &name); inline OSPError moduleVersionCheck(int16_t versionMajor, int16_t versionMinor) { if ((OSPRAY_VERSION_MAJOR == versionMajor) && (OSPRAY_VERSION_MINOR == versionMinor)) { return OSP_NO_ERROR; } else return OSP_VERSION_MISMATCH; } /*! little helper class that prints out a warning string upon the first time it is encountered. Usage: if (someThisBadHappens) { static WarnOnce warning("something bad happened, at least once!"); ... } */ struct OSPRAY_CORE_INTERFACE WarnOnce { WarnOnce( const std::string &message, uint32_t postAtLogLevel = OSP_LOG_WARNING); private: const std::string s; }; OSPRAY_CORE_INTERFACE uint32_t logLevel(); extern "C" OSPRAY_CORE_INTERFACE void postStatusMsg( uint32_t msgId, uint32_t postAtLogLevel); OSPRAY_CORE_INTERFACE void postStatusMsg( const std::stringstream &msg, uint32_t postAtLogLevel = OSP_LOG_DEBUG); OSPRAY_CORE_INTERFACE void postStatusMsg( const std::string &msg, uint32_t postAtLogLevel = OSP_LOG_DEBUG); // use postStatusMsg to output any information, which will use OSPRay's // internal infrastructure, optionally at a given loglevel // a newline is added implicitly ////////////////////////////////////////////////////////////////////////////// struct StatusMsgStream : public std::stringstream { StatusMsgStream(uint32_t postAtLogLevel = OSP_LOG_DEBUG); StatusMsgStream(const StatusMsgStream ©) = delete; StatusMsgStream(StatusMsgStream &&move); StatusMsgStream &operator=(const StatusMsgStream ©) = delete; StatusMsgStream &operator=(StatusMsgStream &&move) = default; ~StatusMsgStream() override; private: uint32_t logLevel{OSP_LOG_DEBUG}; }; inline StatusMsgStream::StatusMsgStream(uint32_t postAtLogLevel) : logLevel(postAtLogLevel) {} inline StatusMsgStream::~StatusMsgStream() { auto msg = str(); if (!msg.empty()) postStatusMsg(msg, logLevel); } inline StatusMsgStream::StatusMsgStream(StatusMsgStream &&move) { this->str(move.str()); } OSPRAY_CORE_INTERFACE StatusMsgStream postStatusMsg( uint32_t postAtLogLevel = OSP_LOG_DEBUG); ///////////////////////////////////////////////////////////////////////////// OSPRAY_CORE_INTERFACE void handleError(OSPError e, const std::string &message); OSPRAY_CORE_INTERFACE void postTraceMsg(const std::string &message); //! log status message at loglevel x #define ospLog(x) StatusMsgStream(x) << "(" << x << "): " //! log status message at loglevel x with function name #define ospLogF(x) StatusMsgStream(x) << __FUNCTION__ << ": " //! log status message at loglevel x with function, file, and line number #define ospLogL(x) \ StatusMsgStream(x) << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \ << "): " // RTTI hash ID lookup helper functions /////////////////////////////////// OSPRAY_CORE_INTERFACE size_t translatedHash(size_t v); template inline size_t typeIdOf() { return translatedHash(typeid(T).hash_code()); } template inline size_t typeIdOf(T *v) { return translatedHash(typeid(*v).hash_code()); } template inline size_t typeIdOf(const T &v) { return translatedHash(typeid(v).hash_code()); } template inline size_t typeIdOf(const std::unique_ptr &v) { return translatedHash(typeid(*v).hash_code()); } template inline size_t typeIdOf(const std::shared_ptr &v) { return translatedHash(typeid(*v).hash_code()); } // RTTI string name lookup helper functions /////////////////////////////// template inline std::string typeString() { return typeid(T).name(); } template inline std::string typeString(T *v) { return typeid(*v).name(); } template inline std::string typeString(const T &v) { return typeid(v).name(); } template inline std::string typeString(const std::unique_ptr &v) { return typeid(*v).name(); } template inline std::string typeString(const std::shared_ptr &v) { return typeid(*v).name(); } } // namespace ospray RenderKit-ospray-85af292/ospray/common/ObjectFactory.h000066400000000000000000000035171464752671100230150ustar00rootroot00000000000000// Copyright 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "OSPCommon.h" #include #include #include #ifdef _WIN32 #ifdef OBJECTFACTORY_IMPORT #define OF_DECLSPEC __declspec(dllimport) #else #define OF_DECLSPEC __declspec(dllexport) #endif #else #define OF_DECLSPEC #endif // 'fcns' member is not defined when imported from other library #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundefined-var-template" namespace ospray { template struct OF_DECLSPEC ObjectFactory { // Register a new type to instantiate template static void registerType(const char *type) { fcns[type] = &allocate_object; } // Instantiate provided type class static T *createInstance(const char *type, Args &&...args) { // Find constructor pointer and call it FactoryFcn fcn = fcns[type]; if (fcn) { auto *obj = fcn(std::forward(args)...); if (obj != nullptr) return obj; } const auto type_string = stringFor(OSPTypeFor::value); throw std::runtime_error("Could not find '" + type_string + "' of type: '" + type + "'. Make sure you have the correct OSPRay libraries linked and initialized."); } private: using FactoryFcn = T *(*)(Args &&...args); using FactoryMap = std::map; // Map of constructor pointers, preferably use 'inline static' since C++17 static FactoryMap fcns; template static T *allocate_object(Args &&...args) { return new D(std::forward(args)...); } }; #ifndef OBJECTFACTORY_IMPORT template typename ObjectFactory::FactoryMap ObjectFactory::fcns; #endif } // namespace ospray #pragma clang diagnostic pop #undef OF_DECLSPEC RenderKit-ospray-85af292/ospray/fb/000077500000000000000000000000001464752671100171775ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/fb/FrameBufferView.h000066400000000000000000000002161464752671100223660ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once namespace ospray { #include "FrameBufferViewDef.h" }RenderKit-ospray-85af292/ospray/fb/FrameBufferViewDef.h000066400000000000000000000024571464752671100230160ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // No pragma once because this struct is defined twice, both in `ospray` and // `ispc` namespace // A view into a portion of the framebuffer to run the frame operation on // TODO: Change name struct FrameBufferView { vec2ui fbDims; // the total dimensions of the global framebuffer vec2ui viewDims; // the dimensions of this view of the framebuffer // Color buffer pointers being input/output to FrameOp const vec4f *colorBufferInput; vec4f *colorBufferOutput; // Other buffers that can used as well in FrameOp const float *depthBuffer; // one float per pixel, may be NULL const vec3f *normalBuffer; // accumulated world-space normal per pixel const vec3f *albedoBuffer; // accumulated albedo, one RGBF32 per pixel #ifdef __cplusplus FrameBufferView() = default; FrameBufferView(const vec2ui &dims, const vec4f *colorBufferInput, const float *depthBuffer = nullptr, const vec3f *normalBuffer = nullptr, const vec3f *albedoBuffer = nullptr) : fbDims(dims), viewDims(dims), colorBufferInput(colorBufferInput), colorBufferOutput(nullptr), depthBuffer(depthBuffer), normalBuffer(normalBuffer), albedoBuffer(albedoBuffer) {} #endif // __cplusplus }; RenderKit-ospray-85af292/ospray/fb/ImageOp.cpp000066400000000000000000000014101464752671100212200ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ImageOp.h" namespace ospray { // ImageOp definitions //////////////////////////////////////////////////////// ImageOp *ImageOp::createImageOp(const char *type, devicert::Device &device) { return createInstance(type, device); } ImageOp::ImageOp() { managedObjectType = OSP_IMAGE_OPERATION; } std::string ImageOp::toString() const { return "ospray::ImageOp(base class)"; } // explicitly create a key function to merge typeinfo from dynamically loaded // modules (to reliably dynamic_cast<> for the denoiser) // see https://github.com/android/ndk/issues/533#issuecomment-335977747 FrameOpInterface::~FrameOpInterface() {}; OSPTYPEFOR_DEFINITION(ImageOp *); } // namespace ospray RenderKit-ospray-85af292/ospray/fb/ImageOp.h000066400000000000000000000033441464752671100206750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "common/Managed.h" #include "common/ObjectFactory.h" #include namespace ospray { namespace devicert { struct AsyncEvent; struct Device; } // namespace devicert struct FrameBufferView; // An instance of an image op that is actually attached to a framebuffer struct OSPRAY_CORE_INTERFACE LiveImageOp { virtual ~LiveImageOp() = default; }; // Base abstraction for a "Image Op" to be performed for // every image that gets written into a frame buffer. // A ImageOp is basically a "hook" that allows to inject arbitrary // code, such as postprocessing, filtering, blending, tone mapping, // sending tiles to a display wall, etc. struct OSPRAY_CORE_INTERFACE ImageOp : public ManagedObject, public ObjectFactory { static ImageOp *createImageOp(const char *type, devicert::Device &device); ImageOp(); ~ImageOp() override = default; std::string toString() const override; }; OSPTYPEFOR_SPECIALIZATION(ImageOp *, OSP_IMAGE_OPERATION); struct Camera; struct OSPRAY_CORE_INTERFACE LiveFrameOpInterface : public LiveImageOp { ~LiveFrameOpInterface() override = default; // Execute FrameOp kernel virtual devicert::AsyncEvent process() = 0; }; struct OSPRAY_CORE_INTERFACE FrameOpInterface : public ImageOp { ~FrameOpInterface() override; // no =default! // Attach an image op to an existing framebuffer. Use this // to pass the params from the API to the instance of the image op // which will actually be run on the framebuffer view or tiles of the // framebuffer passed virtual std::unique_ptr attach( FrameBufferView &fbView) = 0; }; } // namespace ospray RenderKit-ospray-85af292/ospray/include/000077500000000000000000000000001464752671100202335ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/include/ospray/000077500000000000000000000000001464752671100215505ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/include/ospray/OSPEnums.h000066400000000000000000000223351464752671100233770ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // This header is shared with ISPC #pragma once // Log levels which can be set on a device via "logLevel" parameter typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_LOG_DEBUG = 1, OSP_LOG_INFO = 2, OSP_LOG_WARNING = 3, OSP_LOG_ERROR = 4, OSP_LOG_NONE = 5 } OSPLogLevel; typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_DEVICE_VERSION = 0, OSP_DEVICE_VERSION_MAJOR = 1, OSP_DEVICE_VERSION_MINOR = 2, OSP_DEVICE_VERSION_PATCH = 3, OSP_DEVICE_SO_VERSION = 4 } OSPDeviceProperty; // An enum type that represensts the different data types represented in OSPRay typedef enum #if __cplusplus >= 201103L : uint32_t #endif { // Object reference type. OSP_DEVICE = 100, // Void pointer type. OSP_VOID_PTR = 200, // Booleans, same size as OSP_INT. OSP_BOOL = 250, // highest bit to represent objects/handles OSP_OBJECT = 0x8000000, // object subtypes OSP_DATA = 0x8000000 + 100, OSP_CAMERA, OSP_FRAMEBUFFER, OSP_FUTURE, OSP_GEOMETRIC_MODEL, OSP_GEOMETRY, OSP_GROUP, OSP_IMAGE_OPERATION, OSP_INSTANCE, OSP_LIGHT, OSP_MATERIAL, OSP_RENDERER, OSP_TEXTURE, OSP_TRANSFER_FUNCTION, OSP_VOLUME, OSP_VOLUMETRIC_MODEL, OSP_WORLD, // Pointer to a C-style NULL-terminated character string. OSP_STRING = 1500, // Character scalar type. OSP_CHAR = 2000, OSP_VEC2C, OSP_VEC3C, OSP_VEC4C, // Unsigned character scalar and vector types. OSP_UCHAR = 2500, OSP_VEC2UC, OSP_VEC3UC, OSP_VEC4UC, OSP_BYTE = 2500, // XXX OSP_UCHAR, ISPC issue #1246 OSP_RAW = 2500, // XXX OSP_UCHAR, ISPC issue #1246 // Signed 16-bit integer scalar. OSP_SHORT = 3000, OSP_VEC2S, OSP_VEC3S, OSP_VEC4S, // Unsigned 16-bit integer scalar. OSP_USHORT = 3500, OSP_VEC2US, OSP_VEC3US, OSP_VEC4US, // Signed 32-bit integer scalar and vector types. OSP_INT = 4000, OSP_VEC2I, OSP_VEC3I, OSP_VEC4I, // Unsigned 32-bit integer scalar and vector types. OSP_UINT = 4500, OSP_VEC2UI, OSP_VEC3UI, OSP_VEC4UI, // Signed 64-bit integer scalar and vector types. OSP_LONG = 5000, OSP_VEC2L, OSP_VEC3L, OSP_VEC4L, // Unsigned 64-bit integer scalar and vector types. OSP_ULONG = 5550, OSP_VEC2UL, OSP_VEC3UL, OSP_VEC4UL, // Half precision floating point scalar and vector types (IEEE 754 // `binary16`). OSP_HALF = 5800, OSP_VEC2H, OSP_VEC3H, OSP_VEC4H, // Single precision floating point scalar and vector types. OSP_FLOAT = 6000, OSP_VEC2F, OSP_VEC3F, OSP_VEC4F, // Double precision floating point scalar type. OSP_DOUBLE = 7000, OSP_VEC2D, OSP_VEC3D, OSP_VEC4D, // Signed 32-bit integer N-dimensional box types OSP_BOX1I = 8000, OSP_BOX2I, OSP_BOX3I, OSP_BOX4I, // Single precision floating point N-dimensional box types OSP_BOX1F = 10000, OSP_BOX2F, OSP_BOX3F, OSP_BOX4F, // Transformation types OSP_LINEAR2F = 12000, OSP_LINEAR3F, OSP_AFFINE2F, OSP_AFFINE3F, OSP_QUATF, // Guard value. OSP_UNKNOWN = 9999999 } OSPDataType; // OSPRay format constants for Texture creation typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_TEXTURE_RGBA8, OSP_TEXTURE_SRGBA, OSP_TEXTURE_RGBA32F, OSP_TEXTURE_RGB8, OSP_TEXTURE_SRGB, OSP_TEXTURE_RGB32F, OSP_TEXTURE_R8, OSP_TEXTURE_R32F, OSP_TEXTURE_L8, OSP_TEXTURE_RA8, OSP_TEXTURE_LA8, OSP_TEXTURE_RGBA16, OSP_TEXTURE_RGB16, OSP_TEXTURE_RA16, OSP_TEXTURE_R16, OSP_TEXTURE_RA32F, OSP_TEXTURE_RGBA16F, OSP_TEXTURE_RGB16F, OSP_TEXTURE_RA16F, OSP_TEXTURE_R16F, // Denotes an unknown texture format, so we can properly initialize parameters OSP_TEXTURE_FORMAT_INVALID = 255, } OSPTextureFormat; // Filter modes that can be set on 'texture2d' type OSPTexture typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_TEXTURE_FILTER_LINEAR = 0, // default bilinear interpolation OSP_TEXTURE_FILTER_NEAREST = 1 // use nearest-neighbor interpolation } OSPTextureFilter; // Wrap modes that can be set on 'texture2d' type OSPTexture typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_TEXTURE_WRAP_REPEAT, OSP_TEXTURE_WRAP_MIRRORED_REPEAT, OSP_TEXTURE_WRAP_CLAMP_TO_EDGE } OSPTextureWrapMode; // Error codes returned by various API and callback functions typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_NO_ERROR = 0, // No error has been recorded OSP_UNKNOWN_ERROR = 1, // An unknown error has occurred OSP_INVALID_ARGUMENT = 2, // An invalid argument is specified OSP_INVALID_OPERATION = 3, // The operation is not allowed for the specified object OSP_OUT_OF_MEMORY = 4, // There is not enough memory left to execute the command OSP_UNSUPPORTED_CPU = 5, // The CPU is not supported as it does not support SSE4.1 OSP_VERSION_MISMATCH = 6, // A module could not be loaded due to mismatching version } OSPError; // OSPRay format constants for Frame Buffer creation typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_FB_NONE, // framebuffer will not be mapped by application OSP_FB_RGBA8, // one dword per pixel: rgb+alpha, each one byte OSP_FB_SRGBA, // one dword per pixel: rgb (in sRGB space) + alpha, each one // byte OSP_FB_RGBA32F, // one float4 per pixel: rgb+alpha, each one float } OSPFrameBufferFormat; // OSPRay channel constants for Frame Buffer (can be OR'ed together) typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_FB_COLOR = (1 << 0), OSP_FB_DEPTH = (1 << 1), OSP_FB_ACCUM = (1 << 2), OSP_FB_VARIANCE = (1 << 3), OSP_FB_NORMAL = (1 << 4), // in world-space OSP_FB_ALBEDO = (1 << 5), OSP_FB_ID_PRIMITIVE = (1 << 6), OSP_FB_ID_OBJECT = (1 << 7), OSP_FB_ID_INSTANCE = (1 << 8) } OSPFrameBufferChannel; // OSPRay events which can be waited on via ospWait() typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_NONE_FINISHED = 0, OSP_WORLD_RENDERED = 10, OSP_WORLD_COMMITTED = 20, OSP_FRAME_FINISHED = 30, OSP_TASK_FINISHED = 100000 } OSPSyncEvent; // OSPRay cell types definition for unstructured volumes, values are set to // match VTK typedef enum #if __cplusplus >= 201103L : uint8_t #endif { OSP_TETRAHEDRON = 10, OSP_HEXAHEDRON = 12, OSP_WEDGE = 13, OSP_PYRAMID = 14, OSP_UNKNOWN_CELL_TYPE = 255 } OSPUnstructuredCellType; // OSPRay camera stereo image modes typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_STEREO_NONE, OSP_STEREO_LEFT, OSP_STEREO_RIGHT, OSP_STEREO_SIDE_BY_SIDE, OSP_STEREO_TOP_BOTTOM, OSP_STEREO_UNKNOWN = 255 } OSPStereoMode; typedef enum #if __cplusplus >= 201103L : uint32_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 : uint32_t #endif { OSP_ROUND, OSP_FLAT, OSP_RIBBON, OSP_DISJOINT, OSP_UNKNOWN_CURVE_TYPE = 255 } OSPCurveType; typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_SPHERE = 50, OSP_DISC = 51, OSP_ORIENTED_DISC = 52, OSP_UNKNOWN_SPHERE_TYPE = 255 } OSPSphereType; typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_LINEAR, OSP_BEZIER, OSP_BSPLINE, OSP_HERMITE, OSP_CATMULL_ROM, OSP_UNKNOWN_CURVE_BASIS = 255 } OSPCurveBasis; typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_SUBDIVISION_NO_BOUNDARY, OSP_SUBDIVISION_SMOOTH_BOUNDARY, OSP_SUBDIVISION_PIN_CORNERS, OSP_SUBDIVISION_PIN_BOUNDARY, OSP_SUBDIVISION_PIN_ALL } OSPSubdivisionMode; // AMR Volume rendering methods typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_AMR_CURRENT, OSP_AMR_FINEST, OSP_AMR_OCTANT } OSPAMRMethod; // Filter modes for VDB and structured volumes, compatible with VKL typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_VOLUME_FILTER_NEAREST = 0, // treating voxel cell as constant OSP_VOLUME_FILTER_LINEAR = 100, // default trilinear interpolation OSP_VOLUME_FILTER_CUBIC = 200 // tricubic interpolation } OSPVolumeFilter; // VDB node data format typedef enum #if __cplusplus > 201103L : uint32_t #endif { OSP_VOLUME_FORMAT_TILE = 0, // node with no spatial variation. OSP_VOLUME_FORMAT_DENSE_ZYX // a dense grid of voxels in zyx layout } OSPVolumeFormat; // OSPRay pixel filter types typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_PIXELFILTER_POINT, OSP_PIXELFILTER_BOX, OSP_PIXELFILTER_GAUSS, OSP_PIXELFILTER_MITCHELL, OSP_PIXELFILTER_BLACKMAN_HARRIS } OSPPixelFilterType; // OSPRay light quantity types typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_INTENSITY_QUANTITY_RADIANCE, // unit W/sr/m^2 OSP_INTENSITY_QUANTITY_IRRADIANCE, // unit W/m^2 OSP_INTENSITY_QUANTITY_INTENSITY, // radiant intensity, unit W/sr OSP_INTENSITY_QUANTITY_POWER, // radiant flux, unit W OSP_INTENSITY_QUANTITY_SCALE, // linear scaling factor for the built-in type OSP_INTENSITY_QUANTITY_UNKNOWN } OSPIntensityQuantity; // OSPRay quality levels (used for denoiser), same values as OIDN typedef enum #if __cplusplus >= 201103L : uint32_t #endif { OSP_DENOISER_QUALITY_LOW = 4, OSP_DENOISER_QUALITY_MEDIUM = 5, OSP_DENOISER_QUALITY_HIGH = 6 } OSPDenoiserQuality; RenderKit-ospray-85af292/ospray/include/ospray/ospray.h000066400000000000000000000247631464752671100232520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #ifndef NULL #if __cplusplus >= 201103L #define NULL nullptr #else #define NULL 0 #endif #endif #include #include #include "OSPEnums.h" #ifdef _WIN32 #ifdef ospray_EXPORTS #define OSPRAY_INTERFACE __declspec(dllexport) #else #define OSPRAY_INTERFACE __declspec(dllimport) #endif #else #define OSPRAY_INTERFACE #endif #ifdef __GNUC__ #define OSP_DEPRECATED __attribute__((deprecated)) #elif defined(_MSC_VER) #define OSP_DEPRECATED __declspec(deprecated) #else #define OSP_DEPRECATED #endif #ifdef __cplusplus // C++ DOES support default initializers #define OSP_DEFAULT_VAL(a) = a #else /* C99 does NOT support default initializers, so we use this macro to define them away */ #define OSP_DEFAULT_VAL(a) #endif // Give OSPRay handle types a concrete definition to enable C++ type checking #ifdef __cplusplus namespace osp { struct Device; struct ManagedObject { }; struct Camera : public ManagedObject { }; struct Data : public ManagedObject { }; struct FrameBuffer : public ManagedObject { }; struct Future : public ManagedObject { }; struct GeometricModel : public ManagedObject { }; struct Geometry : public ManagedObject { }; struct Group : public ManagedObject { }; struct ImageOperation : public ManagedObject { }; struct Instance : public ManagedObject { }; struct Light : public ManagedObject { }; struct Material : public ManagedObject { }; struct Renderer : public ManagedObject { }; struct Texture : public ManagedObject { }; struct TransferFunction : public ManagedObject { }; struct Volume : public ManagedObject { }; struct VolumetricModel : public ManagedObject { }; struct World : public ManagedObject { }; } // namespace osp typedef osp::Device *OSPDevice; typedef osp::Camera *OSPCamera; typedef osp::Data *OSPData; typedef osp::FrameBuffer *OSPFrameBuffer; typedef osp::Future *OSPFuture; typedef osp::GeometricModel *OSPGeometricModel; typedef osp::Geometry *OSPGeometry; typedef osp::Group *OSPGroup; typedef osp::ImageOperation *OSPImageOperation; typedef osp::Instance *OSPInstance; typedef osp::Light *OSPLight; typedef osp::ManagedObject *OSPObject; typedef osp::Material *OSPMaterial; typedef osp::Renderer *OSPRenderer; typedef osp::Texture *OSPTexture; typedef osp::TransferFunction *OSPTransferFunction; typedef osp::Volume *OSPVolume; typedef osp::VolumetricModel *OSPVolumetricModel; typedef osp::World *OSPWorld; #else typedef void *OSPDevice; typedef void _OSPManagedObject; /* Abstract object types. in C99, those are all the same because C99 doesn't know inheritance, and we want to make sure that a OSPGeometry can still be passed to a function that expects a OSPObject, etc. */ typedef _OSPManagedObject *OSPManagedObject, *OSPCamera, *OSPData, *OSPFrameBuffer, *OSPFuture, *OSPGeometricModel, *OSPGeometry, *OSPGroup, *OSPImageOperation, *OSPInstance, *OSPLight, *OSPMaterial, *OSPObject, *OSPRenderer, *OSPTexture, *OSPTransferFunction, *OSPVolume, *OSPVolumetricModel, *OSPWorld; #endif #ifdef __cplusplus extern "C" { #endif // OSPRay Initialization //////////////////////////////////////////////////// /* Initialize OSPRay using commandline arguments. equivalent to doing ospNewDevice() followed by ospSetCurrentDevice() returns OSPError value to report any errors during initialization */ OSPRAY_INTERFACE OSPError ospInit( int *argc OSP_DEFAULT_VAL(NULL), const char **argv OSP_DEFAULT_VAL(NULL)); // returns the OSPRay Version in use by the device OSPRAY_INTERFACE int64_t ospDeviceGetProperty(OSPDevice, OSPDeviceProperty); // Shutdown the OSPRay engine...effectively deletes whatever device is currently // set. OSPRAY_INTERFACE void ospShutdown(); // Create an OSPRay engine backend using explicit device string. OSPRAY_INTERFACE OSPDevice ospNewDevice( const char *deviceType OSP_DEFAULT_VAL("cpu")); // Set current device the API responds to OSPRAY_INTERFACE void ospSetCurrentDevice(OSPDevice); // Get the currently set device OSPRAY_INTERFACE OSPDevice ospGetCurrentDevice(); OSPRAY_INTERFACE void ospDeviceSetParam( OSPDevice, const char *id, OSPDataType, const void *mem); OSPRAY_INTERFACE void ospDeviceRemoveParam(OSPDevice, const char *id); // Status message callback function type typedef void (*OSPStatusCallback)(void *userData, const char *messageText); // Set callback for given Device to call when a status message occurs OSPRAY_INTERFACE void ospDeviceSetStatusCallback( OSPDevice, OSPStatusCallback, void *userData); // Error message callback function type typedef void (*OSPErrorCallback)( void *userData, OSPError, const char *errorDetails); // Set callback for given Device to call when an error occurs OSPRAY_INTERFACE void ospDeviceSetErrorCallback( OSPDevice, OSPErrorCallback, void *userData); // Get the OSPError code for the last error that has occurred on the device OSPRAY_INTERFACE OSPError ospDeviceGetLastErrorCode(OSPDevice); // Get the message for the last error that has occurred on the device OSPRAY_INTERFACE const char *ospDeviceGetLastErrorMsg(OSPDevice); // Commit parameters on a given device OSPRAY_INTERFACE void ospDeviceCommit(OSPDevice); // OSPDevice handle lifetimes OSPRAY_INTERFACE void ospDeviceRelease(OSPDevice); OSPRAY_INTERFACE void ospDeviceRetain(OSPDevice); /* Load module 'name' from shard lib libospray_module_.so returns OSPError value to report any errors during initialization */ OSPRAY_INTERFACE OSPError ospLoadModule(const char *name); // OSPRay Data Arrays /////////////////////////////////////////////////////// // Memory deleter callback function type typedef void (*OSPDeleterCallback)( const void *userData, const void *sharedData); OSPRAY_INTERFACE OSPData ospNewSharedData(const void *sharedData, OSPDataType, uint64_t numItems1, int64_t byteStride1 OSP_DEFAULT_VAL(0), uint64_t numItems2 OSP_DEFAULT_VAL(1), int64_t byteStride2 OSP_DEFAULT_VAL(0), uint64_t numItems3 OSP_DEFAULT_VAL(1), int64_t byteStride3 OSP_DEFAULT_VAL(0), OSPDeleterCallback OSP_DEFAULT_VAL(NULL), const void *userPtr OSP_DEFAULT_VAL(NULL)); OSPRAY_INTERFACE OSPData ospNewData(OSPDataType, uint64_t numItems1, uint64_t numItems2 OSP_DEFAULT_VAL(1), uint64_t numItems3 OSP_DEFAULT_VAL(1)); OSPRAY_INTERFACE void ospCopyData(const OSPData source, OSPData destination, uint64_t destinationIndex1 OSP_DEFAULT_VAL(0), uint64_t destinationIndex2 OSP_DEFAULT_VAL(0), uint64_t destinationIndex3 OSP_DEFAULT_VAL(0)); // Renderable Objects /////////////////////////////////////////////////////// OSPRAY_INTERFACE OSPLight ospNewLight(const char *type); OSPRAY_INTERFACE OSPCamera ospNewCamera(const char *type); OSPRAY_INTERFACE OSPGeometry ospNewGeometry(const char *type); OSPRAY_INTERFACE OSPVolume ospNewVolume(const char *type); OSPRAY_INTERFACE OSPGeometricModel ospNewGeometricModel( OSPGeometry OSP_DEFAULT_VAL(NULL)); OSPRAY_INTERFACE OSPVolumetricModel ospNewVolumetricModel( OSPVolume OSP_DEFAULT_VAL(NULL)); // Model Meta-Data ////////////////////////////////////////////////////////// OSPRAY_INTERFACE OSPMaterial ospNewMaterial(const char *materialType); OSPRAY_INTERFACE OSPTransferFunction ospNewTransferFunction(const char *type); OSPRAY_INTERFACE OSPTexture ospNewTexture(const char *type); // Instancing /////////////////////////////////////////////////////////////// OSPRAY_INTERFACE OSPGroup ospNewGroup(); OSPRAY_INTERFACE OSPInstance ospNewInstance(OSPGroup OSP_DEFAULT_VAL(NULL)); // Top-level Worlds ///////////////////////////////////////////////////////// OSPRAY_INTERFACE OSPWorld ospNewWorld(); typedef struct { float lower[3]; float upper[3]; } OSPBounds; // Return bounds if the object is able (OSPWorld, OSPInstance, and OSPGroup) OSPRAY_INTERFACE OSPBounds ospGetBounds(OSPObject); // Object + Parameter Lifetime Management /////////////////////////////////// // Set a parameter, where 'mem' points the address of the type specified OSPRAY_INTERFACE void ospSetParam( OSPObject, const char *id, OSPDataType, const void *mem); OSPRAY_INTERFACE void ospRemoveParam(OSPObject, const char *id); // Make parameters which have been set visible to the object OSPRAY_INTERFACE void ospCommit(OSPObject); // Reduce the application-side object ref count by 1 OSPRAY_INTERFACE void ospRelease(OSPObject); // Increace the application-side object ref count by 1 OSPRAY_INTERFACE void ospRetain(OSPObject); // FrameBuffer Manipulation ///////////////////////////////////////////////// OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(int size_x, int size_y, OSPFrameBufferFormat format OSP_DEFAULT_VAL(OSP_FB_SRGBA), uint32_t frameBufferChannels OSP_DEFAULT_VAL(OSP_FB_COLOR)); OSPRAY_INTERFACE OSPImageOperation ospNewImageOperation(const char *type); // Pointer access (read-only) to the memory of the given frame buffer channel OSPRAY_INTERFACE const void *ospMapFrameBuffer( OSPFrameBuffer, OSPFrameBufferChannel OSP_DEFAULT_VAL(OSP_FB_COLOR)); // Unmap a previously mapped frame buffer pointer OSPRAY_INTERFACE void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer); // Get variance from last rendered frame OSPRAY_INTERFACE float ospGetVariance(OSPFrameBuffer); // Reset frame buffer accumulation for next render frame call OSPRAY_INTERFACE void ospResetAccumulation(OSPFrameBuffer); // Frame Rendering ////////////////////////////////////////////////////////// OSPRAY_INTERFACE OSPRenderer ospNewRenderer(const char *type); // Render a frame (non-blocking), return a future to the task executed by OSPRay OSPRAY_INTERFACE OSPFuture ospRenderFrame( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); // Ask if all events tracked by an OSPFuture handle have been completed OSPRAY_INTERFACE int ospIsReady( OSPFuture, OSPSyncEvent OSP_DEFAULT_VAL(OSP_TASK_FINISHED)); // Wait on a specific event OSPRAY_INTERFACE void ospWait( OSPFuture, OSPSyncEvent OSP_DEFAULT_VAL(OSP_TASK_FINISHED)); // Cancel the given task (may block calling thread) OSPRAY_INTERFACE void ospCancel(OSPFuture); // Get the completion state of the given task [0.f-1.f] OSPRAY_INTERFACE float ospGetProgress(OSPFuture); // Get the execution duration (in seconds) state of the given task OSPRAY_INTERFACE float ospGetTaskDuration(OSPFuture); typedef struct { int hasHit; float worldPosition[3]; OSPInstance instance; OSPGeometricModel model; uint32_t primID; } OSPPickResult; OSPRAY_INTERFACE void ospPick(OSPPickResult *result, OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld, float screenPos_x, float screenPos_y); #ifdef __cplusplus } // extern "C" #endif RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp.h000066400000000000000000000013571464752671100241060ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // \file ospray/ospray.h Defines the external OSPRay API */ // NOTE: this is a single include for all the C++ wrappers around ospray.h #include "ospray_cpp/Camera.h" #include "ospray_cpp/Data.h" #include "ospray_cpp/Device.h" #include "ospray_cpp/FrameBuffer.h" #include "ospray_cpp/Future.h" #include "ospray_cpp/GeometricModel.h" #include "ospray_cpp/Group.h" #include "ospray_cpp/ImageOperation.h" #include "ospray_cpp/Instance.h" #include "ospray_cpp/Light.h" #include "ospray_cpp/Material.h" #include "ospray_cpp/Renderer.h" #include "ospray_cpp/Texture.h" #include "ospray_cpp/TransferFunction.h" #include "ospray_cpp/VolumetricModel.h" #include "ospray_cpp/World.h" RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/000077500000000000000000000000001464752671100237275ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Camera.h000066400000000000000000000013751464752671100252760ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Camera : public ManagedObject { public: Camera(const std::string &type); Camera(OSPCamera existing = nullptr); }; static_assert(sizeof(Camera) == sizeof(OSPCamera), "cpp::Camera can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Camera::Camera(const std::string &type) { ospObject = ospNewCamera(type.c_str()); } inline Camera::Camera(OSPCamera existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Camera, OSP_CAMERA); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Data.h000066400000000000000000000162051464752671100247550ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" // stl #include #include namespace ospray { namespace cpp { template class Data : public ManagedObject { public: // Construction from an existing array (explicit element type and size/stride) template Data(const void *init, OSPDataType type, const DIM_T &numItems); template Data(const void *init, OSPDataType type, const DIM_T &numItems, const DIM_T &byteStride); // Construction from an existing array (infer element type and size/stride) template Data(const T *init, const DIM_T &numItems); template Data(const T *init, const DIM_T &numItems, const DIM_T &byteStride); // Adapters to work with existing STL containers template Data(const std::array &arr); template Data(const std::vector &arr); // Set a single object as a 1-item data array template explicit Data(const T &obj); // Construct from an existing OSPData handle (cpp::Data then owns handle) Data(OSPData existing = nullptr); protected: template void validate_element_type(); private: template void validate_dimension_type(); void constructArray(const void *init, OSPDataType type, uint64_t numItems1, int64_t byteStride1 = 0, uint64_t numItems2 = 1, int64_t byteStride2 = 0, uint64_t numItems3 = 1, int64_t byteStride3 = 0); }; using SharedData = Data; using CopiedData = Data; class MovedData : public SharedData { public: template MovedData(std::vector &arr); private: template static void vectorDeleter(const void *vec, const void *addr); }; static_assert( sizeof(Data<>) == sizeof(OSPData), "cpp::Data can't have data members!"); // Inlined function definitions /////////////////////////////////////////// template template inline Data::Data( const void *init, OSPDataType type, const DIM_T &numItems) : Data(init, type, numItems, DIM_T(0)) {} template template inline Data::Data(const void *init, OSPDataType format, const DIM_T &numItems, const DIM_T &byteStride) { validate_dimension_type(); constexpr auto dim_t = OSPTypeFor::value; constexpr auto nDims = OSPDimensionalityOf::value; using vec_element_t = typename OSPVecElementOf::type; const auto *d = (const vec_element_t *)&numItems; const auto *s = (const vec_element_t *)&byteStride; switch (nDims) { case 1: constructArray(init, format, d[0], s[0]); break; case 2: constructArray(init, format, d[0], s[0], d[1], s[1]); break; case 3: constructArray(init, format, d[0], s[0], d[1], s[1], d[2], s[2]); break; default: throw std::runtime_error("invalid dimension type constructing cpp::Data"); } } template template inline Data::Data(const T *init, const DIM_T &numItems) : Data(init, numItems, DIM_T(0)) {} template template inline Data::Data( const T *init, const DIM_T &numItems, const DIM_T &byteStride) { validate_element_type(); validate_dimension_type(); constexpr auto format = OSPTypeFor::value; constexpr auto dim_t = OSPTypeFor::value; constexpr auto nDims = OSPDimensionalityOf::value; using vec_element_t = typename OSPVecElementOf::type; const auto *d = (const vec_element_t *)&numItems; const auto *s = (const vec_element_t *)&byteStride; switch (nDims) { case 1: constructArray(init, format, d[0], s[0]); break; case 2: constructArray(init, format, d[0], s[0], d[1], s[1]); break; case 3: constructArray(init, format, d[0], s[0], d[1], s[1], d[2], s[2]); break; default: throw std::runtime_error("invalid dimension type constructing cpp::Data"); } } template template inline Data::Data(const std::array &arr) : Data(arr.data(), N) {} template template inline Data::Data(const std::vector &arr) : Data(arr.data(), arr.size()) {} template template inline Data::Data(const T &obj) : Data(&obj, size_t(1)) {} template inline Data::Data(OSPData existing) : ManagedObject(existing) {} template template inline void Data::validate_element_type() { static_assert(OSPTypeFor::value != OSP_UNKNOWN, "Only types corresponding to OSPDataType values can be set " "as elements in OSPRay Data arrays. NOTE: Math types (vec, " "box, linear, affine) must be inferable as OSP_* enums, which are " "defined by the OSPTYPEFOR_SPECIALIZATION() macro."); } template template inline void Data::validate_dimension_type() { static_assert(OSPTypeFor::value == OSP_INT || OSPTypeFor::value == OSP_VEC2I || OSPTypeFor::value == OSP_VEC3I || OSPTypeFor::value == OSP_ULONG || OSPTypeFor::value == OSP_VEC2UL || OSPTypeFor::value == OSP_VEC3UL, "The type used to describe an OSPData array dimensions must infer to " "OSP_INT, OSP_ULONG, OSP_VEC2UL, or OSP_VEC3UL. These type inferences " "are defined by using the OSPTYPEFOR_SPECIALIZATION() macro."); } template inline void Data::constructArray(const void *data, OSPDataType format, uint64_t numItems1, int64_t byteStride1, uint64_t numItems2, int64_t byteStride2, uint64_t numItems3, int64_t byteStride3) { OSPData tmp = ospNewSharedData(data, format, numItems1, byteStride1, numItems2, byteStride2, numItems3, byteStride3); if (SHARED) { ospObject = tmp; } else { ospObject = ospNewData(format, numItems1, numItems2, numItems3); ospCopyData(tmp, ospObject); ospRelease(tmp); } } template void MovedData::vectorDeleter(const void *vec, const void *addr) { auto *v = (std::vector *)vec; assert(v->data() == addr); (void)addr; delete v; } template inline MovedData::MovedData(std::vector &arr) { validate_element_type(); auto *donee = new std::vector(std::move(arr)); ospObject = ospNewSharedData(donee->data(), OSPTypeFor::value, donee->size(), 0, 1, 0, 1, 0, vectorDeleter, donee); } } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::SharedData, OSP_DATA); OSPTYPEFOR_SPECIALIZATION(cpp::CopiedData, OSP_DATA); OSPTYPEFOR_SPECIALIZATION(cpp::MovedData, OSP_DATA); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Device.h000066400000000000000000000072611464752671100253050ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ospray/ospray.h" // ospray::cpp #include "Traits.h" #include #include namespace ospray { namespace cpp { class Device { public: Device(const std::string &type = "cpu"); Device(const Device ©); Device(Device &&move); Device(OSPDevice existing = nullptr); ~Device(); Device &operator=(const Device ©); Device &operator=(Device &&move); template void setErrorCallback(FCN_T &&fcn); template void setStatusCallback(FCN_T &&fcn); void setParam(const std::string &name, const int v) const; void setParam(const std::string &name, const unsigned int v) const; void setParam(const std::string &name, const bool v) const; void setParam(const std::string &name, const char *v) const; void setParam(const std::string &name, const std::string &v) const; void setParam(const std::string &name, OSPDataType, const void *) const; void removeParam(const std::string &name) const; void commit() const; void setCurrent() const; static Device current(); OSPDevice handle() const; private: OSPDevice ospHandle; }; // Inlined function definitions /////////////////////////////////////////// inline Device::Device(const std::string &type) { ospHandle = ospNewDevice(type.c_str()); } inline Device::Device(const Device ©) : ospHandle(copy.ospHandle) { ospDeviceRetain(copy.handle()); } inline Device::Device(Device &&move) { ospHandle = move.handle(); move.ospHandle = nullptr; } inline Device::Device(OSPDevice existing) : ospHandle(existing) {} inline Device::~Device() { ospDeviceRelease(ospHandle); } inline Device &Device::operator=(const Device ©) { ospDeviceRelease(ospHandle); ospHandle = copy.handle(); ospDeviceRetain(copy.handle()); return *this; } inline Device &Device::operator=(Device &&move) { ospDeviceRelease(ospHandle); ospHandle = move.handle(); move.ospHandle = nullptr; return *this; } template inline void Device::setErrorCallback(FCN_T &&fcn) { ospDeviceSetErrorCallback(ospHandle, std::forward(fcn), nullptr); } template inline void Device::setStatusCallback(FCN_T &&fcn) { ospDeviceSetStatusCallback(ospHandle, std::forward(fcn), nullptr); } inline void Device::setParam(const std::string &name, const int v) const { ospDeviceSetParam(ospHandle, name.c_str(), OSP_INT, &v); } inline void Device::setParam( const std::string &name, const unsigned int v) const { ospDeviceSetParam(ospHandle, name.c_str(), OSP_UINT, &v); } inline void Device::setParam(const std::string &name, const bool v) const { ospDeviceSetParam(ospHandle, name.c_str(), OSP_BOOL, &v); } inline void Device::setParam(const std::string &name, const char *v) const { ospDeviceSetParam(ospHandle, name.c_str(), OSP_STRING, v); } inline void Device::setParam( const std::string &name, const std::string &v) const { ospDeviceSetParam(ospHandle, name.c_str(), OSP_STRING, v.c_str()); } inline void Device::setParam( const std::string &name, OSPDataType type, const void *mem) const { ospDeviceSetParam(ospHandle, name.c_str(), type, mem); } inline void Device::removeParam(const std::string &name) const { ospDeviceRemoveParam(ospHandle, name.c_str()); } inline void Device::commit() const { ospDeviceCommit(ospHandle); } inline void Device::setCurrent() const { ospSetCurrentDevice(ospHandle); } inline Device Device::current() { return Device(ospGetCurrentDevice()); } inline OSPDevice Device::handle() const { return ospHandle; } } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Device, OSP_DEVICE); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/FrameBuffer.h000066400000000000000000000062501464752671100262670ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "Camera.h" #include "Future.h" #include "GeometricModel.h" #include "Instance.h" #include "Renderer.h" #include "World.h" namespace ospray { namespace cpp { struct PickResult { bool hasHit{false}; float worldPosition[3]; Instance instance{(OSPInstance) nullptr}; GeometricModel model{(OSPGeometricModel) nullptr}; uint32_t primID{0}; }; class FrameBuffer : public ManagedObject { public: // NOTE(jda) - this does *not* create the underlying OSP object FrameBuffer() = default; FrameBuffer(int size_x, int size_y, OSPFrameBufferFormat format = OSP_FB_SRGBA, int channels = OSP_FB_COLOR); FrameBuffer(OSPFrameBuffer existing); void resetAccumulation() const; Future renderFrame( const Renderer &renderer, const Camera &camera, const World &world) const; PickResult pick(const Renderer &renderer, const Camera &camera, const World &world, float screenPos_x, float screenPos_y) const; void *map(OSPFrameBufferChannel channel) const; void unmap(void *ptr) const; void clear() const; float variance() const; }; static_assert(sizeof(FrameBuffer) == sizeof(OSPFrameBuffer), "cpp::FrameBuffer can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline FrameBuffer::FrameBuffer( int size_x, int size_y, OSPFrameBufferFormat format, int channels) { ospObject = ospNewFrameBuffer(size_x, size_y, format, channels); } inline FrameBuffer::FrameBuffer(OSPFrameBuffer existing) : ManagedObject(existing) {} inline void FrameBuffer::resetAccumulation() const { ospResetAccumulation(handle()); } inline Future FrameBuffer::renderFrame( const Renderer &renderer, const Camera &camera, const World &world) const { return ospRenderFrame( handle(), renderer.handle(), camera.handle(), world.handle()); } inline PickResult FrameBuffer::pick(const Renderer &renderer, const Camera &camera, const World &world, float screenPos_x, float screenPos_y) const { PickResult res; OSPPickResult pick; ospPick((OSPPickResult *)&pick, handle(), renderer.handle(), camera.handle(), world.handle(), screenPos_x, screenPos_y); if (pick.hasHit) { res.hasHit = true; res.instance = Instance(pick.instance); res.model = GeometricModel(pick.model); res.primID = pick.primID; res.worldPosition[0] = pick.worldPosition[0]; res.worldPosition[1] = pick.worldPosition[1]; res.worldPosition[2] = pick.worldPosition[2]; } return res; } inline void *FrameBuffer::map(OSPFrameBufferChannel channel) const { return const_cast(ospMapFrameBuffer(handle(), channel)); } inline void FrameBuffer::unmap(void *ptr) const { ospUnmapFrameBuffer(ptr, handle()); } inline void FrameBuffer::clear() const { ospResetAccumulation(handle()); } inline float FrameBuffer::variance() const { return ospGetVariance(handle()); } } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::FrameBuffer, OSP_FRAMEBUFFER); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Future.h000066400000000000000000000021751464752671100253570ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Future : public ManagedObject { public: Future(OSPFuture existing = nullptr); bool isReady(OSPSyncEvent = OSP_TASK_FINISHED); void wait(OSPSyncEvent = OSP_TASK_FINISHED); void cancel(); float progress(); float duration(); }; static_assert(sizeof(Future) == sizeof(OSPFuture), "cpp::Future can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Future::Future(OSPFuture existing) : ManagedObject(existing) {} inline bool Future::isReady(OSPSyncEvent e) { return ospIsReady(handle(), e); } inline void Future::wait(OSPSyncEvent e) { ospWait(handle(), e); } inline void Future::cancel() { ospCancel(handle()); } inline float Future::progress() { return ospGetProgress(handle()); } inline float Future::duration() { return ospGetTaskDuration(handle()); } } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Future, OSP_FUTURE); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/GeometricModel.h000066400000000000000000000020321464752671100267740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Geometry.h" #include "Material.h" namespace ospray { namespace cpp { class GeometricModel : public ManagedObject { public: GeometricModel(const Geometry &); GeometricModel(OSPGeometry); GeometricModel(OSPGeometricModel existing = nullptr); }; static_assert(sizeof(GeometricModel) == sizeof(OSPGeometricModel), "cpp::GeometricModel can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline GeometricModel::GeometricModel(const Geometry &geom) : GeometricModel(geom.handle()) {} inline GeometricModel::GeometricModel(OSPGeometry geom) { ospObject = ospNewGeometricModel(geom); } inline GeometricModel::GeometricModel(OSPGeometricModel existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::GeometricModel, OSP_GEOMETRIC_MODEL); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Geometry.h000066400000000000000000000014431464752671100256750ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Geometry : public ManagedObject { public: Geometry(const std::string &type); Geometry(OSPGeometry existing = nullptr); }; static_assert(sizeof(Geometry) == sizeof(OSPGeometry), "cpp::Geometry can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Geometry::Geometry(const std::string &type) { ospObject = ospNewGeometry(type.c_str()); } inline Geometry::Geometry(OSPGeometry existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Geometry, OSP_GEOMETRY); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Group.h000066400000000000000000000012471464752671100252000ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Group : public ManagedObject { public: Group(); Group(OSPGroup existing); }; static_assert( sizeof(Group) == sizeof(OSPGroup), "cpp::Group can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Group::Group() { ospObject = ospNewGroup(); } inline Group::Group(OSPGroup existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Group, OSP_GROUP); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/ImageOperation.h000066400000000000000000000016341464752671100270070ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class ImageOperation : public ManagedObject { public: ImageOperation(const std::string &type); ImageOperation(OSPImageOperation existing = nullptr); }; static_assert(sizeof(ImageOperation) == sizeof(OSPImageOperation), "cpp::ImageOperation can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline ImageOperation::ImageOperation(const std::string &type) { ospObject = ospNewImageOperation(type.c_str()); } inline ImageOperation::ImageOperation(OSPImageOperation existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::ImageOperation, OSP_IMAGE_OPERATION); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Instance.h000066400000000000000000000015571464752671100256540ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Group.h" namespace ospray { namespace cpp { class Instance : public ManagedObject { public: Instance(const Group &group); Instance(OSPGroup group); Instance(OSPInstance existing = nullptr); }; static_assert(sizeof(Instance) == sizeof(OSPInstance), "cpp::Instance can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Instance::Instance(const Group &group) : Instance(group.handle()) {} inline Instance::Instance(OSPGroup group) { ospObject = ospNewInstance(group); } inline Instance::Instance(OSPInstance existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Instance, OSP_INSTANCE); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Light.h000066400000000000000000000013751464752671100251550ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Light : public ManagedObject { public: Light(const std::string &light_type); Light(OSPLight existing = nullptr); }; static_assert( sizeof(Light) == sizeof(OSPLight), "cpp::Light can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Light::Light(const std::string &light_type) { ospObject = ospNewLight(light_type.c_str()); } inline Light::Light(OSPLight existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Light, OSP_LIGHT); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/ManagedObject.h000066400000000000000000000134301464752671100265640ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // stl #include #include #include // ospray #include "ospray/ospray.h" // ospray::cpp #include "Traits.h" namespace ospray { namespace cpp { template class ManagedObject { public: static constexpr OSPDataType type = TYPE; ManagedObject(HANDLE_T object = nullptr); ~ManagedObject(); ManagedObject(const ManagedObject ©); ManagedObject(ManagedObject &&move); ManagedObject &operator=(const ManagedObject ©); ManagedObject &operator=(ManagedObject &&move); bool operator==(const ManagedObject &other) const; bool operator!=(const ManagedObject &other) const; template void setParam(const std::string &name, const T &v) const; void setParam(const std::string &name, const char *v) const; void setParam(const std::string &name, const std::string &v) const; void setParam(const std::string &name, OSPDataType, const void *) const; void removeParam(const std::string &name) const; template BOX3F_T getBounds() const; void commit() const; //! Get the underlying specific OSP* handle HANDLE_T handle() const; //! return whether the given object is valid, or NULL operator bool() const; protected: HANDLE_T ospObject; }; // Inlined function definitions /////////////////////////////////////////// template inline ManagedObject::ManagedObject(HANDLE_T object) : ospObject(object) { using OSPObject_T = typename std::remove_pointer::type; using OtherOSP_T = typename std::remove_pointer::type; static_assert(std::is_same::value || std::is_base_of::value, "ManagedObject can only be instantiated with " "OSPObject (a.k.a. osp::ManagedObject*) or one of its" "descendants (a.k.a. the OSP* family of types)."); } template inline ManagedObject::~ManagedObject() { ospRelease(ospObject); } template inline ManagedObject::ManagedObject( const ManagedObject ©) : ospObject(copy.ospObject) { if (copy.handle()) ospRetain(copy.handle()); } template inline ManagedObject::ManagedObject( ManagedObject &&move) { ospObject = move.handle(); move.ospObject = nullptr; } template inline ManagedObject &ManagedObject::operator=( const ManagedObject ©) { ospRelease(ospObject); ospObject = copy.handle(); if (copy.handle()) ospRetain(copy.handle()); return *this; } template inline ManagedObject &ManagedObject::operator=( ManagedObject &&move) { ospRelease(ospObject); ospObject = move.handle(); move.ospObject = nullptr; return *this; } template template inline void ManagedObject::setParam( const std::string &name, const T &v) const { static_assert(OSPTypeFor::value != OSP_UNKNOWN, "Only types corresponding to OSPDataType values can be set " "as parameters on OSPRay objects. NOTE: Math types (vec, " "box, linear, affine) are " "expected to come from rkcommon::math."); ospSetParam(ospObject, name.c_str(), OSPTypeFor::value, &v); } template inline void ManagedObject::setParam( const std::string &name, const char *v) const { ospSetParam(ospObject, name.c_str(), OSP_STRING, v); } template inline void ManagedObject::setParam( const std::string &name, const std::string &v) const { ospSetParam(ospObject, name.c_str(), OSP_STRING, v.c_str()); } template inline void ManagedObject::setParam( const std::string &name, OSPDataType type, const void *mem) const { ospSetParam(ospObject, name.c_str(), type, mem); } template inline void ManagedObject::removeParam( const std::string &name) const { ospRemoveParam(ospObject, name.c_str()); } template template BOX3F_T ManagedObject::getBounds() const { static_assert(OSPTypeFor::value == OSP_BOX3F, "Your type for BOX3F_T must convert to OSP_BOX3F. You need to define" " this conversion via the OSPTYPEFOR_SPECIALIZATION macro."); auto b = ospGetBounds(ospObject); return *((BOX3F_T *)&b); } template inline void ManagedObject::commit() const { ospCommit(ospObject); } template inline HANDLE_T ManagedObject::handle() const { return ospObject; } template inline ManagedObject::operator bool() const { return handle() != nullptr; } template inline bool ManagedObject::operator==( const ManagedObject &other) const { return handle() == other.handle(); } template inline bool ManagedObject::operator!=( const ManagedObject &other) const { return !(*this == other); } } // namespace cpp } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Material.h000066400000000000000000000014571464752671100256450ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Material : public ManagedObject { public: Material(const std::string &mat_type); Material(OSPMaterial existing = nullptr); }; static_assert(sizeof(Material) == sizeof(OSPMaterial), "cpp::Material can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Material::Material(const std::string &mat_type) { ospObject = ospNewMaterial(mat_type.c_str()); } inline Material::Material(OSPMaterial existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Material, OSP_MATERIAL); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Renderer.h000066400000000000000000000014431464752671100256500ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Renderer : public ManagedObject { public: Renderer(const std::string &type); Renderer(OSPRenderer existing = nullptr); }; static_assert(sizeof(Renderer) == sizeof(OSPRenderer), "cpp::Renderer can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Renderer::Renderer(const std::string &type) { ospObject = ospNewRenderer(type.c_str()); } inline Renderer::Renderer(OSPRenderer existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Renderer, OSP_RENDERER); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Texture.h000066400000000000000000000014201464752671100255350ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class Texture : public ManagedObject { public: Texture(const std::string &type); Texture(OSPTexture existing = nullptr); }; static_assert(sizeof(Texture) == sizeof(OSPTexture), "cpp::Texture can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Texture::Texture(const std::string &type) { ospObject = ospNewTexture(type.c_str()); } inline Texture::Texture(OSPTexture existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Texture, OSP_TEXTURE); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Traits.h000066400000000000000000000227721464752671100253600ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // ospray #include "ospray/ospray.h" static_assert( sizeof(bool) == 1, "OSPRay assumes the size of 'bool' to be 1 byte."); namespace ospray { // Infer (compile time) OSP_DATA_TYPE from input type ///////////////////////// template struct OSPTypeFor { static constexpr OSPDataType value = OSP_UNKNOWN; }; #define OSPTYPEFOR_SPECIALIZATION(type, osp_type) \ template <> \ struct OSPTypeFor \ { \ static constexpr OSPDataType value = osp_type; \ }; OSPTYPEFOR_SPECIALIZATION(void *, OSP_VOID_PTR); OSPTYPEFOR_SPECIALIZATION(char *, OSP_STRING); OSPTYPEFOR_SPECIALIZATION(const char *, OSP_STRING); OSPTYPEFOR_SPECIALIZATION(const char[], OSP_STRING); OSPTYPEFOR_SPECIALIZATION(bool, OSP_BOOL); OSPTYPEFOR_SPECIALIZATION(char, OSP_CHAR); OSPTYPEFOR_SPECIALIZATION(unsigned char, OSP_UCHAR); OSPTYPEFOR_SPECIALIZATION(short, OSP_SHORT); OSPTYPEFOR_SPECIALIZATION(unsigned short, OSP_USHORT); OSPTYPEFOR_SPECIALIZATION(int, OSP_INT); OSPTYPEFOR_SPECIALIZATION(unsigned int, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(long, OSP_LONG); OSPTYPEFOR_SPECIALIZATION(unsigned long, OSP_ULONG); OSPTYPEFOR_SPECIALIZATION(long long, OSP_LONG); OSPTYPEFOR_SPECIALIZATION(unsigned long long, OSP_ULONG); OSPTYPEFOR_SPECIALIZATION(float, OSP_FLOAT); OSPTYPEFOR_SPECIALIZATION(double, OSP_DOUBLE); OSPTYPEFOR_SPECIALIZATION(OSPObject, OSP_OBJECT); OSPTYPEFOR_SPECIALIZATION(OSPCamera, OSP_CAMERA); OSPTYPEFOR_SPECIALIZATION(OSPData, OSP_DATA); OSPTYPEFOR_SPECIALIZATION(OSPFrameBuffer, OSP_FRAMEBUFFER); OSPTYPEFOR_SPECIALIZATION(OSPFuture, OSP_FUTURE); OSPTYPEFOR_SPECIALIZATION(OSPGeometricModel, OSP_GEOMETRIC_MODEL); OSPTYPEFOR_SPECIALIZATION(OSPGeometry, OSP_GEOMETRY); OSPTYPEFOR_SPECIALIZATION(OSPGroup, OSP_GROUP); OSPTYPEFOR_SPECIALIZATION(OSPImageOperation, OSP_IMAGE_OPERATION); OSPTYPEFOR_SPECIALIZATION(OSPInstance, OSP_INSTANCE); OSPTYPEFOR_SPECIALIZATION(OSPLight, OSP_LIGHT); OSPTYPEFOR_SPECIALIZATION(OSPMaterial, OSP_MATERIAL); OSPTYPEFOR_SPECIALIZATION(OSPRenderer, OSP_RENDERER); OSPTYPEFOR_SPECIALIZATION(OSPTexture, OSP_TEXTURE); OSPTYPEFOR_SPECIALIZATION(OSPTransferFunction, OSP_TRANSFER_FUNCTION); OSPTYPEFOR_SPECIALIZATION(OSPVolume, OSP_VOLUME); OSPTYPEFOR_SPECIALIZATION(OSPVolumetricModel, OSP_VOLUMETRIC_MODEL); OSPTYPEFOR_SPECIALIZATION(OSPWorld, OSP_WORLD); OSPTYPEFOR_SPECIALIZATION(OSPLogLevel, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPDeviceProperty, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPDataType, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPTextureFormat, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPTextureFilter, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPTextureWrapMode, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPError, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPFrameBufferFormat, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPFrameBufferChannel, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPSyncEvent, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPUnstructuredCellType, OSP_UCHAR); OSPTYPEFOR_SPECIALIZATION(OSPStereoMode, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPShutterType, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPCurveType, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPCurveBasis, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPSubdivisionMode, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPAMRMethod, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPVolumeFilter, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPVolumeFormat, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPPixelFilterType, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPIntensityQuantity, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPSphereType, OSP_UINT); OSPTYPEFOR_SPECIALIZATION(OSPDenoiserQuality, OSP_UINT); #define OSPTYPEFOR_DEFINITION(type) \ constexpr OSPDataType OSPTypeFor::value // Infer element type from OSP_* vec types input type ///////////////////////// template struct OSPVecElementOf { using type = void; }; #define OSPVECELEMENTOF_SPECIALIZATION(osp_type, out_type) \ template <> \ struct OSPVecElementOf \ { \ using type = out_type; \ }; OSPVECELEMENTOF_SPECIALIZATION(OSP_UCHAR, unsigned char); OSPVECELEMENTOF_SPECIALIZATION(OSP_INT, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_UINT, uint32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_LONG, int64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_ULONG, uint64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_FLOAT, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2UC, unsigned char); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3UC, unsigned char); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4UC, unsigned char); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2C, char); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3C, char); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4C, char); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2S, short); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3S, short); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4S, short); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2US, unsigned short); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3US, unsigned short); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4US, unsigned short); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2UI, uint32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3UI, uint32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4UI, uint32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2L, int64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3L, int64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4L, int64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2UL, uint64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3UL, uint64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4UL, uint64_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2F, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3F, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4F, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC2D, double); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC3D, double); OSPVECELEMENTOF_SPECIALIZATION(OSP_VEC4D, double); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX1I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX2I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX3I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX4I, int32_t); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX1F, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX2F, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX3F, float); OSPVECELEMENTOF_SPECIALIZATION(OSP_BOX4F, float); // Infer OSPDataType dimensionality /////////////////////////////////////////// template struct OSPDimensionalityOf { static constexpr int value = 1; }; #define OSPDIMENSIONALITYOF_SPECIALIZATION(osp_type, out_value) \ template <> \ struct OSPDimensionalityOf \ { \ static constexpr int value = out_value; \ }; OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2UC, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3UC, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4UC, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2C, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3C, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4C, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2S, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3S, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4S, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2US, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3US, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4US, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2I, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3I, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4I, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2UI, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3UI, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4UI, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2L, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3L, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4L, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2UL, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3UL, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4UL, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2H, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3H, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4H, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2F, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3F, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4F, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC2D, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC3D, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_VEC4D, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX1I, 1); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX2I, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX3I, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX4I, 4); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX1F, 1); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX2F, 2); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX3F, 3); OSPDIMENSIONALITYOF_SPECIALIZATION(OSP_BOX4F, 4); #define OSPDIMENSIONALITYOF_DEFINITION(type) \ constexpr int OSPDimensionalityOf::value } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/TransferFunction.h000066400000000000000000000017021464752671100273720ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ManagedObject.h" namespace ospray { namespace cpp { class TransferFunction : public ManagedObject { public: TransferFunction(const std::string &type); TransferFunction(OSPTransferFunction existing = nullptr); }; static_assert(sizeof(TransferFunction) == sizeof(OSPTransferFunction), "cpp::TransferFunction can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline TransferFunction::TransferFunction(const std::string &type) { ospObject = ospNewTransferFunction(type.c_str()); } inline TransferFunction::TransferFunction(OSPTransferFunction existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::TransferFunction, OSP_TRANSFER_FUNCTION); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/Volume.h000066400000000000000000000014171464752671100253520ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "ManagedObject.h" namespace ospray { namespace cpp { class Volume : public ManagedObject { public: Volume(const std::string &type); Volume(OSPVolume existing = nullptr); }; static_assert(sizeof(Volume) == sizeof(OSPVolume), "cpp::Volume can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline Volume::Volume(const std::string &type) { ospObject = ospNewVolume(type.c_str()); } inline Volume::Volume(OSPVolume existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::Volume, OSP_VOLUME); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/VolumetricModel.h000066400000000000000000000020531464752671100272120ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "TransferFunction.h" #include "Volume.h" namespace ospray { namespace cpp { class VolumetricModel : public ManagedObject { public: VolumetricModel(const Volume &); VolumetricModel(OSPVolume); VolumetricModel(OSPVolumetricModel existing = nullptr); }; static_assert(sizeof(VolumetricModel) == sizeof(OSPVolumetricModel), "cpp::VolumetricModel can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline VolumetricModel::VolumetricModel(const Volume &vol) : VolumetricModel(vol.handle()) {} inline VolumetricModel::VolumetricModel(OSPVolume vol) { ospObject = ospNewVolumetricModel(vol); } inline VolumetricModel::VolumetricModel(OSPVolumetricModel existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::VolumetricModel, OSP_VOLUMETRIC_MODEL); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/World.h000066400000000000000000000012751464752671100251740ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "Instance.h" #include "ManagedObject.h" namespace ospray { namespace cpp { class World : public ManagedObject { public: World(); World(OSPWorld existing); }; static_assert( sizeof(World) == sizeof(OSPWorld), "cpp::World can't have data members!"); // Inlined function definitions /////////////////////////////////////////// inline World::World() { ospObject = ospNewWorld(); } inline World::World(OSPWorld existing) : ManagedObject(existing) {} } // namespace cpp OSPTYPEFOR_SPECIALIZATION(cpp::World, OSP_WORLD); } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/ext/000077500000000000000000000000001464752671100245275ustar00rootroot00000000000000RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/ext/glm.h000066400000000000000000000027461464752671100254700ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // glm #include "glm/vec2.hpp" #include "glm/vec3.hpp" #include "glm/vec4.hpp" #include "glm/mat2x2.hpp" #include "glm/mat3x2.hpp" #include "glm/mat3x3.hpp" #include "glm/mat4x3.hpp" // ospray #include "../Traits.h" namespace ospray { OSPTYPEFOR_SPECIALIZATION(glm::vec2, OSP_VEC2F); OSPTYPEFOR_SPECIALIZATION(glm::vec3, OSP_VEC3F); OSPTYPEFOR_SPECIALIZATION(glm::vec4, OSP_VEC4F); OSPTYPEFOR_SPECIALIZATION(glm::ivec2, OSP_VEC2I); OSPTYPEFOR_SPECIALIZATION(glm::ivec3, OSP_VEC3I); OSPTYPEFOR_SPECIALIZATION(glm::ivec4, OSP_VEC4I); OSPTYPEFOR_SPECIALIZATION(glm::uvec2, OSP_VEC2UI); OSPTYPEFOR_SPECIALIZATION(glm::uvec3, OSP_VEC3UI); OSPTYPEFOR_SPECIALIZATION(glm::uvec4, OSP_VEC4UI); OSPTYPEFOR_SPECIALIZATION(glm::mat2x2, OSP_LINEAR2F); OSPTYPEFOR_SPECIALIZATION(glm::mat3x3, OSP_LINEAR3F); OSPTYPEFOR_SPECIALIZATION(glm::mat3x2, OSP_AFFINE2F); OSPTYPEFOR_SPECIALIZATION(glm::mat4x3, OSP_AFFINE3F); #ifdef OSPRAY_GLM_DEFINITIONS OSPTYPEFOR_DEFINITION(glm::vec2); OSPTYPEFOR_DEFINITION(glm::vec3); OSPTYPEFOR_DEFINITION(glm::vec4); OSPTYPEFOR_DEFINITION(glm::ivec2); OSPTYPEFOR_DEFINITION(glm::ivec3); OSPTYPEFOR_DEFINITION(glm::ivec4); OSPTYPEFOR_DEFINITION(glm::uvec2); OSPTYPEFOR_DEFINITION(glm::uvec3); OSPTYPEFOR_DEFINITION(glm::uvec4); OSPTYPEFOR_DEFINITION(glm::mat2x2); OSPTYPEFOR_DEFINITION(glm::mat3x3); OSPTYPEFOR_DEFINITION(glm::mat3x2); OSPTYPEFOR_DEFINITION(glm::mat4x3); #endif } // namespace ospray RenderKit-ospray-85af292/ospray/include/ospray/ospray_cpp/ext/rkcommon.h000066400000000000000000000115451464752671100265330ustar00rootroot00000000000000// Copyright 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once // rkcommon #include "rkcommon/math/AffineSpace.h" #include "rkcommon/math/box.h" // ospray #include "../Traits.h" namespace ospray { OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2uc, OSP_VEC2UC); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3uc, OSP_VEC3UC); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4uc, OSP_VEC4UC); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2c, OSP_VEC2C); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3c, OSP_VEC3C); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4c, OSP_VEC4C); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2us, OSP_VEC2US); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3us, OSP_VEC3US); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4us, OSP_VEC4US); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2s, OSP_VEC2S); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3s, OSP_VEC3S); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4s, OSP_VEC4S); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2i, OSP_VEC2I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3i, OSP_VEC3I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4i, OSP_VEC4I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2ui, OSP_VEC2UI); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3ui, OSP_VEC3UI); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4ui, OSP_VEC4UI); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2l, OSP_VEC2L); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3l, OSP_VEC3L); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4l, OSP_VEC4L); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2ul, OSP_VEC2UL); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3ul, OSP_VEC3UL); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4ul, OSP_VEC4UL); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2f, OSP_VEC2F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3f, OSP_VEC3F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4f, OSP_VEC4F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec2d, OSP_VEC2D); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec3d, OSP_VEC3D); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::vec4d, OSP_VEC4D); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box1i, OSP_BOX1I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box2i, OSP_BOX2I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box3i, OSP_BOX3I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box4i, OSP_BOX4I); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box1f, OSP_BOX1F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box2f, OSP_BOX2F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box3f, OSP_BOX3F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::box4f, OSP_BOX4F); 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); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3uc); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4uc); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2c); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3c); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4c); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2us); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3us); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4us); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2s); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3s); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4s); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2i); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3i); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4i); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2ui); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3ui); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4ui); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2l); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3l); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4l); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2ul); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3ul); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4ul); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2f); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3f); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4f); OSPTYPEFOR_DEFINITION(rkcommon::math::vec2d); OSPTYPEFOR_DEFINITION(rkcommon::math::vec3d); OSPTYPEFOR_DEFINITION(rkcommon::math::vec4d); OSPTYPEFOR_DEFINITION(rkcommon::math::box1i); OSPTYPEFOR_DEFINITION(rkcommon::math::box2i); OSPTYPEFOR_DEFINITION(rkcommon::math::box3i); OSPTYPEFOR_DEFINITION(rkcommon::math::box4i); OSPTYPEFOR_DEFINITION(rkcommon::math::box1f); OSPTYPEFOR_DEFINITION(rkcommon::math::box2f); OSPTYPEFOR_DEFINITION(rkcommon::math::box3f); OSPTYPEFOR_DEFINITION(rkcommon::math::box4f); 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 RenderKit-ospray-85af292/ospray/include/ospray/ospray_util.h000066400000000000000000000065421464752671100243020ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ospray.h" #ifdef __cplusplus extern "C" { #endif // OSPData helpers ////////////////////////////////////////////////////////// OSPRAY_INTERFACE OSPData ospNewSharedData1D( const void *sharedData, OSPDataType, uint64_t numItems); OSPRAY_INTERFACE OSPData ospNewAssignedData1D(const void *sharedData, OSPDataType, uint64_t numItems, OSPDeleterCallback, const void *userPtr); OSPRAY_INTERFACE OSPData ospNewSharedData1DStride( const void *sharedData, OSPDataType, uint64_t numItems, int64_t byteStride); OSPRAY_INTERFACE OSPData ospNewSharedData2D(const void *sharedData, OSPDataType, uint64_t numItems1, uint64_t numItems2); OSPRAY_INTERFACE OSPData ospNewSharedData2DStride(const void *sharedData, OSPDataType, uint64_t numItems1, int64_t byteStride1, uint64_t numItems2, int64_t byteStride2); OSPRAY_INTERFACE OSPData ospNewSharedData3D(const void *sharedData, OSPDataType, uint64_t numItems1, uint64_t numItems2, uint64_t numItems3); OSPRAY_INTERFACE OSPData ospNewData1D(OSPDataType, uint64_t numItems); OSPRAY_INTERFACE OSPData ospNewData2D( OSPDataType, uint64_t numItems1, uint64_t numItems2); OSPRAY_INTERFACE void ospCopyData1D( const OSPData source, OSPData destination, uint64_t destinationIndex); OSPRAY_INTERFACE void ospCopyData2D(const OSPData source, OSPData destination, uint64_t destinationIndex1, uint64_t destinationIndex2); // Parameter helpers ////////////////////////////////////////////////////////// OSPRAY_INTERFACE void ospSetString(OSPObject, const char *n, const char *s); OSPRAY_INTERFACE void ospSetObject(OSPObject, const char *n, OSPObject obj); OSPRAY_INTERFACE void ospSetBool(OSPObject, const char *n, int x); OSPRAY_INTERFACE void ospSetFloat(OSPObject, const char *n, float x); OSPRAY_INTERFACE void ospSetInt(OSPObject, const char *n, int x); OSPRAY_INTERFACE void ospSetUInt(OSPObject, const char *n, unsigned int x); OSPRAY_INTERFACE void ospSetBox1f(OSPObject, const char *n, float x, float y); // clang-format off OSPRAY_INTERFACE void ospSetLinear2f(OSPObject, const char *n, float x, float y, float z, float w); OSPRAY_INTERFACE void ospSetVec2f(OSPObject, const char *n, float x, float y); OSPRAY_INTERFACE void ospSetVec3f(OSPObject, const char *n, float x, float y, float z); OSPRAY_INTERFACE void ospSetVec4f(OSPObject, const char *n, float x, float y, float z, float w); OSPRAY_INTERFACE void ospSetVec2i(OSPObject, const char *n, int x, int y); OSPRAY_INTERFACE void ospSetVec3i(OSPObject, const char *n, int x, int y, int z); OSPRAY_INTERFACE void ospSetVec4i(OSPObject, const char *n, int x, int y, int z, int w); // Take 'obj' and put it in an opaque OSPData array with given element type, then set on 'target' OSPRAY_INTERFACE void ospSetObjectAsData(OSPObject target, const char *n, OSPDataType, OSPObject obj); // clang-format on // Rendering helpers ////////////////////////////////////////////////////////// // Start a frame task and immediately wait on it, return frame buffer variance OSPRAY_INTERFACE float ospRenderFrameBlocking( OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld); #ifdef __cplusplus } // extern "C" #endif RenderKit-ospray-85af292/ospray/ospray.rc000066400000000000000000000036201464752671100204540ustar00rootroot00000000000000ÿþ// Copyright 2016 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ospray/version.h" 1 VERSIONINFO FILEVERSION OSPRAY_VERSION_MAJOR,OSPRAY_VERSION_MINOR,OSPRAY_VERSION_PATCH,0 PRODUCTVERSION OSPRAY_VERSION_MAJOR,OSPRAY_VERSION_MINOR,OSPRAY_VERSION_PATCH,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Intel" VALUE "FileDescription", "OSPRay Ray Tracing Rendering Engine" VALUE "FileVersion", OSPRAY_VERSION VALUE "ProductVersion", OSPRAY_VERSION VALUE "LegalCopyright", "© 2009 Intel Corporation" VALUE "InternalName", "OSPRay" VALUE "ProductName", "Intel® OSPRay" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END RenderKit-ospray-85af292/ospray/version.h.in000066400000000000000000000006541464752671100210600ustar00rootroot00000000000000// Copyright 2009 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #define OSPRAY_VERSION_MAJOR @OSPRAY_VERSION_MAJOR@ #define OSPRAY_VERSION_MINOR @OSPRAY_VERSION_MINOR@ #define OSPRAY_VERSION_PATCH @OSPRAY_VERSION_PATCH@ #define OSPRAY_SOVERSION @OSPRAY_SOVERSION@ #define OSPRAY_VERSION_GITHASH "@OSPRAY_VERSION_GITHASH@" #define OSPRAY_VERSION_NOTE "@OSPRAY_VERSION_NOTE@" #define OSPRAY_VERSION "@OSPRAY_VERSION@" RenderKit-ospray-85af292/scripts/000077500000000000000000000000001464752671100167625ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/build/000077500000000000000000000000001464752671100200615ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/build/linux.sh000077500000000000000000000003541464752671100215610ustar00rootroot00000000000000#!/usr/bin/env bash ## Copyright 2015 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set -ex mkdir build cd build cmake --version cmake -L \ -D CMAKE_INSTALL_LIBDIR=lib \ "$@" \ ../scripts/superbuild cmake --build . RenderKit-ospray-85af292/scripts/build/macosx.sh000077700000000000000000000000001464752671100233752linux.shustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/build/win.ps1000077500000000000000000000007661464752671100213170ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 Param( [string] $G = 'Ninja', [ValidateSet('Release', 'RelWithDebInfo', 'Debug')][string] $buildType = 'Release' ) md build cd build cmake --version $exitCode = 0 cmake -L ` -G $G ` $args ` -D CMAKE_BUILD_TYPE=$buildType ` -D DEPENDENCIES_BUILD_TYPE=$buildType ` ../scripts/superbuild if ($LastExitCode) { $exitCode++ } cmake --build . --config $buildType if ($LastExitCode) { $exitCode++ } exit $exitCode RenderKit-ospray-85af292/scripts/files-to-md5.sh000077500000000000000000000030301464752671100215220ustar00rootroot00000000000000#!/bin/bash ## Copyright 2017 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # This script should be called from build directory (OSPRay root should be in ../) # # Usage: # export BASELINE_OUTPUT_DIR=user@machine-name:/target/path # export BASELINE_MD5_OUTPUT_DIR=/dir/with/md5/hashes # export BASELINE_INPUT_IMAGES_DIR=/dir/with/files/to/be/synced # ../scripts/files-to-md5.sh md5 () { md5sum $1 | awk '{print $1 }' } if [[ ! $BASELINE_OUTPUT_DIR ]] then echo "Please set BASELINE_OUTPUT_DIR env variable" exit 1 fi if [[ ! $BASELINE_MD5_OUTPUT_DIR ]] then echo "Please set BASELINE_MD5_OUTPUT_DIR env variable" exit 1 fi if [[ ! $BASELINE_INPUT_IMAGES_DIR ]] then echo "Please set BASELINE_INPUT_IMAGES_DIR env variable" exit 1 fi LOCAL_TMP_DIR=/tmp/ospray-tmp-data # Remove any old files (whole directory) rm -rf $LOCAL_TMP_DIR # Create this directory again mkdir $LOCAL_TMP_DIR # From now on any command should stop executing script set -e for FILE in $BASELINE_INPUT_IMAGES_DIR/*; do # Copy file to local tmp directory with new name (based on md5 from this img) cp $FILE $LOCAL_TMP_DIR/`md5 $FILE` # Create/Fill metadata file in ospray repo # so we can link img in remote repo by this md5 string md5 $FILE > $BASELINE_MD5_OUTPUT_DIR/`basename $FILE`.md5 done # Copy all files (only when there is need to update) to target CI machine rsync --progress -au --no-o --no-g $LOCAL_TMP_DIR/* $BASELINE_OUTPUT_DIR # Another cleanup - we don't want to leave any files locally rm -rf $LOCAL_TMP_DIR/* RenderKit-ospray-85af292/scripts/install_linux_gcc.sh000077500000000000000000000023441464752671100230250ustar00rootroot00000000000000#!/bin/bash ## Copyright 2014 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 dest=$HOME/devtools-2 arch=`arch` major=`rpm -q --qf "%{VERSION}" $(rpm -q --whatprovides redhat-release)` source_url=http://people.centos.org/tru/devtools-2/$major/$arch/RPMS usr_path="$HOME/devtools-2/opt/rh/devtoolset-2/root/usr" packages="\ devtoolset-2-binutils \ devtoolset-2-gcc \ devtoolset-2-libstdc++-devel \ devtoolset-2-gcc-c++ \ " echo Installing gcc in $dest pushd . > /dev/null mkdir -p $dest cd $dest echo .fetching RPM list wget -cq $source_url/repodata/primary.xml.gz gunzip -c primary.xml.gz > primary.xml for package in $packages ; do echo .looking for $package p=`grep -A 29 "^$package" primary.xml | grep -B 29 '' | sed -e "s@.*.*@\1@;ty;d;:y" | sort -g | tail -n 1` echo ...fetching $p wget -cq $source_url/$p echo ...installing $p rpm2cpio $p | cpio -idu --quiet done popd > /dev/null export PATH="$usr_path/bin":$PATH export LD_LIBRARY_PATH="$usr_path/lib64":$LD_LIBRARY_PATH echo Installation finished. To use gcc of devtoolset-2 be sure to keep \""$usr_path/bin"\" in your \$PATH and \""$usr_path/lib64"\" in your \$LD_LIBRARY_PATH. RenderKit-ospray-85af292/scripts/release/000077500000000000000000000000001464752671100204025ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/release/linux.sh000077500000000000000000000073451464752671100221110ustar00rootroot00000000000000#!/bin/bash ## Copyright 2014 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 #### Helper functions #### function check_symbols { for sym in `nm $1 | grep $2_` do version=(`echo $sym | sed 's/.*@@\(.*\)$/\1/g' | grep -E -o "[0-9]+"`) if [ ${#version[@]} -ne 0 ]; then if [ ${#version[@]} -eq 1 ]; then version[1]=0; fi if [ ${#version[@]} -eq 2 ]; then version[2]=0; fi if [ ${version[0]} -gt $3 ]; then echo "Error: problematic $2 symbol " $sym exit 1 fi if [ ${version[0]} -lt $3 ]; then continue; fi if [ ${version[1]} -gt $4 ]; then echo "Error: problematic $2 symbol " $sym exit 1 fi if [ ${version[1]} -lt $4 ]; then continue; fi if [ ${version[2]} -gt $5 ]; then echo "Error: problematic $2 symbol " $sym exit 1 fi fi done } function check_lib_dependency_error { for lib in "$1" do if [ -n "`ldd $lib | fgrep $2`" ]; then echo "Error: dependency to '$2' found" exit 3 fi done } function get_so_version { local version=`ldd $1 | fgrep $2 | sed "s/.*\.so\.\([0-9\.]\+\).*/\1/"` echo "$version" } #### Set variables for script #### ROOT_DIR=$PWD DEP_DIR=$ROOT_DIR/deps DEP_BUILD_DIR=$ROOT_DIR/build_deps THREADS=`nproc` if [ `uname -m` == aarch64 ]; then GPU=OFF else GPU=ON SYM_TEST=true # FIXME: currently building ARM on Ubuntu fi #### Build dependencies #### mkdir $DEP_BUILD_DIR cd $DEP_BUILD_DIR # NOTE(jda) - Some Linux OSs need to have lib/ on LD_LIBRARY_PATH at build time export LD_LIBRARY_PATH=$DEP_DIR/lib:${LD_LIBRARY_PATH} cmake --version cmake \ "$@" \ -D BUILD_JOBS=$THREADS \ -D BUILD_DEPENDENCIES_ONLY=ON \ -D CMAKE_INSTALL_PREFIX=$DEP_DIR \ -D CMAKE_INSTALL_LIBDIR=lib \ -D BUILD_OSPRAY_MODULE_MPI=ON \ -D BUILD_GPU_SUPPORT=$GPU \ -D INSTALL_IN_SEPARATE_DIRECTORIES=OFF \ ../scripts/superbuild cmake --build . cd $ROOT_DIR #### Build OSPRay #### mkdir -p build_release cd build_release # Clean out build directory to be sure we are doing a fresh build rm -rf * # Setup environment for dependencies export CMAKE_PREFIX_PATH=$DEP_DIR # set release settings cmake -L \ "$@" \ -D TBB_ROOT=$DEP_DIR \ -D OSPRAY_ZIP_MODE=ON \ -D OSPRAY_BUILD_ISA=ALL \ -D OSPRAY_INSTALL_DEPENDENCIES=ON \ -D OSPRAY_MODULE_DENOISER=ON \ -D OSPRAY_MODULE_MPI=ON \ -D OSPRAY_MODULE_GPU=$GPU \ -D CMAKE_INSTALL_INCLUDEDIR=include \ -D CMAKE_INSTALL_LIBDIR=lib \ -D CMAKE_INSTALL_DOCDIR=doc \ -D CMAKE_INSTALL_BINDIR=bin \ -D CMAKE_BUILD_WITH_INSTALL_RPATH=ON \ .. # create tar.gz make -j $THREADS preinstall if [ $SYM_TEST ] ; then # verify libs for lib in libospray.so libospray_module_cpu.so libospray_module_mpi_offload.so libospray_module_mpi_distributed_cpu.so ; do echo "checking $lib..." check_symbols $lib GLIBC 2 28 0 check_symbols $lib GLIBCXX 3 4 22 check_symbols $lib CXXABI 1 3 11 check_lib_dependency_error $lib libimf.so check_lib_dependency_error $lib libsvml.so done for lib in libospray_module_mpi_offload.so libospray_module_mpi_distributed_cpu.so ; do echo "checking $lib..." check_lib_dependency_error $lib libmpifort.so MPICH_ABI_VER=12 mpi_so_ver=$(get_so_version $lib libmpi.so) mpicxx_so_ver=$(get_so_version $lib libmpicxx.so) if [ -z "$mpi_so_ver" ] || [ -z "$mpicxx_so_ver" ]; then echo "MPI module is not linked against libmpi.so or libmpicxx.so" exit 3 fi if [ "$mpi_so_ver" != "$MPICH_ABI_VER" ]; then echo "MPI module is linked against the wrong MPICH ABI: libmpi.so.$mpi_so_ver" exit 3 fi if [ "$mpicxx_so_ver" != "$MPICH_ABI_VER" ]; then echo "MPI module is linked against the wrong MPICH ABI: libmpicxx.so.$mpi_so_ver" exit 3 fi done fi cmake --build . --target package || exit 2 RenderKit-ospray-85af292/scripts/release/macosx.sh000077500000000000000000000033631464752671100222400ustar00rootroot00000000000000#!/bin/bash ## Copyright 2014 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 #### Helper functions #### umask=`umask` function onexit { umask $umask } trap onexit EXIT umask 002 #### Set variables for script #### ROOT_DIR=$PWD DEP_DIR=$ROOT_DIR/deps DEP_BUILD_DIR=$ROOT_DIR/build_deps THREADS=`sysctl -n hw.logicalcpu` # set compiler if the user hasn't explicitly set CC and CXX if [ -z $CC ]; then echo "***NOTE: Defaulting to use clang!" echo -n " Please set env variables 'CC' and 'CXX' to" echo " a different supported compiler (gcc/icc) if desired." export CC=clang export CXX=clang++ fi # to make sure we do not include nor link against wrong TBB unset CPATH unset LIBRARY_PATH unset DYLD_LIBRARY_PATH #### Build dependencies #### mkdir $DEP_BUILD_DIR cd $DEP_BUILD_DIR cmake --version cmake \ "$@" \ -D BUILD_JOBS=$THREADS \ -D BUILD_DEPENDENCIES_ONLY=ON \ -D CMAKE_INSTALL_PREFIX=$DEP_DIR \ -D CMAKE_INSTALL_LIBDIR=lib \ -D INSTALL_IN_SEPARATE_DIRECTORIES=OFF \ ../scripts/superbuild cmake --build . cd $ROOT_DIR #### Build OSPRay #### mkdir -p build_release cd build_release # Clean out build directory to be sure we are doing a fresh build rm -rf * # Setup environment for dependencies export CMAKE_PREFIX_PATH=$DEP_DIR # set release and installer settings cmake -L \ "$@" \ -D OSPRAY_BUILD_ISA=ALL \ -D TBB_ROOT=$DEP_DIR \ -D OSPRAY_ZIP_MODE=ON \ -D OSPRAY_MODULE_DENOISER=ON \ -D OSPRAY_INSTALL_DEPENDENCIES=ON \ -D CMAKE_INSTALL_INCLUDEDIR=include \ -D CMAKE_INSTALL_LIBDIR=lib \ -D CMAKE_INSTALL_DOCDIR=doc \ -D CMAKE_INSTALL_BINDIR=bin \ -D CMAKE_BUILD_WITH_INSTALL_RPATH=ON \ -D CPACK_PRE_BUILD_SCRIPTS=$CPACK_PRE_BUILD_SIGNING_SCRIPT \ .. make -j $THREADS package || exit 2 RenderKit-ospray-85af292/scripts/release/win.ps1000077500000000000000000000043151464752671100216320ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 Param( [string] $G = 'Ninja' ) $ROOT_DIR = pwd $DEP_DIR = "$ROOT_DIR\deps" ## Build dependencies ## mkdir deps_build cd deps_build cmake --version $exitCode = 0 cmake -L ` -G $G ` $args ` -D CMAKE_BUILD_TYPE=Release ` -D DEPENDENCIES_BUILD_TYPE=Release ` -D BUILD_DEPENDENCIES_ONLY=ON ` -D CMAKE_INSTALL_PREFIX=$DEP_DIR ` -D CMAKE_INSTALL_LIBDIR=lib ` -D BUILD_OSPRAY_MODULE_MPI=ON ` -D BUILD_GPU_SUPPORT=ON ` -D INSTALL_IN_SEPARATE_DIRECTORIES=OFF ` ../scripts/superbuild if ($LastExitCode) { $exitCode++ } cmake --build . --config Release if ($LastExitCode) { $exitCode++ } cd $ROOT_DIR #### Build OSPRay #### md build_release cd build_release # Clean out build directory to be sure we are doing a fresh build rm -r -fo * # Setup environment for dependencies $env:CMAKE_PREFIX_PATH = $DEP_DIR if ($G -eq 'Ninja') { $package = 'package' # FIXME WA for OSPRay to build with GNU-style options $cxx_compiler = '-DCMAKE_CXX_COMPILER=clang++' $c_compiler = '-DCMAKE_C_COMPILER=clang' } else { $package = 'PACKAGE' } # set release settings cmake -L ` -G $G ` $args ` $cxx_compiler ` $c_compiler ` -D CMAKE_BUILD_TYPE=Release ` -D USE_STATIC_RUNTIME=OFF ` -D CMAKE_PREFIX_PATH="$DEP_DIR\lib\cmake" ` -D OSPRAY_MODULE_PATH="$ROOT_DIR\deps_build" ` -D TBB_ROOT=$DEP_DIR ` -D OSPRAY_ZIP_MODE=OFF ` -D OSPRAY_BUILD_ISA=ALL ` -D OSPRAY_INSTALL_DEPENDENCIES=ON ` -D OSPRAY_MODULE_DENOISER=ON ` -D OSPRAY_MODULE_MPI=ON ` -D OSPRAY_MODULE_GPU=ON ` -D CMAKE_INSTALL_INCLUDEDIR=include ` -D CMAKE_INSTALL_LIBDIR=lib ` -D CMAKE_INSTALL_DOCDIR=doc ` -D CMAKE_INSTALL_BINDIR=bin ` -D CMAKE_INSTALL_DATAROOTDIR= ` -D OSPRAY_SIGN_FILE=$env:SIGN_FILE_WINDOWS ` .. if ($LastExitCode) { $exitCode++ } # compile and create installers cmake --build . --config Release --target sign_files if ($LastExitCode) { $exitCode++ } cmake --build . --config Release --target $package if ($LastExitCode) { $exitCode++ } # create ZIP files cmake -L ` -D OSPRAY_ZIP_MODE=ON ` .. if ($LastExitCode) { $exitCode++ } cmake --build . --config Release --target $package if ($LastExitCode) { $exitCode++ } exit $exitCode RenderKit-ospray-85af292/scripts/scan/000077500000000000000000000000001464752671100177065ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/scan/bdba.sh000077500000000000000000000043261464752671100211420ustar00rootroot00000000000000#!/bin/bash ## Copyright 2019 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 files=$1 jq_tool="$SHARED_TOOLS_PATH/jq-linux64" logfile="bdba.log" failed=0 for file_path in $files ; do echo -e "\n" >> $logfile #upload file upload_response=`curl -k -H "Authorization: Bearer $BDBA_TOKEN" -H "Group: $BDBA_GROUP" -T $file_path "$BDBA_SERVER/api/upload/"` product_id=`echo "$upload_response" | $jq_tool -r '.results.product_id'` if [ $product_id == "null" ]; then echo "Cannot upload file $file_path" >> $logfile failed=1 continue fi report_url=`echo "$upload_response" | $jq_tool -r '.results.report_url'` echo "Scan upload of $file_path completed - product id: $product_id ($report_url)" >> $logfile set +e MAX_RETRY=600 RETRY_COUNTER="0" while [ $RETRY_COUNTER -lt $MAX_RETRY ]; do response=`curl -s -X GET -H "Authorization: Bearer $BDBA_TOKEN" -k $BDBA_SERVER/api/product/$product_id/` CMD_RETURN_CODE=$? status=`echo "$response" | $jq_tool -r '.results.status'` verdict=`echo "$response" | $jq_tool -r '.results.summary.verdict.short'` if [ $CMD_RETURN_CODE == 0 ] && [[ $status == "R" ]]; then echo $response | python -m json.tool echo "Verdict: $verdict" >> $logfile if [ $verdict != "Pass" ] && [ $verdict != "null" ]; then echo "There is a problem - please check report $report_url" >> $logfile failed=1 fi # Download pdf report & components list file_name=`basename "$file_path"` echo "File name: $file_name" curl -H "Authorization: Bearer $BDBA_TOKEN" -k $BDBA_SERVER/api/product/$product_id/pdf-report?cvss_version=3 -o ${file_name}_report.pdf curl -H "Authorization: Bearer $BDBA_TOKEN" -k $BDBA_SERVER/api/product/$product_id/csv-libs -o ${file_name}_components.csv break fi RETRY_COUNTER=$[$RETRY_COUNTER+1] echo "Scan not finished yet, [$RETRY_COUNTER/$MAX_RETRY] - checking again ... " sleep 20 done set -e if [ $RETRY_COUNTER -ge $MAX_RETRY ]; then failed=62 continue fi done cat $logfile exit $failed RenderKit-ospray-85af292/scripts/scan/kw-check-issues.sh000077500000000000000000000015471464752671100232610ustar00rootroot00000000000000#!/bin/bash -xe ## Copyright 2020 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 KW_ISSUES_FILE=/tmp/issues KW_SERVER_API_URL=http://$KW_SERVER_IP:$KW_SERVER_PORT/review/api KW_BUILD_NAME=$(cat $CI_PROJECT_DIR/klocwork/build_name) echo "Checking for issues in $KW_BUILD_NAME ..." curl -f --data "action=search&project=$KW_PROJECT_NAME&query=build:'$KW_BUILD_NAME'%20status:Analyze,Fix,Fix%20in%20Next%20Release,Fix%20in%20Later%20Release,Defer,Filter&user=$KW_USER<oken=$KW_LTOKEN" $KW_SERVER_API_URL -o $KW_ISSUES_FILE getCriticalCount() { cat $KW_ISSUES_FILE | wc -l } if [ -f $KW_ISSUES_FILE ]; then echo "Issues found - $(getCriticalCount) in $KW_BUILD_NAME"; while IFS= read -r line; do echo $line | python -m json.tool; done < $KW_ISSUES_FILE exit 1; else echo "There are no issues which should be take care in $KW_BUILD_NAME" fi RenderKit-ospray-85af292/scripts/scan/kw-gen-report.sh000077500000000000000000000033251464752671100227510ustar00rootroot00000000000000#!/bin/bash -xe ## Copyright 2020 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 KW_SERVER_API_URL=http://$KW_SERVER_IP:$KW_SERVER_PORT/review/api KW_BUILD_NAME=$(cat $CI_PROJECT_DIR/klocwork/build_name) KW_BUILD_LOG_FILE=$CI_PROJECT_DIR/klocwork/build.log export PATH="$SHARED_TOOLS_PATH:$PATH" [ -f $KW_BUILD_LOG_FILE ] || (echo "Build log file not found. Expected to be in: $KW_BUILD_LOG_FILE." ; exit 1;) mkdir -p $CI_PROJECT_DIR/klocwork report_file=$CI_PROJECT_DIR/klocwork/report.log echo "------------------" >> $report_file echo "Report generated at: "$(date '+%d/%m/%Y %H:%M:%S') >> $report_file echo "Project source code url: $CI_PROJECT_URL" >> $report_file echo "Project source code sha: $CI_COMMIT_SHA" >> $report_file echo "Klocwork server: http://$KW_SERVER_IP:$KW_SERVER_PORT" >> $report_file echo "------------------" >> $report_file echo -e "\n\n\n" >> $report_file # Get all issues list and put to report file column_list=".id, .code, .severity, .state, .status, .taxonomyName, .owner, .url, .file, .line" echo "------------------" >> $report_file echo "Issues list:" >> $report_file echo "------------------" >> $report_file echo $column_list | sed 's/\\t/ ,/g' | column -t -s, >> $report_file echo "------------------" >> $report_file curl -f --data "action=search&project=$KW_PROJECT_NAME&query=build:'$KW_BUILD_NAME'&user=$KW_USER<oken=$KW_LTOKEN" $KW_SERVER_API_URL | jq-linux64 "[${column_list}] | @tsv" | sed 's/\\t/|/g' | column -t -s'|' | cut -d'"' -f2 >> $report_file echo -e "\n\n\n" >> $report_file # Attach build log to report file echo "------------------" >> $report_file echo "Build & scan log:" >> $report_file echo "------------------" >> $report_file cat $KW_BUILD_LOG_FILE >> $report_file RenderKit-ospray-85af292/scripts/scan/store-files.sh000077500000000000000000000003741464752671100225050ustar00rootroot00000000000000#!/bin/bash -xe ## Copyright 2019 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 project_name=$1 build_id=$2 group_name=$3 files=$4 STORAGE_DIR=$STORAGE_PATH/$project_name/$build_id/$group_name/ mkdir -p $STORAGE_DIR cp $files $STORAGE_DIR/ RenderKit-ospray-85af292/scripts/superbuild/000077500000000000000000000000001464752671100211405ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/superbuild/CMakeLists.txt000066400000000000000000000260501464752671100237030ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ## Global settings ## cmake_minimum_required(VERSION 3.7) set(CMAKE_INSTALL_MESSAGE LAZY) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies) if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING "Final install location." FORCE) endif() if (NOT CMAKE_BUILD_TYPE) 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) endif() ## Establish project ## project(OSPRay_superbuild) if(CMAKE_SIZEOF_VOID_P EQUAL 4) message(FATAL_ERROR "OSPRay can only be built on 64-bit platforms. This problem most commonly happens on Windows, where the right solution is to switch to a 64-bit generator: retry running CMake with '-G \"Visual Studio 15 2017 Win64\"'") else() message(STATUS "Proceeding with a 64-bit generator. (${CMAKE_SIZEOF_VOID_P})") endif() if (POLICY CMP0114) # allow old CMake behavior: NO_DEPENDS for ExternalProject_Add_StepTargets cmake_policy(SET CMP0114 OLD) # 3.19 endif () if (POLICY CMP0135) # use timestamp of extraction of downloaded archives cmake_policy(SET CMP0135 NEW) # 3.24 endif () include(ExternalProject) include(GNUInstallDirs) include(ProcessorCount) include(CMakeDependentOption) ## Superbuild options ## ProcessorCount(PROCESSOR_COUNT) if(NOT PROCESSOR_COUNT EQUAL 0) set(BUILD_JOBS ${PROCESSOR_COUNT} CACHE STRING "Number of build jobs '-j '") else() set(BUILD_JOBS 4 CACHE STRING "Number of build jobs '-j '") endif() option(ALWAYS_REBUILD "Force every project to always be rebuilt?" OFF) option(INSTALL_IN_SEPARATE_DIRECTORIES "Install libraries into their own directories under CMAKE_INSTALL_PREFIX" ON ) option(INSTALL_DEPENDENCIES "Install OSPRay dependencies" ON) if (APPLE) set(BUILD_GPU_SUPPORT OFF) else() option(BUILD_GPU_SUPPORT "Enable beta GPU support and building module_gpu" OFF) endif() option(DOWNLOAD_ISPC "Download ISPC or use the one found in the system environment?" ON) if (DOWNLOAD_ISPC) set(ISPC_VERSION "1.24.0" CACHE STRING "Which version of ISPC to download?") mark_as_advanced(CLEAR ISPC_VERSION) if (ISPC_VERSION STREQUAL "1.24.0") if (APPLE) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(ISPC_HASH "7f3891d0157aed3cab159fbc5235235b62797053db9387f5a61c8d0a22369ae0") else() set(ISPC_HASH "986eb172fe9db3e8da560e9d0d788832991638fab61ca80587d87eb175ffb520") endif() elseif (WIN32) set(ISPC_HASH "a7c21cb2434f5364acbdf0933af6de49198458ed6f0b62012e03c3325c972649") else() if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(ISPC_HASH "890ad5f31581091bf4ae9f235a7bb6fd9cabcbd6cf1670104ad61f1ad2da4c76") else() set(ISPC_HASH "79885d4482356dba7c01da312b6449fd575b097845ebcb90344dac5c178b43f5") endif() endif() endif() else() mark_as_advanced(FORCE ISPC_VERSION) endif() set(RKCOMMON_VERSION "1.14.0" CACHE STRING "Which version of rkcommon to build?") if (RKCOMMON_VERSION STREQUAL "1.14.0") set(RKCOMMON_HASH "5aef75afc8d4fccf9e70df4cbdf29a1b28b39ee51b5588b94b83a14c6a166d83") endif() option(DOWNLOAD_TBB "Download TBB or use the one found in the system environment?" ON) if (DOWNLOAD_TBB) set(TBB_VERSION "2021.13.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.13.0") if (BUILD_TBB_FROM_SOURCE) set(TBB_HASH "3ad5dd08954b39d113dc5b3f8a8dc6dc1fd5250032b7c491eb07aed5c94133e1") else() if (APPLE) set(TBB_HASH "e9aa143de91f65ea15b62ceeba5845bbc914c882d32bf9c9a405e6b8b5a70ade") elseif (WIN32) set(TBB_HASH "0a7b19b52ec9d8eaa10cbbe396e955130815489c544642acecda8ef8d2d7f64d") else() set(TBB_HASH "f5c9304710051f0193a07fb91b6d6ada5a3e0a6d623951ee176b1897816ecf4c") endif() endif() endif() else() mark_as_advanced(FORCE TBB_VERSION) mark_as_advanced(FORCE BUILD_TBB_FROM_SOURCE) endif() option(BUILD_EMBREE_FROM_SOURCE "Build Embree or use pre-built version?" OFF) set(EMBREE_VERSION "4.3.3" CACHE STRING "Which version of Embree to build?") if (EMBREE_VERSION STREQUAL "4.3.3") if (BUILD_EMBREE_FROM_SOURCE) set(EMBREE_HASH "8a3bc3c3e21aa209d9861a28f8ba93b2f82ed0dc93341dddac09f1f03c36ef2d") else() if (APPLE) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(EMBREE_HASH "ee310bcd8480ed82f2be29289b9a811c83db6a36160c8afdcb61bb4de4d337df") else() set(EMBREE_HASH "98997523dfff8efd8120075f7feba00cfc765c992d758d9be12d56bfe6bec233") endif() elseif (WIN32) set(EMBREE_HASH "d4c07f88df9f009dd84e4e9b9dcec32ad7d96f927bd88de00b721b0923d481a9") set(EMBREE_SYCL_HASH "1675fd6907e4697400ce58942343fdf99fc4e6f0fa0b259d61755ae72aa9aa18") else() set(EMBREE_HASH "757e6e8b987d13ac34aa7c4c3657120fd54a78c2a1034e30dda5cd5df06f3cdd") set(EMBREE_SYCL_HASH "9952f9f8fe103449e18084c8bd822a7e3130844c54abfd164f1ce36e46b92572") endif() endif() endif() option(BUILD_OPENVKL "Build Open VKL as a part of the superbuild." ON) if (BUILD_OPENVKL) set(OPENVKL_VERSION "2.0.1" CACHE STRING "Which version of OpenVKL to build?") mark_as_advanced(CLEAR OPENVKL_VERSION) # XXX need to build VKL from source when installing in single directory, # otherwise its packaged, stale Embree will overwrite the already installed # new Embree cmake_dependent_option( BUILD_OPENVKL_FROM_SOURCE "Build OpenVKL or use pre-built version?" OFF "INSTALL_IN_SEPARATE_DIRECTORIES OR NOT INSTALL_DEPENDENCIES" ON ) mark_as_advanced(CLEAR BUILD_OPENVKL_FROM_SOURCE) if (OPENVKL_VERSION STREQUAL "2.0.1") if (BUILD_OPENVKL_FROM_SOURCE) set(OPENVKL_HASH "6676f2171f9d61844ef2a417df79275226026bc4210a4afc61da2160ecaaf5ed") else() if (APPLE) set(OPENVKL_HASH "b04ab7a3376334ec6cf58014e41052d6d1d07cbd49c02f9a0f461849b79a0f45") elseif(WIN32) set(OPENVKL_HASH "634500d449e80da324e317d78abb5c6a634ae8c3d8b049261d49c49e1e8c7daa") else() set(OPENVKL_HASH "74939c835ec533c9de7af975e5cd0ee6db74a748388d89c915e3a08ebf274ad0") endif() endif() endif() else() mark_as_advanced(FORCE OPENVKL_VERSION) mark_as_advanced(FORCE BUILD_OPENVKL_FROM_SOURCE) endif() option(BUILD_OIDN "Build OpenImageDenoise as a part of the superbuild." ON) if (BUILD_OIDN) set(OIDN_VERSION "2.3.0" 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 "2.3.0") if (BUILD_OIDN_FROM_SOURCE) set(OIDN_HASH "cce3010962ec84e0ba1acd8c9055a3d8de402fedb1b463517cfeb920a276e427") else() if (APPLE) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(OIDN_HASH "9dc42edba6461082e940c8c8cf19e6528d3d40f7f45c695fab33671b39414627") else() set(OIDN_HASH "8b3285d2d8c431c061a2cf0c5bf90fd519b5ad5fb6db828b07dc6662daa9e07b") endif() elseif (WIN32) set(OIDN_HASH "272781c9398eec7aeef9cd1be5b5aad7bb3debfc574308ce930b8e55ee51effd") else() set(OIDN_HASH "02693c3eb3888eeb0c59c9bb1142b28b899ac8dd02bad4397beaffb5f8bef863") endif() endif() endif() else() mark_as_advanced(FORCE OIDN_VERSION) mark_as_advanced(FORCE BUILD_OIDN_FROM_SOURCE) endif() option(BUILD_GLFW "Build glfw for OSPRay examples or use one in existing environment?" ON) option(BUILD_DEPENDENCIES_ONLY "Don't build OSPRay itself, only its dependencies" OFF) option(BUILD_OSPRAY_CI_EXTRAS "Enable OSPRay's extra compiler checks." OFF) option(BUILD_OSPRAY_APPS "Enable building OSPRay apps" ON) option(BUILD_OSPRAY_MODULE_MPI "Enable building module_mpi" OFF) option(BUILD_OSPRAY_MODULE_MULTIDEVICE "Enable building module_multidevice" OFF) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(ISA_X86 OFF) if (APPLE) set(ISA_NEON OFF) set(ISA_NEON2X ON) else() set(ISA_NEON ON) set(ISA_NEON2X OFF) endif() else() set(ISA_X86 ON) set(ISA_NEON OFF) set(ISA_NEON2X OFF) endif() option(BUILD_ISA_SSE4 "Build for SSE4" ${ISA_X86}) mark_as_advanced(BUILD_ISA_SSE4) option(BUILD_ISA_AVX "Build for AVX" ${ISA_X86}) mark_as_advanced(BUILD_ISA_AVX) option(BUILD_ISA_AVX2 "Build for AVX2" ${ISA_X86}) mark_as_advanced(BUILD_ISA_AVX2) option(BUILD_ISA_AVX512 "Build for AVX512" ${ISA_X86}) mark_as_advanced(BUILD_ISA_AVX512) option(BUILD_ISA_NEON "Build for NEON" ${ISA_NEON}) mark_as_advanced(BUILD_ISA_NEON) option(BUILD_ISA_NEON2X "Build for double pumped NEON" ${ISA_NEON2X}) mark_as_advanced(BUILD_ISA_NEON2X) if (BUILD_ISA_NEON AND BUILD_ISA_NEON2X) message(FATAL_ERROR "Only one Neon ISA may be enabled; choose either NEON or NEON2X") endif() ## Setup top-level variables ## set(installDir ${CMAKE_INSTALL_PREFIX}) get_filename_component(INSTALL_DIR_ABSOLUTE ${installDir} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) if (${CMAKE_VERSION} VERSION_GREATER 3.11.4) set(PARALLEL_JOBS_OPTS -j ${BUILD_JOBS}) endif() ## Build dependencies ## set(DEFAULT_BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${DEPENDENCIES_BUILD_TYPE} ${PARALLEL_JOBS_OPTS}) if (DOWNLOAD_ISPC) include(dep_ispc) endif() if (DOWNLOAD_TBB) include(dep_tbb) endif() include(dep_rkcommon) if (BUILD_GLFW) include(dep_glfw) endif() if (BUILD_OIDN) include(dep_oidn) endif() include(dep_glm) if (BUILD_OSPRAY_APPS) include(dep_gtest) include(dep_benchmark) endif() if (BUILD_OSPRAY_MODULE_MPI) set(OSPRAY_MODULE_MPI ON) include(dep_snappy) endif() ##### FIXME WA for Embree, VKL and OSPRay to build with GNU-style options if (WIN32 AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) # remember CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS before switching to GNU-style # frontend, which won't look for MSVCRT anymore set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE) include(InstallRequiredSystemLibraries) file(CONFIGURE OUTPUT ospray_system_runtime.cmake CONTENT "set(OSPRAY_INSTALL_SYSTEM_RUNTIME_LIBS \"@CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS@\")" @ONLY NEWLINE_STYLE WIN32) set(CMAKE_C_COMPILER clang) set(CMAKE_CXX_COMPILER clang++) endif() include(dep_embree) if (BUILD_OPENVKL) include(dep_openvkl) endif() ## Build main projects ## set(DEFAULT_BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE} ${PARALLEL_JOBS_OPTS}) if (NOT BUILD_DEPENDENCIES_ONLY) include(build_ospray.cmake) endif() RenderKit-ospray-85af292/scripts/superbuild/README.md000066400000000000000000000065361464752671100224310ustar00rootroot00000000000000## CMake Superbuild For convenience, OSPRay provides a CMake Superbuild script which will pull down OSPRay’s dependencies and build OSPRay itself. By default, the result is an install directory, with each dependency in its own directory. Run with: ```sh mkdir build cd build cmake [/scripts/superbuild] cmake --build . ``` On Windows make sure to select a 64\ bit generator, e.g. ```sh cmake -G "Visual Studio 17 2022" [/scripts/superbuild] ``` The resulting `install` directory (or the one set with `CMAKE_INSTALL_PREFIX`) will have everything in it, with one subdirectory per dependency. CMake options to note (all have sensible defaults): CMAKE_INSTALL_PREFIX : will be the root directory where everything gets installed. BUILD_JOBS : sets the number given to `make -j` for parallel builds. INSTALL_IN_SEPARATE_DIRECTORIES : toggles installation of all libraries in separate or the same directory. BUILD_OPENVKL : whether to enable volume rendering via Open VKL BUILD_EMBREE_FROM_SOURCE : set to OFF will download a pre-built version of Embree. BUILD_OIDN_FROM_SOURCE : set to OFF will download a pre-built version of Open Image Denoise. OIDN_VERSION : determines which version of Open Image Denoise to pull down. BUILD_OSPRAY_MODULE_MPI : set to ON to build OSPRay’s MPI module for data-replicated and distributed parallel rendering on multiple nodes. BUILD_GPU_SUPPORT : enables beta GPU support, fetching the SYCL variants of the dependencies and builds `OSPRAY_MODULE_GPU` BUILD_TBB_FROM_SOURCE : set to ON to build TBB from source (required for ARM support). The default setting is OFF. For the full set of options, run: ```sh ccmake [/scripts/superbuild] ``` or ```sh cmake-gui [/scripts/superbuild] ``` ### Cross-Compilation with the Superbuild The superbuild can be passed a [CMake Toolchain file](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html) to configure for cross-compilation. This is done by passing the toolchain file when running cmake. When cross compiling it is also likely that you’ll want to build TBB and Embree from source to ensure they’re built for the correct target, rather than the target the Github binaries are built for. It may also be necessary to disable specific ISAs for the target by passing `BUILD_ISA_=OFF` as well. ```sh mkdir build cd build cmake --toolchain [toolchain_file.cmake] [path/to/this/directory] -DBUILD_TBB_FROM_SOURCE=ON \ -DBUILD_EMBREE_FROM_SOURCE=ON \ ``` While OSPRay supports ARM natively, it may be desirable to cross-compile it for `x86_64` to run in Rosetta depending on the application integrating OSPRay. This can be done using the toolchain file `toolchains/macos-rosetta.cmake`, and by disabling all non-SSE ISAs when building. This can also be done by launching an `x86_64` bash shell and then compiling as usual in this environment, which will cause the compilation chain to target `x86_64`. The `BUILD_ISA_=OFF` flags should be passed to disable all ISAs besides SSE4 for Rosetta: ```sh arch -x86_64 bash mkdir build cd build cmake [path/to/this/directory] -DBUILD_TBB_FROM_SOURCE=ON \ -DBUILD_EMBREE_FROM_SOURCE=ON \ -DBUILD_ISA_AVX=OFF \ -DBUILD_ISA_AVX2=OFF \ -DBUILD_ISA_AVX512=OFF \ ``` RenderKit-ospray-85af292/scripts/superbuild/build_ospray.cmake000066400000000000000000000050521464752671100246400ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME ospray) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (NOT DEFINED BUILD_OSPRAY_GLM) set(BUILD_OSPRAY_GLM ${BUILD_OSPRAY_APPS}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_COMMAND "" STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../.. BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | # Use the alternate list separator CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} -DOSPRAY_ENABLE_APPS=${BUILD_OSPRAY_APPS} -DOSPRAY_APPS_ENABLE_GLM=${BUILD_OSPRAY_GLM} -DOSPRAY_BUILD_ISA=ALL -DOSPRAY_ENABLE_VOLUMES=${BUILD_OPENVKL} -DOSPRAY_MODULE_BILINEAR_PATCH=${BUILD_OSPRAY_CI_EXTRAS} -DOSPRAY_MODULE_DENOISER=${BUILD_OIDN} -DOSPRAY_INSTALL_DEPENDENCIES=${INSTALL_DEPENDENCIES} -DOSPRAY_STRICT_BUILD=${BUILD_OSPRAY_CI_EXTRAS} -DOSPRAY_WARN_AS_ERRORS=${BUILD_OSPRAY_CI_EXTRAS} -DOSPRAY_MODULE_MPI=${BUILD_OSPRAY_MODULE_MPI} -DOSPRAY_MODULE_GPU=${BUILD_GPU_SUPPORT} -DOSPRAY_MODULE_MULTIDEVICE=${BUILD_OSPRAY_MODULE_MULTIDEVICE} $<$:-DRKCOMMON_TBB_ROOT=${TBB_PATH}> $<$:-DISPC_EXECUTABLE=${ISPC_PATH}> -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -DOSPRAY_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR} # FIXME WA for OSPRay to build with GNU-style options BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS OFF ) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure glm rkcommon embree $<$:openvkl> $<$:benchmark> $<$:gtest> $<$:snappy> $<$:glfw> $<$:ispc> $<$:oidn> ) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/000077500000000000000000000000001464752671100235665ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_benchmark.cmake000066400000000000000000000016601464752671100273550ustar00rootroot00000000000000## Copyright 2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME benchmark) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) else() set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) endif() ExternalProject_Add(${COMPONENT_NAME} URL "https://github.com/google/benchmark/archive/refs/tags/v1.8.5.tar.gz" URL_HASH "SHA256=d26789a2b46d8808a48a4556ee58ccc7c497fcd4c0af9b90197674a81e04798a" # Skip updating on subsequent builds (faster) UPDATE_COMMAND "" DEPENDS gtest CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DBENCHMARK_ENABLE_TESTING=OFF -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_ENABLE_WERROR=OFF -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} ) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_embree.cmake000066400000000000000000000071241464752671100266630ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME embree) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (EMBREE_HASH) set(EMBREE_URL_HASH URL_HASH SHA256=${EMBREE_HASH}) endif() if (BUILD_EMBREE_FROM_SOURCE) string(REGEX REPLACE "(^[0-9]+\.[0-9]+\.[0-9]+$)" "v\\1" EMBREE_ARCHIVE ${EMBREE_VERSION}) set(EMBREE_URL "https://github.com/embree/embree/archive/${EMBREE_ARCHIVE}.tar.gz" CACHE STRING "Location to get Embree source from") if (${EMBREE_URL} MATCHES ".*\.tar\.gz$") set(EMBREE_CLONE_URL URL ${EMBREE_URL}) else() set(EMBREE_CLONE_URL GIT_REPOSITORY ${EMBREE_URL} GIT_TAG ${EMBREE_VERSION}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | # Use the alternate list separator ${EMBREE_CLONE_URL} ${EMBREE_URL_HASH} CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} $<$:-DEMBREE_TBB_ROOT=${TBB_PATH}> $<$:-DEMBREE_ISPC_EXECUTABLE=${ISPC_PATH}> -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} -DEMBREE_TUTORIALS=OFF -DBUILD_TESTING=OFF -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -DEMBREE_ISA_SSE42=${BUILD_ISA_SSE4} -DEMBREE_ISA_AVX=${BUILD_ISA_AVX} -DEMBREE_ISA_AVX2=${BUILD_ISA_AVX2} -DEMBREE_ISA_AVX512=${BUILD_ISA_AVX512} -DEMBREE_ISA_NEON=${BUILD_ISA_NEON} -DEMBREE_ISA_NEON2X=${BUILD_ISA_NEON2X} -DEMBREE_ISPC_SUPPORT=ON -DEMBREE_SYCL_SUPPORT=${BUILD_GPU_SUPPORT} BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS ${ALWAYS_REBUILD} ) if (DOWNLOAD_TBB) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure tbb) endif() if (DOWNLOAD_ISPC) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure ispc) endif() else() if (APPLE) set(EMBREE_OSSUFFIX "${CMAKE_SYSTEM_PROCESSOR}.macosx.zip") elseif (WIN32) set(EMBREE_OSSUFFIX "x64.windows.zip") else() set(EMBREE_OSSUFFIX "x86_64.linux.tar.gz") endif() if (BUILD_GPU_SUPPORT) set(EMBREE_TAG ".sycl") if (EMBREE_SYCL_HASH) set(EMBREE_URL_HASH URL_HASH SHA256=${EMBREE_SYCL_HASH}) endif() endif() set(EMBREE_URL "https://github.com/embree/embree/releases/download/v${EMBREE_VERSION}/embree-${EMBREE_VERSION}${EMBREE_TAG}.${EMBREE_OSSUFFIX}") ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME} URL ${EMBREE_URL} ${EMBREE_URL_HASH} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_directory / ${COMPONENT_PATH} BUILD_ALWAYS OFF ) endif() list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_glfw.cmake000066400000000000000000000036631464752671100263670ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME glfw) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build URL "https://github.com/glfw/glfw/archive/refs/tags/3.3.10.zip" URL_HASH "SHA256=5e4ae02dc7c9b084232824c2511679a7e0b0b09f2bae70191ad9703691368b58" # `patch` is not available on all systems, so use `git apply` instead. Note # that we initialize a Git repo in the GLFW download directory to allow the # Git patching approach to work. Also note that we don't want to actually # check out the GLFW Git repo, since we want our GLFW_HASH security checks # to still function correctly. PATCH_COMMAND git init -q . && git apply -v -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/glfw.patch CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} -DBUILD_SHARED_LIBS:BOOL=OFF -D_GLFW_BUILD_DLL:BOOL=ON # merge into ospray_imgui.dll -DGLFW_BUILD_DOCS=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS ${ALWAYS_REBUILD} ) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_glm.cmake000066400000000000000000000017771464752671100262130ustar00rootroot00000000000000## Copyright 2020 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME glm) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | # Use the alternate list separator URL "https://github.com/g-truc/glm/archive/refs/tags/1.0.1.tar.gz" URL_HASH "SHA256=9f3174561fd26904b23f0db5e560971cbf9b3cbda0b280f04d5c379d03bf234c" CMAKE_ARGS -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DGLM_BUILD_LIBRARY=OFF -DGLM_BUILD_TESTS=OFF -DGLM_TEST_ENABLE=OFF BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS OFF ) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}/share/glm) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_gtest.cmake000066400000000000000000000017171464752671100265540ustar00rootroot00000000000000## Copyright 2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME gtest) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() # Google Test follows the "Live Head" philosophy and therefore recommends # using the latest commit to 'master' ExternalProject_Add(${COMPONENT_NAME} URL "https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip" URL_HASH "SHA256=1f357c27ca988c3f7c6b4bf68a9395005ac6761f034046e9dde0896e3aba00e4" # # Skip updating on subsequent builds (faster) UPDATE_COMMAND "" CMAKE_ARGS -Dgtest_force_shared_crt=ON -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} -DBUILD_GMOCK=OFF ) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_ispc.cmake000066400000000000000000000023001464752671100263510ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME ispc) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (APPLE) set(ISPC_OSSUFFIX "macOS.${CMAKE_SYSTEM_PROCESSOR}.tar.gz") elseif(WIN32) set(ISPC_OSSUFFIX "windows.zip") else() if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") set(ISPC_OSSUFFIX "linux.aarch64.tar.gz") else() set(ISPC_OSSUFFIX "linux-oneapi.tar.gz") endif() endif() set(ISPC_URL "https://github.com/ispc/ispc/releases/download/v${ISPC_VERSION}/ispc-v${ISPC_VERSION}-${ISPC_OSSUFFIX}") if (ISPC_HASH) set(ISPC_URL_HASH URL_HASH SHA256=${ISPC_HASH}) endif() set(ISPC_PATH "${COMPONENT_PATH}/bin/ispc${CMAKE_EXECUTABLE_SUFFIX}") ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME} URL ${ISPC_URL} ${ISPC_URL_HASH} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_if_different /bin/ispc${CMAKE_EXECUTABLE_SUFFIX} ${ISPC_PATH} BUILD_ALWAYS OFF ) RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_oidn.cmake000066400000000000000000000064451464752671100263620ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME oidn) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (OIDN_HASH) set(OIDN_URL_HASH URL_HASH SHA256=${OIDN_HASH}) endif() if (BUILD_OIDN_FROM_SOURCE) if(${OIDN_VERSION} MATCHES "(^[0-9]+\.[0-9]+\.[0-9]+$)") set(OIDN_DEFAULT_URL "https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz") else() set(OIDN_DEFAULT_URL "https://www.github.com/OpenImageDenoise/oidn.git") endif() set(OIDN_URL ${OIDN_DEFAULT_URL} CACHE STRING "Location to get OpenImageDenoise source from") if (${OIDN_URL} MATCHES ".*\.src\.tar\.gz$") set(OIDN_CLONE_URL URL ${OIDN_URL}) else() set(OIDN_CLONE_URL GIT_REPOSITORY ${OIDN_URL} GIT_TAG ${OIDN_VERSION}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | # Use the alternate list separator ${OIDN_CLONE_URL} ${OIDN_URL_HASH} GIT_SHALLOW ON CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} $<$:-DTBB_ROOT=${TBB_PATH}> $<$:-DISPC_EXECUTABLE=${ISPC_PATH}> -DCMAKE_BUILD_TYPE=Release # XXX debug builds are currently broken -DOIDN_APPS=OFF -DOIDN_ZIP_MODE=ON # to set install RPATH -DOIDN_DEVICE_SYCL=${BUILD_GPU_SUPPORT} -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS ${ALWAYS_REBUILD} ) if (DOWNLOAD_TBB) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure tbb) endif() if (DOWNLOAD_ISPC) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure ispc) endif() else() if (APPLE) set(OIDN_OSSUFFIX "${CMAKE_SYSTEM_PROCESSOR}.macos.tar.gz") elseif (WIN32) set(OIDN_OSSUFFIX "x64.windows.zip") else() set(OIDN_OSSUFFIX "x86_64.linux.tar.gz") endif() set(OIDN_URL "https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.${OIDN_OSSUFFIX}") ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME} URL ${OIDN_URL} ${OIDN_URL_HASH} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_directory / ${COMPONENT_PATH} BUILD_ALWAYS OFF ) endif() list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_openvkl.cmake000066400000000000000000000070041464752671100270770ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME openvkl) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (OPENVKL_HASH) set(OPENVKL_URL_HASH URL_HASH SHA256=${OPENVKL_HASH}) endif() if (BUILD_OPENVKL_FROM_SOURCE) string(REGEX REPLACE "(^[0-9]+\.[0-9]+\.[0-9]+$)" "v\\1" OPENVKL_ARCHIVE ${OPENVKL_VERSION}) set(OPENVKL_BRANCH "${OPENVKL_ARCHIVE}" CACHE STRING "Which branch of OpenVKL to build" ) set(OPENVKL_URL "https://github.com/openvkl/openvkl/archive/${OPENVKL_ARCHIVE}.zip" CACHE STRING "Location to clone OpenVKL source from") string(REGEX MATCH ".*\.zip$" ZIP_FILENAME ${OPENVKL_URL}) if (ZIP_FILENAME) set(OPENVKL_CLONE_URL URL ${OPENVKL_URL}) else() set(OPENVKL_CLONE_URL GIT_REPOSITORY ${OPENVKL_URL} GIT_TAG ${OPENVKL_BRANCH}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | # Use the alternate list separator ${OPENVKL_CLONE_URL} ${OPENVKL_URL_HASH} CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} $<$:-DRKCOMMON_TBB_ROOT=${TBB_PATH}> $<$:-DISPC_EXECUTABLE=${ISPC_PATH}> -DBUILD_BENCHMARKS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -DOPENVKL_ISA_SSE4=${BUILD_ISA_SSE4} -DOPENVKL_ISA_AVX=${BUILD_ISA_AVX} -DOPENVKL_ISA_AVX2=${BUILD_ISA_AVX2} -DOPENVKL_ISA_AVX512SKX=${BUILD_ISA_AVX512} -DOPENVKL_ISA_NEON=${BUILD_ISA_NEON} -DOPENVKL_ISA_NEON2X=${BUILD_ISA_NEON2X} -DOPENVKL_ENABLE_DEVICE_GPU=${BUILD_GPU_SUPPORT} BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS ${ALWAYS_REBUILD} ) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure rkcommon embree $<$:ispc> ) else() if (APPLE) set(OPENVKL_OSSUFFIX "${CMAKE_SYSTEM_PROCESSOR}.macos.zip") elseif (WIN32) set(OPENVKL_OSSUFFIX "sycl.x86_64.windows.zip") else() set(OPENVKL_OSSUFFIX "sycl.x86_64.linux.tar.gz") endif() set(OPENVKL_URL "https://github.com/openvkl/openvkl/releases/download/v${OPENVKL_VERSION}/openvkl-${OPENVKL_VERSION}${OPENVKL_TAG}.${OPENVKL_OSSUFFIX}") ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME} URL ${OPENVKL_URL} ${OPENVKL_URL_HASH} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_directory ${COMPONENT_PATH} BUILD_ALWAYS OFF ) endif() list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}")RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_rkcommon.cmake000066400000000000000000000040201464752671100272410ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME rkcommon) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (RKCOMMON_HASH) set(RKCOMMON_URL_HASH URL_HASH SHA256=${RKCOMMON_HASH}) endif() string(REGEX REPLACE "(^[0-9]+\.[0-9]+\.[0-9]+$)" "v\\1" RKCOMMON_ARCHIVE ${RKCOMMON_VERSION}) set(RKCOMMON_URL "https://github.com/ospray/rkcommon/archive/${RKCOMMON_ARCHIVE}.tar.gz" CACHE STRING "Location to get rkcommon source from") if (${RKCOMMON_URL} MATCHES ".*\.tar\.gz$") set(RKCOMMON_CLONE_URL URL ${RKCOMMON_URL}) else() set(RKCOMMON_CLONE_URL GIT_REPOSITORY ${RKCOMMON_URL} GIT_TAG ${RKCOMMON_VERSION}) endif() ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | ${RKCOMMON_CLONE_URL} ${RKCOMMON_URL_HASH} CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} -DINSTALL_DEPS=OFF -DBUILD_TESTING=OFF $<$:-DRKCOMMON_TBB_ROOT=${TBB_PATH}> -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS ${ALWAYS_REBUILD} ) ExternalProject_Add_StepTargets(${COMPONENT_NAME} NO_DEPENDS download) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") if (DOWNLOAD_TBB) ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure tbb) endif() RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_snappy.cmake000066400000000000000000000017051464752671100267350ustar00rootroot00000000000000## Copyright 2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME snappy) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) else() set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) endif() ExternalProject_Add(${COMPONENT_NAME} URL "https://github.com/google/snappy/archive/refs/tags/1.2.1.tar.gz" URL_HASH "SHA256=736aeb64d86566d2236ddffa2865ee5d7a82d26c9016b36218fcc27ea4f09f86" # Skip updating on subsequent builds (faster) UPDATE_COMMAND "" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DBUILD_SHARED_LIBS:BOOL=OFF -DSNAPPY_BUILD_TESTS:BOOL=OFF -DSNAPPY_BUILD_BENCHMARKS:BOOL=OFF -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} ) list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/dep_tbb.cmake000066400000000000000000000050521464752671100261710ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 set(COMPONENT_NAME tbb) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}) if (INSTALL_IN_SEPARATE_DIRECTORIES) set(COMPONENT_PATH ${INSTALL_DIR_ABSOLUTE}/${COMPONENT_NAME}) endif() if (TBB_HASH) set(TBB_URL_HASH URL_HASH SHA256=${TBB_HASH}) endif() if (BUILD_TBB_FROM_SOURCE) string(REGEX REPLACE "(^[0-9]+\.[0-9]+\.[0-9]+$)" "v\\1" TBB_ARCHIVE ${TBB_VERSION}) ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME}/build LIST_SEPARATOR | # Use the alternate list separator URL "https://github.com/oneapi-src/oneTBB/archive/refs/tags/${TBB_ARCHIVE}.tar.gz" ${TBB_URL_HASH} CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${COMPONENT_PATH} -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR} -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} -DCMAKE_INSTALL_DOCDIR=${CMAKE_INSTALL_DOCDIR} -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR} -DCMAKE_BUILD_TYPE=${DEPENDENCIES_BUILD_TYPE} -DTBB_TEST=OFF -DTBB_STRICT=OFF -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} BUILD_COMMAND ${DEFAULT_BUILD_COMMAND} BUILD_ALWAYS ${ALWAYS_REBUILD} ) else() if (TBB_VERSION VERSION_LESS 2021) set(TBB_FOLDER "tbb") else() set(TBB_PREFIX "oneapi-") endif() if (APPLE) set(TBB_OSSUFFIX "mac.tgz") elseif (WIN32) set(TBB_OSSUFFIX "win.zip") else() set(TBB_OSSUFFIX "lin.tgz") endif() set(TBB_URL "https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/${TBB_PREFIX}tbb-${TBB_VERSION}-${TBB_OSSUFFIX}") ExternalProject_Add(${COMPONENT_NAME} PREFIX ${COMPONENT_NAME} DOWNLOAD_DIR ${COMPONENT_NAME} STAMP_DIR ${COMPONENT_NAME}/stamp SOURCE_DIR ${COMPONENT_NAME}/src BINARY_DIR ${COMPONENT_NAME} URL ${TBB_URL} ${TBB_URL_HASH} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_directory /${TBB_FOLDER} ${COMPONENT_PATH} BUILD_ALWAYS OFF ) endif() set(TBB_PATH "${COMPONENT_PATH}") list(APPEND CMAKE_PREFIX_PATH ${COMPONENT_PATH}) string(REPLACE ";" "|" CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}") RenderKit-ospray-85af292/scripts/superbuild/dependencies/glfw.patch000066400000000000000000000100521464752671100255440ustar00rootroot00000000000000diff --git a/src/null_platform.h b/src/null_platform.h index 708975d1..d916b922 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -43,7 +43,7 @@ #include "null_joystick.h" #if defined(_GLFW_WIN32) - #define _glfw_dlopen(name) LoadLibraryA(name) + #define _glfw_dlopen(name) LoadLibraryExA(name,NULL,LOAD_LIBRARY_SEARCH_SYSTEM32) #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) #else diff --git a/src/wgl_context.c b/src/wgl_context.c index b245b292..042e0f25 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -422,7 +422,7 @@ GLFWbool _glfwInitWGL(void) if (_glfw.wgl.instance) return GLFW_TRUE; - _glfw.wgl.instance = LoadLibraryA("opengl32.dll"); + _glfw.wgl.instance = LoadLibraryExA("opengl32.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (!_glfw.wgl.instance) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, diff --git a/src/win32_init.c b/src/win32_init.c index 885f32fa..5e698cc2 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -82,7 +82,7 @@ static GLFWbool loadLibraries(void) return GLFW_FALSE; } - _glfw.win32.user32.instance = LoadLibraryA("user32.dll"); + _glfw.win32.user32.instance = LoadLibraryExA("user32.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (!_glfw.win32.user32.instance) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, @@ -105,7 +105,7 @@ static GLFWbool loadLibraries(void) _glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi) GetProcAddress(_glfw.win32.user32.instance, "GetSystemMetricsForDpi"); - _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll"); + _glfw.win32.dinput8.instance = LoadLibraryExA("dinput8.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (_glfw.win32.dinput8.instance) { _glfw.win32.dinput8.Create = (PFN_DirectInput8Create) @@ -126,7 +126,7 @@ static GLFWbool loadLibraries(void) for (i = 0; names[i]; i++) { - _glfw.win32.xinput.instance = LoadLibraryA(names[i]); + _glfw.win32.xinput.instance = LoadLibraryExA(names[i],NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (_glfw.win32.xinput.instance) { _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities) @@ -139,7 +139,7 @@ static GLFWbool loadLibraries(void) } } - _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll"); + _glfw.win32.dwmapi.instance = LoadLibraryExA("dwmapi.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (_glfw.win32.dwmapi.instance) { _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled) @@ -152,7 +152,7 @@ static GLFWbool loadLibraries(void) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); } - _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); + _glfw.win32.shcore.instance = LoadLibraryExA("shcore.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (_glfw.win32.shcore.instance) { _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness) @@ -161,7 +161,7 @@ static GLFWbool loadLibraries(void) GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor"); } - _glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll"); + _glfw.win32.ntdll.instance = LoadLibraryExA("ntdll.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (_glfw.win32.ntdll.instance) { _glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo) diff --git a/src/win32_platform.h b/src/win32_platform.h index e729709f..4a7d8068 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -289,7 +289,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)( #define _GLFW_WNDCLASSNAME L"GLFW30" #endif -#define _glfw_dlopen(name) LoadLibraryA(name) +#define _glfw_dlopen(name) LoadLibraryExA(name,NULL,LOAD_LIBRARY_SEARCH_SYSTEM32) #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) RenderKit-ospray-85af292/scripts/superbuild/toolchains/000077500000000000000000000000001464752671100233035ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/superbuild/toolchains/macos-rosetta.cmake000066400000000000000000000012201464752671100270610ustar00rootroot00000000000000## Copyright 2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # This toolchain file is used to cross-compile OSPRay for x86_64 on ARM-based # MacOS systems (i.e., to run in Rosetta). Although OSPRay itself builds a # native ARM/M1 binary by default, compiling for x86_64 can be useful on such # systems when integrating OSPRay with applications that do not run natively on # ARM yet. set(CMAKE_SYSTEM_NAME Darwin) set(CMAKE_SYSTEM_PROCESSOR x86_64) set(CLANG_TRIPLE x86_64-apple-darwin) set(CMAKE_C_COMPILER clang) set(CMAKE_C_COMPILER_TARGET ${CLANG_TRIPLE}) set(CMAKE_CXX_COMPILER clang++) set(CMAKE_CXX_COMPILER_TARGET ${CLANG_TRIPLE}) RenderKit-ospray-85af292/scripts/tests/000077500000000000000000000000001464752671100201245ustar00rootroot00000000000000RenderKit-ospray-85af292/scripts/tests/README000066400000000000000000000042471464752671100210130ustar00rootroot00000000000000Running Tests ------------- notes for all items: ${OSPRAY_SOURCE_DIR} is the ospray source root. PATH and LD_LIBRARY_PATH should contain ${OSPRAY_BUILD_DIR}. 1. Build OSPRay Compile OSPRay in a build directory of your choosing. We will refer to this directory as ${OSPRAY_BUILD_DIR}. 2. Generate baseline images (OPTIONAL) Build OSPRay with OSPRAY_TESTING on. Only generate new images for a test that has changed. To generate new images for a specific test run ./ospTestSuite --gtest_filter="*TESTNAME*" --dump-img --baseline-dir=test_image_data/ which will create images in a folder called test_image_data. To make new images for all tests, In ${OSPRAY_BUILD_DIR}, run the "generate_baseline.sh" script: % ${OSPRAY_SOURCE_DIR}/scripts/tests/generate_baseline.sh This will output generated images in a folder named generated_test_images. These images will not automatically be used as baseline images for the tests unless put into the correct folder (/build_regression_tests/regression_test_baseline/) or the update script is used (5). 3. Run regression tests To verify whether a change to the codebase broke anything, run % ${OSPRAY_SOURCE_DIR}/scripts/tests/run_tests.sh ${OSPRAY_SOURCE_DIR} * where ISA is empty if using own generated images, or "AVX2" or "AVX512SKX" to * download golden images for that ISA target This will download golden baseline images into a folder named build_regression_tests/regression_test_baseline in the current working directory (OSPRAY_BUILD_DIR) and run tests to compare them. 4. To run an individual test ./ospTestSuite --gtest_list_tests this will output a list of test names ./ospTestSuite --gest_filter="*NAME*" will run a single test 5. Add or update generated test images to ospray Use the included update_test_baseline.sh script and then send the resulting files to ospray developers or do the following steps: call md5sum on the resulting .png files. Add a .png.md5 file to tests/baseling/TESTNAME.png.md5 with the value of the checksum. rename the .png file to be the checksum value, and then send this to OSPRay Devs who will add it to https://github.com/ospray/ospray-test-data / https://www.ospray.org/ospray-test-data/. RenderKit-ospray-85af292/scripts/tests/generate_baseline.bat000066400000000000000000000003311464752671100242450ustar00rootroot00000000000000@echo off rem Copyright 2016 Intel Corporation rem SPDX-License-Identifier: Apache-2.0 setlocal md generated_test_images ospTestSuite --dump-img --baseline-dir=generated_test_images exit /B %ERRORLEBEL% endlocal RenderKit-ospray-85af292/scripts/tests/generate_baseline.sh000077500000000000000000000004601464752671100241170ustar00rootroot00000000000000#!/bin/bash ## Copyright 2016 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # results are put in a new folder called generated_test_images rm -rf generated_test_images mkdir generated_test_images ospTestSuite --dump-img --baseline-dir=generated_test_images/ FAILED=$(echo $?) exit $FAILED RenderKit-ospray-85af292/scripts/tests/run-benchmarks.sh000077500000000000000000000112511464752671100234020ustar00rootroot00000000000000#!/bin/bash -xe ## Copyright 2020 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # benchmark configuration SOURCE_ROOT=`pwd` PROJECT_NAME="OSPRay" BENCHMARK_FLAGS="--benchmark_min_time=${BENCHMARK_MIN_TIME_SECONDS:-10s}" if [ "$1" = "GPU" ] ; then BENCHMARK_FLAGS="$BENCHMARK_FLAGS --benchmark_time_unit=s --benchmark_min_warmup_time=2 --osp:load-modules=gpu --osp:device=gpu" export ONEAPI_DEVICE_SELECTOR=level_zero:* export SYCL_CACHE_PERSISTENT=1 export OIDN_VERBOSE=2 export ZE_FLAT_DEVICE_HIERARCHY=COMPOSITE # WA for PVC fi export LD_LIBRARY_PATH=`pwd`/build/install/ospray/lib:${LD_LIBRARY_PATH} cd build/install/ospray/bin rm -f *.json ################################# PLEASE READ ################################## # # Note that suites and subsuites must exist in the database _before_ attempting # insertion of results. This is intentional! You should think carefully about # your [suite -> subsuite -> benchmark] hierarchy and definitions. These should # be stable over time (especially for suites and subsuites) to facilitate # long-term comparisons. # # These can be inserted using the benchmark client, through the "insert suite" # and "insert subsuite" commands. Ask for help if you have questions. # ################################# PLEASE READ ################################### ###################### # Example benchmarks # ###################### SUITE_NAME="Examples" SUBSUITE_NAME="BoxesAO" SUBSUITE_REGEX="^boxes" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json # wait to insert contexts (which will be reused for all subsequent benchmark runs) # until first benchmark successfully finishes. benny insert code_context "${PROJECT_NAME}" ${SOURCE_ROOT} --save-json code_context.json benny insert run_context ${BENNY_SYSTEM_TOKEN} ./code_context.json --save-json run_context.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json # subsequent subsuite runs... SUBSUITE_NAME="CornellBoxSPP" SUBSUITE_REGEX="^cornell_box" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json SUBSUITE_NAME="GravitySpheresVolumeDIM" SUBSUITE_REGEX="^gravity_spheres_volume" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json SUBSUITE_NAME="PerlinNoiseVolumes" SUBSUITE_REGEX="^perlin_noise_volumes" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json SUBSUITE_NAME="ParticleVolumes" SUBSUITE_REGEX="^particle_volume" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json SUBSUITE_NAME="UnstructuredVolumes" SUBSUITE_REGEX="^unstructured_volume" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json SUBSUITE_NAME="Clipping" SUBSUITE_REGEX="^clip" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json SUBSUITE_NAME="Other" SUBSUITE_REGEX="^(random_spheres|streamlines|planes|vdb_volume|gravity_spheres_amr)" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json ################### # Microbenchmarks # ################### SUITE_NAME="Microbenchmarks" SUBSUITE_NAME="Setup" SUBSUITE_REGEX="^setup" ./ospBenchmark ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json RenderKit-ospray-85af292/scripts/tests/run_gpu_tests.ps1000077500000000000000000000116711464752671100234630ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # to run: ./run_tests.ps1 [SKIP_GPU] [TEST_MPI] [TEST_MULTIDEVICE] # a new folder is created called build_regression_tests with results $osprayDir=$args[0] $testGPU = $TRUE $testMPI = $FALSE $testMultiDevice = $FALSE foreach ($arg in $args) { if ($arg -eq "SKIP_GPU") { $testGPU = $FALSE } if ($arg -eq "TEST_MPI") { $testMPI = $TRUE } if ($arg -eq "TEST_MULTIDEVICE") { $testMultiDevice = $TRUE } } md build_regression_tests cd build_regression_tests $exitCode = 0 # try Ninja first cmake -G Ninja -D OSPRAY_TEST_ISA=AVX512SKX $osprayDir/test_image_data if ($LastExitCode) { cmake -D OSPRAY_TEST_ISA=AVX512SKX $osprayDir/test_image_data if ($LastExitCode) { $exitCode++ } } cmake --build . --config Release --target ospray_test_data if ($LastExitCode) { $exitCode++ } ### Excluded tests on GPU ######################### # Clipping unsupported $test_filters="ClippingParallel.planes" $test_filters+=":TestScenesClipping/FromOsprayTesting.*" $test_filters+=":TestScenesMaxDepth/FromOsprayTestingMaxDepth.test_scenes/1" $test_filters+=":TestScenesMaxDepth/FromOsprayTestingMaxDepth.test_scenes/2" $test_filters+=":TestMotionBlur/MotionBlurBoxes.*" $test_filters+=":CameraRollingShutter/MotionBlurBoxes.*" $test_filters+=":CameraStereoRollingShutter/MotionBlurBoxes.*" # Subdivision surfaces unsupported $test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/15" $test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/16" $test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/17" $test_filters+=":Color/Interpolation.Interpolation/4" $test_filters+=":Color/Interpolation.Interpolation/5" $test_filters+=":Color/Interpolation.Interpolation/6" $test_filters+=":Color/Interpolation.Interpolation/7" $test_filters+=":Texcoord/Interpolation.Interpolation/2" $test_filters+=":Texcoord/Interpolation.Interpolation/3" # Multiple volumes unsupported $test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/3" $test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/4" $test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/5" $test_filters+=":TestScenesVolumesStrictParams/FromOsprayTesting.*" # Requires non-overlapping multiple volume support on GPU $test_filters+=":ObjectInstance/IDBuffer.*" # Instancing test includes multiple volumes $test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/24" $test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/25" $test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/26" # 'mix' material not supported on GPU (not practical to implement without fn ptr) $test_filters+=":TestScenesPtMaterials/FromOsprayTesting.test_scenes/8" # Crashing FIXME $test_filters+=":Primitive/IDBuffer.*" # Different noise $test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/1" # Artifacts, Windows only (driver?) $test_filters+=":TestScenesPtMaterials/FromOsprayTesting.test_scenes/4" $test_filters+=":TestScenesPtMaterials/FromOsprayTesting.test_scenes/5" $test_filters+=":TestScenesVolumes/UnstructuredVolume.simple/2" $test_filters+=":TestScenesVolumes/UnstructuredVolume.simple/3" $env:ONEAPI_DEVICE_SELECTOR="level_zero:*" $env:SYCL_CACHE_PERSISTENT="1" $env:OIDN_VERBOSE="2" if ($testGPU) { md failed-gpu ospTestSuite.exe --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-gpu --osp:load-modules=gpu --osp:device=gpu --gtest_filter="-$test_filters" --own-SYCL if ($LastExitCode) { $exitCode++ } $env:OSPRAY_ALLOW_DEVICE_MEMORY = "1" ospTestSuite.exe --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-gpu --osp:load-modules=gpu --osp:device=gpu --gtest_filter=SharedData/TestUSMSharing.structured_regular/2 --own-SYCL if ($LastExitCode) { $exitCode++ } $env:OSPRAY_ALLOW_DEVICE_MEMORY = "0" } if ($testMultiDevice) { md failed-multidevice $env:OSPRAY_NUM_SUBDEVICES=2 ospTestSuite.exe --osp:load-modules=multidevice_cpu --osp:device=multidevice --gtest_output=xml:tests-multidevice.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-multidevice --gtest_filter="-$test_filters" if ($LastExitCode) { $exitCode++ } } if ($testMPI) { md failed-mpi-gpu $env:OSPRAY_MPI_DISTRIBUTED_GPU=1 mpiexec.exe -np 1 ospTestSuite.exe --osp:load-modules=mpi_offload --osp:device=mpiOffload --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-mpi-gpu --gtest_filter="-$test_filters" : -np 2 ospray_mpi_worker.exe if ($LastExitCode) { $exitCode++ } md failed-mpi-gpu-data-parallel $test_filters="MPIDistribTestScenesVolumes/MPIFromOsprayTesting.test_scenes/1" # FIXME mpiexec.exe -np 3 -prepend-rank ospMPIDistribTestSuite.exe --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-mpi-gpu-data-parallel --gtest_filter="-$test_filters" if ($LastExitCode) { $exitCode++ } } exit $exitCode RenderKit-ospray-85af292/scripts/tests/run_gpu_tests.sh000077500000000000000000000117331464752671100233710ustar00rootroot00000000000000#!/bin/bash ## Copyright 2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # to run: ./run_tests.sh [SKIP_GPU] [TEST_MPI] [TEST_MULTIDEVICE] # a new folder is created called build_regression_tests with results SOURCEDIR=$([[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}") if [ -z "$MPI_ROOT_CONFIG" ]; then MPI_ROOT_CONFIG="-np 1" fi if [ -z "$MPI_WORKER_CONFIG" ]; then MPI_WORKER_CONFIG="-np 2" fi # optional command line arguments TEST_GPU=true while [[ $# -gt 0 ]] do key="$1" case $key in SKIP_GPU) unset TEST_GPU shift ;; TEST_MPI) TEST_MPI=true shift ;; TEST_MULTIDEVICE) TEST_MULTIDEVICE=true shift ;; *) shift ;; esac done mkdir build_regression_tests cd build_regression_tests exitCode=0 cmake -D OSPRAY_TEST_ISA=AVX512SKX "${SOURCEDIR}/test_image_data" let exitCode+=$? export CMAKE_BUILD_PARALLEL_LEVEL=32 cmake --build . --target ospray_test_data let exitCode+=$? ### Excluded tests on GPU ######################### # Clipping unsupported test_filters="ClippingParallel.planes" test_filters+=":TestScenesClipping/FromOsprayTesting.*" test_filters+=":TestScenesMaxDepth/FromOsprayTestingMaxDepth.test_scenes/1" test_filters+=":TestScenesMaxDepth/FromOsprayTestingMaxDepth.test_scenes/2" test_filters+=":TestMotionBlur/MotionBlurBoxes.*" test_filters+=":CameraRollingShutter/MotionBlurBoxes.*" test_filters+=":CameraStereoRollingShutter/MotionBlurBoxes.*" # Subdivision surfaces unsupported test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/15" test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/16" test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/17" test_filters+=":Color/Interpolation.Interpolation/4" test_filters+=":Color/Interpolation.Interpolation/5" test_filters+=":Color/Interpolation.Interpolation/6" test_filters+=":Color/Interpolation.Interpolation/7" test_filters+=":Texcoord/Interpolation.Interpolation/2" test_filters+=":Texcoord/Interpolation.Interpolation/3" # Multiple volumes unsupported test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/3" test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/4" test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/5" test_filters+=":TestScenesVolumesStrictParams/FromOsprayTesting.*" # Requires non-overlapping multiple volume support on GPU test_filters+=":ObjectInstance/IDBuffer.*" # Instancing test includes multiple volumes test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/24" test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/25" test_filters+=":TestScenesGeometry/FromOsprayTesting.test_scenes/26" # 'mix' material not supported on GPU (not practical to implement without fn ptr) test_filters+=":TestScenesPtMaterials/FromOsprayTesting.test_scenes/8" # Crashing FIXME test_filters+=":Primitive/IDBuffer.*" # Different noise test_filters+=":TestScenesVolumes/FromOsprayTesting.test_scenes/1" export ONEAPI_DEVICE_SELECTOR=level_zero:* export SYCL_CACHE_PERSISTENT=1 export OIDN_VERBOSE=2 export ZE_FLAT_DEVICE_HIERARCHY=COMPOSITE # WA for PVC if [ $TEST_GPU ]; then mkdir failed-gpu ospTestSuite --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-gpu --osp:load-modules=gpu --osp:device=gpu --gtest_filter="-$test_filters" --own-SYCL let exitCode+=$? OSPRAY_ALLOW_DEVICE_MEMORY=1 ospTestSuite --baseline-dir=regression_test_baseline/ --failed-dir=failed-gpu --osp:load-modules=gpu --osp:device=gpu --gtest_filter=SharedData/TestUSMSharing.structured_regular/2 --own-SYCL let exitCode+=$? fi if [ $TEST_MULTIDEVICE ]; then mkdir failed-multidevice OSPRAY_NUM_SUBDEVICES=2 ospTestSuite --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-multidevice --gtest_filter="-$test_filters" --osp:load-modules=multidevice_gpu --osp:device=multidevice --own-SYCL let exitCode+=$? OSPRAY_ALLOW_DEVICE_MEMORY=1 OSPRAY_NUM_SUBDEVICES=2 ospTestSuite --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-multidevice --gtest_filter=SharedData/TestUSMSharing.structured_regular/2 --osp:load-modules=multidevice_gpu --osp:device=multidevice --own-SYCL let exitCode+=$? fi if [ $TEST_MPI ]; then mkdir failed-mpi-gpu # Need to export, not just set for MPI to pick it up export OSPRAY_MPI_DISTRIBUTED_GPU=1 mpiexec $MPI_ROOT_CONFIG ospTestSuite --gtest_output=xml:tests-mpi-offload.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi-gpu --osp:load-modules=mpi_offload --osp:device=mpiOffload --gtest_filter="-$test_filters" : $MPI_WORKER_CONFIG ospray_mpi_worker let exitCode+=$? mkdir failed-mpi-gpu-data-parallel test_filters="MPIDistribTestScenesVolumes/MPIFromOsprayTesting.test_scenes/1" # FIXME mpiexec -np 3 ospMPIDistribTestSuite --gtest_output=xml:tests-mpi-distrib.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi-gpu-data-parallel --gtest_filter="-$test_filters" let exitCode+=$? fi exit $exitCode RenderKit-ospray-85af292/scripts/tests/run_tests.ps1000077500000000000000000000040471464752671100226070ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # to run: ./run_tests.ps1 [SKIP_CPU] [TEST_MPI] [TEST_MULTIDEVICE] # a new folder is created called build_regression_tests with results $osprayDir=$args[0] $testISA=$args[1] $testCPU = $TRUE $testMPI = $FALSE $testMultiDevice = $FALSE foreach ($arg in $args) { if ($arg -eq "SKIP_CPU") { $testCPU = $FALSE } if ($arg -eq "TEST_MPI") { $testMPI = $TRUE } if ($arg -eq "TEST_MULTIDEVICE") { $testMultiDevice = $TRUE } } md build_regression_tests cd build_regression_tests $exitCode = 0 # try Ninja first cmake -G Ninja -D OSPRAY_TEST_ISA=$testISA $osprayDir/test_image_data if ($LastExitCode) { cmake -D OSPRAY_TEST_ISA=$testISA $osprayDir/test_image_data if ($LastExitCode) { $exitCode++ } } cmake --build . --config Release --target ospray_test_data if ($LastExitCode) { $exitCode++ } if ($testCPU) { md failed ospTestSuite.exe --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed if ($LastExitCode) { $exitCode++ } } if ($testMultiDevice) { md failed-multidevice $env:OSPRAY_NUM_SUBDEVICES=2 ospTestSuite.exe --osp:load-modules=multidevice_cpu --osp:device=multidevice --gtest_output=xml:tests-multidevice.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-multidevice --gtest_filter="-$test_filters" if ($LastExitCode) { $exitCode++ } } if ($testMPI) { md failed-mpi $test_filters += ":TestScenesVariance/*" mpiexec.exe -np 1 ospTestSuite.exe --osp:load-modules=mpi_offload --osp:device=mpiOffload --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-mpi --gtest_filter="-$test_filters" : -np 2 ospray_mpi_worker.exe if ($LastExitCode) { $exitCode++ } md failed-mpi-data-parallel mpiexec.exe -np 3 -prepend-rank ospMPIDistribTestSuite.exe --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-mpi-data-parallel if ($LastExitCode) { $exitCode++ } } exit $exitCode RenderKit-ospray-85af292/scripts/tests/run_tests.sh000077500000000000000000000043511464752671100225140ustar00rootroot00000000000000#!/bin/bash ## Copyright 2016 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 # to run: ./run_tests.sh [SKIP_CPU] [TEST_MPI] [TEST_MULTIDEVICE] # a new folder is created called build_regression_tests with results if [ -z "$MPI_ROOT_CONFIG" ]; then MPI_ROOT_CONFIG="-np 1" fi if [ -z "$MPI_WORKER_CONFIG" ]; then MPI_WORKER_CONFIG="-np 2" fi if [ -z "$1" ]; then echo "usage: run_tests.sh [TEST_MPI] [TEST_MULTIDEVICE]" exit -1 fi # Expand relative paths. SOURCEDIR=$([[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}") TESTISA=$2 # optional command line arguments TEST_CPU=true while [[ $# -gt 0 ]] do key="$1" case $key in SKIP_CPU) unset TEST_CPU shift ;; TEST_MPI) TEST_MPI=true shift ;; TEST_MULTIDEVICE) TEST_MULTIDEVICE=true shift ;; *) shift ;; esac done mkdir build_regression_tests cd build_regression_tests exitCode=0 cmake -D OSPRAY_TEST_ISA=$TESTISA ${SOURCEDIR}/test_image_data let exitCode+=$? export CMAKE_BUILD_PARALLEL_LEVEL=32 cmake --build . --target ospray_test_data let exitCode+=$? export OIDN_VERBOSE=2 if [ $TEST_CPU ]; then mkdir failed ospTestSuite --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed let exitCode+=$? fi if [ $TEST_MULTIDEVICE ]; then mkdir failed-multidevice OSPRAY_NUM_SUBDEVICES=2 ospTestSuite --gtest_output=xml:tests.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-multidevice --gtest_filter="-$test_filters" --osp:load-modules=multidevice_cpu --osp:device=multidevice let exitCode+=$? fi if [ $TEST_MPI ]; then mkdir failed-mpi test_filters="TestScenesVariance/*" mpiexec $MPI_ROOT_CONFIG ospTestSuite --gtest_output=xml:tests-mpi-offload.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi --gtest_filter="-$test_filters" --osp:load-modules=mpi_offload --osp:device=mpiOffload : $MPI_WORKER_CONFIG ospray_mpi_worker let exitCode+=$? mkdir failed-mpi-data-parallel mpiexec -np 3 ospMPIDistribTestSuite --gtest_output=xml:tests-mpi-distrib.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi-data-parallel let exitCode+=$? fi exit $exitCode RenderKit-ospray-85af292/scripts/tests/run_tutorials.sh000077500000000000000000000022361464752671100234000ustar00rootroot00000000000000#!/bin/bash ## Copyright 2016 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 export LD_LIBRARY_PATH=`pwd`/build/install/ospray/lib:$LD_LIBRARY_PATH export DYLD_LIBRARY_PATH=`pwd`/build/install/ospray/lib:$DYLD_LIBRARY_PATH export PATH=`pwd`/build/install/ospray/bin:$PATH while [[ $# -gt 0 ]] do key="$1" case $key in TEST_MPI) TEST_MPI=true shift ;; *) shift ;; esac done exitCode=0 echo -e "\n\nRunning 'ospTutorial'..." ospTutorial let exitCode+=$? echo -e "\n\nRunning 'ospTutorialCpp'..." ospTutorialCpp let exitCode+=$? echo -e "\n\nRunning 'ospTutorialAsync'..." ospTutorialAsync let exitCode+=$? if [[ -x `pwd`/build/install/ospray/bin/ospTutorialGLM ]] ; then echo -e "\n\nRunning 'ospTutorialGLM'..." ospTutorialGLM let exitCode+=$? fi if [ $TEST_MPI ]; then echo -e "\n\nRunning 'ospMPIDistribTutorial'..." mpiexec -np 3 ospMPIDistribTutorial let exitCode+=$? echo -e "\n\nRunning 'ospMPIDistribTutorialCpp'..." mpiexec -np 3 ospMPIDistribTutorialCpp let exitCode+=$? echo -e "\n\nRunning 'ospMPIDistribTutorialAsync'..." mpiexec -np 3 ospMPIDistribTutorialAsync let exitCode+=$? fi exit $exitCode RenderKit-ospray-85af292/scripts/tests/update_test_baseline.sh000077500000000000000000000013251464752671100246470ustar00rootroot00000000000000#!/bin/bash ## Copyright 2016 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 #author=Carson Brownlee #generates md5 checksums for generated regression test image # and uploads checksum and image to sdvis server # # argument 1: name of test # argument 2: directory of test result images # argument 3: path of ospray source # argument 4: path to ospray-test-data # argument 5: ISA (optional) # isas="AVX2 AVX512SKX" md5=`md5sum $2/$1.png | awk '{print $1 }'` echo $md5 if [ -n "$5" ]; then # if ISA specified place reference image only in the ISA specific directories isas=$5 fi for isa in $isas do echo $md5 > $3/test_image_data/baseline/$isa/$1.png.md5 done cp $2/$1.png $4/MD5/$md5 cd $4 git add MD5/$md5 RenderKit-ospray-85af292/test_image_data/000077500000000000000000000000001464752671100204055ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/CMakeLists.txt000066400000000000000000000022201464752671100231410ustar00rootroot00000000000000## Copyright 2009 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.5) project(ospray_test_data NONE) # Baseline images for tests and benchmarks include(ExternalData) # Variable determines which reference images will be used for testing set(OSPRAY_TEST_ISA "AVX512SKX" CACHE STRING "Reference images ISA") set_property(CACHE OSPRAY_TEST_ISA PROPERTY STRINGS AVX2 AVX512SKX) set(ExternalData_URL_TEMPLATES "https://www.ospray.org/ospray-test-data/%(algo)/%(hash)" "https://www.ospray.org/ospray-test-data/%(algo)/%(hash)" # retry on error ) file(TO_CMAKE_PATH "$ENV{STORAGE_PATH}" STORAGE_PATH) set(ExternalData_OBJECT_STORES "${CMAKE_BINARY_DIR}/regression_test_baseline" "${STORAGE_PATH}/projects/OSPRay/test-data" ) set(ExternalData_BINARY_ROOT ${CMAKE_BINARY_DIR}/regression_test_baseline) set(ExternalData_SOURCE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/baseline/${OSPRAY_TEST_ISA}) ExternalData_Expand_Arguments(ospray_test_data ospray_test_suite DATA{${ExternalData_SOURCE_ROOT}/,REGEX:.*} ) ExternalData_Add_Target(ospray_test_data) set_target_properties(ospray_test_data PROPERTIES EXCLUDE_FROM_ALL TRUE) RenderKit-ospray-85af292/test_image_data/README000066400000000000000000000000571464752671100212670ustar00rootroot00000000000000for tests information see scripts/tests/README RenderKit-ospray-85af292/test_image_data/baseline/000077500000000000000000000000001464752671100221675ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2/000077500000000000000000000000001464752671100227075ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2/AmbientLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100320510ustar00rootroot0000000000000067daf471b763cf03d3b0d17226f5a166 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/AmbientLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100320520ustar00rootroot00000000000000aa59d7082ec8cb93dfc9b95cb01cf37d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/ClippingParallel_planes.png.md5000066400000000000000000000000411464752671100306600ustar00rootroot0000000000000024936b121705fd9cc9fdc59c216a1c53 Curves_TestScenesGeometry_test_scenes_0.png.md5000066400000000000000000000000411464752671100337560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2882ba977f68b0815293c44d604618fb8 Curves_TestScenesGeometry_test_scenes_1.png.md5000066400000000000000000000000411464752671100337570ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a22b984373be41e86feff5b2a4121b49 Curves_TestScenesGeometry_test_scenes_10.png.md5000066400000000000000000000000411464752671100340370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27441623be7aafd6b19f70fbc69d89fc1 Curves_TestScenesGeometry_test_scenes_11.png.md5000066400000000000000000000000411464752671100340400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20fc866fc4291ff9f79a1f64571cd134a Curves_TestScenesGeometry_test_scenes_12.png.md5000066400000000000000000000000411464752671100340410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a2e926faa3c76d63aaa1aef9dede7ec0 Curves_TestScenesGeometry_test_scenes_13.png.md5000066400000000000000000000000411464752671100340420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2422f6f8d2a4805b7e3b42e2cdae8eeea Curves_TestScenesGeometry_test_scenes_14.png.md5000066400000000000000000000000411464752671100340430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX22a7cf802e75f7efb90fbaf7f8457c1d8 Curves_TestScenesGeometry_test_scenes_15.png.md5000066400000000000000000000000411464752671100340440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24dcd72951efa109e66baf42d74326654 Curves_TestScenesGeometry_test_scenes_16.png.md5000066400000000000000000000000411464752671100340450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a1d1028d099c8cf32ab813c826058b32 Curves_TestScenesGeometry_test_scenes_17.png.md5000066400000000000000000000000411464752671100340460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fc3e7ad06241fc50d397870252d495ae Curves_TestScenesGeometry_test_scenes_18.png.md5000066400000000000000000000000411464752671100340470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2917bce6953c64095755c5583c53fb6b5 Curves_TestScenesGeometry_test_scenes_19.png.md5000066400000000000000000000000411464752671100340500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX243a4e65c47032d6201fe1e347a19f1ef Curves_TestScenesGeometry_test_scenes_2.png.md5000066400000000000000000000000411464752671100337600ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a1e97368016cd291e17e4e1cac325234 Curves_TestScenesGeometry_test_scenes_20.png.md5000066400000000000000000000000411464752671100340400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2043c3d27a805f43b8da9321e2e59e22c Curves_TestScenesGeometry_test_scenes_3.png.md5000066400000000000000000000000411464752671100337610ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2448c61a8278f76a94c2ae633b3f2359b Curves_TestScenesGeometry_test_scenes_4.png.md5000066400000000000000000000000411464752671100337620ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c6309ef9c9ebcae988e05694dc05c2e7 Curves_TestScenesGeometry_test_scenes_5.png.md5000066400000000000000000000000411464752671100337630ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b5ffc718870ba5359b30c7aaa4ea9382 Curves_TestScenesGeometry_test_scenes_6.png.md5000066400000000000000000000000411464752671100337640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX238c517740d03a70167bea3951d53ab30 Curves_TestScenesGeometry_test_scenes_7.png.md5000066400000000000000000000000411464752671100337650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f427e56260493351bba7e022486a1587 Curves_TestScenesGeometry_test_scenes_8.png.md5000066400000000000000000000000411464752671100337660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a7c662a4681783bd466a6e864d538d55 Curves_TestScenesGeometry_test_scenes_9.png.md5000066400000000000000000000000411464752671100337670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f70f5b320125c2b5363e7783ab4a8b06 CylinderLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100356320ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX273ed3d47eeac3a9b6fc673060c1c5328 CylinderLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100356330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24a7ebb5f6043f46912d9b1c4f35499bf CylinderLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100356340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX23ea087abfcc25b0ae4c7be49462e4c78 CylinderLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100356350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e4ed1ed1f60faca8502105cbe2291a95 CylinderLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100341770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2dac74a13cc7f155a14b31ad33ec9b3c4 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100322430ustar00rootroot0000000000000011b1e39e738a027d748ed001602cf13d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100322440ustar00rootroot0000000000000084a7c4de39de086a654eda24ea5a141d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100322450ustar00rootroot000000000000000e5e30af1a3e4c3e352e2af2996697be RenderKit-ospray-85af292/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100322460ustar00rootroot00000000000000a600e9c329322c20bd93995c4cf2ce9e RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DenoiserOp_DenoiserOp_DenoiserOp_0.png.md5000066400000000000000000000000411464752671100326400ustar00rootroot00000000000000ded988069e8394b26dbe0ea554b4149b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DenoiserOp_DenoiserOp_DenoiserOp_1.png.md5000066400000000000000000000000411464752671100326410ustar00rootroot00000000000000e9e4a9c5dee535fe8e7996a519b67156 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DenoiserOp_DenoiserOp_DenoiserOp_2.png.md5000066400000000000000000000000411464752671100326420ustar00rootroot00000000000000c384bd9efbe58c20f14dd01d73f0b069 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DenoiserOp_DenoiserOp_DenoiserOp_3.png.md5000066400000000000000000000000411464752671100326430ustar00rootroot0000000000000069041af4dcb8bce523679bcb5f7436d4 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DenoiserOp_DenoiserOp_DenoiserOp_4.png.md5000066400000000000000000000000411464752671100326440ustar00rootroot000000000000006278286a6b4504277e4420ade3aebc9b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DenoiserOp_DenoiserOp_DenoiserOp_5.png.md5000066400000000000000000000000411464752671100326450ustar00rootroot00000000000000c75f4ef7cb81362bdf1f9a37033faf77 DepthCompositeVolume_Renderers_simple_0.png.md5000066400000000000000000000000411464752671100337350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2642603a3031518fe9f21bf6d07835528 DepthCompositeVolume_Renderers_simple_1.png.md5000066400000000000000000000000411464752671100337360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a48a2b26a51f0ccab651ef1dfa48c061 DepthCompositeVolume_Renderers_simple_2.png.md5000066400000000000000000000000411464752671100337370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX256089ffe487951c01a12eb629198ed8e DepthCompositeVolume_Renderers_simple_3.png.md5000066400000000000000000000000411464752671100337400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ff857fab1a8f9325760f08851316501b DistantLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100340340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2323173a42d4f374d660cffaf5ec2df44 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DistantLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100321000ustar00rootroot0000000000000012c66430113874ba4d795c2a5335f897 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DistantLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100321010ustar00rootroot00000000000000d2851bae6777011ed87fa5b6d64ff7c8 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DistantLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100321020ustar00rootroot00000000000000368189c68d2e689d830a566c6880a839 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/DistantLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100321030ustar00rootroot000000000000004cb53696a83b0c7326c6888c002828a3 FromOsprayTestingLightSamples_TestScenesLightSamples_testScenes_0.png.md5000066400000000000000000000000411464752671100410650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2229965d72a3a5a964302dbd8395ebc1d FromOsprayTestingLightSamples_TestScenesLightSamples_testScenes_1.png.md5000066400000000000000000000000411464752671100410660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX28b083f2e31e097dbfc51568d4cc80e5b FromOsprayTestingMaxDepth_TestScenesMaxDepth_test_scenes_0.png.md5000066400000000000000000000000411464752671100375200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27b145567101fa685ef4fd3d9318e0ab8 FromOsprayTestingMaxDepth_TestScenesMaxDepth_test_scenes_1.png.md5000066400000000000000000000000411464752671100375210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fdfdeaf9cf2b46b75164a382d1392a24 FromOsprayTestingMaxDepth_TestScenesMaxDepth_test_scenes_2.png.md5000066400000000000000000000000411464752671100375220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20ca1c6949e3509a4c0286a1cb0935446 FromOsprayTestingVariance_TestScenesVariance_testScenes_0.png.md5000066400000000000000000000000411464752671100373550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27f2868db0487194db7cf7a8d945680f9 FromOsprayTesting_TestScenesClipping_test_scenes_0.png.md5000066400000000000000000000000411464752671100361200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20296157028674dc93d72d85d0e965818 FromOsprayTesting_TestScenesClipping_test_scenes_1.png.md5000066400000000000000000000000411464752671100361210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20fd1877c94ac8514b0dfbd9e30726421 FromOsprayTesting_TestScenesClipping_test_scenes_10.png.md5000066400000000000000000000000411464752671100362010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fc569947d28c532f62adc96ec4785828 FromOsprayTesting_TestScenesClipping_test_scenes_11.png.md5000066400000000000000000000000411464752671100362020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2888d98f1dd39afaecb178993b0d746ad FromOsprayTesting_TestScenesClipping_test_scenes_12.png.md5000066400000000000000000000000411464752671100362030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX26fdf5191f445f07d244e8e6d082f84bf FromOsprayTesting_TestScenesClipping_test_scenes_13.png.md5000066400000000000000000000000411464752671100362040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2df8a811a67c3433067c9a6a48aa4c2ba FromOsprayTesting_TestScenesClipping_test_scenes_14.png.md5000066400000000000000000000000411464752671100362050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29ff00941883291ec044226779055cef2 FromOsprayTesting_TestScenesClipping_test_scenes_15.png.md5000066400000000000000000000000411464752671100362060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX282791520206ee937d3cc1b7c2e196cb5 FromOsprayTesting_TestScenesClipping_test_scenes_16.png.md5000066400000000000000000000000411464752671100362070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b49014c001b9bcccc647809993fece68 FromOsprayTesting_TestScenesClipping_test_scenes_17.png.md5000066400000000000000000000000411464752671100362100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20f9fb5b8cc9667e4dece6fc4a43de759 FromOsprayTesting_TestScenesClipping_test_scenes_18.png.md5000066400000000000000000000000411464752671100362110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX229796dae1e53914c740c14d130005f81 FromOsprayTesting_TestScenesClipping_test_scenes_19.png.md5000066400000000000000000000000411464752671100362120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e016efcd24a7f94c326ff1e3fcf4f36c FromOsprayTesting_TestScenesClipping_test_scenes_2.png.md5000066400000000000000000000000411464752671100361220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX23941e408aef3ce9f87d8cacf1ebe9504 FromOsprayTesting_TestScenesClipping_test_scenes_20.png.md5000066400000000000000000000000411464752671100362020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX287174ee15065c15b9687ad1b8713ef92 FromOsprayTesting_TestScenesClipping_test_scenes_21.png.md5000066400000000000000000000000411464752671100362030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29c746c040621f1889075118e35fe2b7d FromOsprayTesting_TestScenesClipping_test_scenes_22.png.md5000066400000000000000000000000411464752671100362040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX28ab32391e78a4e9baa94fa66c4228ded FromOsprayTesting_TestScenesClipping_test_scenes_23.png.md5000066400000000000000000000000411464752671100362050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX200674517ea25290fefdb1eb341a122b0 FromOsprayTesting_TestScenesClipping_test_scenes_24.png.md5000066400000000000000000000000411464752671100362060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX243adbf11389d8ad144d2b36f2a25470a FromOsprayTesting_TestScenesClipping_test_scenes_25.png.md5000066400000000000000000000000411464752671100362070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2440c14728d370912fe9b804bbc956d83 FromOsprayTesting_TestScenesClipping_test_scenes_26.png.md5000066400000000000000000000000411464752671100362100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21b5caed59b3f0331dc480dc001195e27 FromOsprayTesting_TestScenesClipping_test_scenes_3.png.md5000066400000000000000000000000411464752671100361230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a5ad0f0c20eafe1b6403062357bce181 FromOsprayTesting_TestScenesClipping_test_scenes_4.png.md5000066400000000000000000000000411464752671100361240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ef40d7d0b2f00e247bc25b4c9e65a130 FromOsprayTesting_TestScenesClipping_test_scenes_5.png.md5000066400000000000000000000000411464752671100361250ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2bc95c3ddc66b3e79f6c8e982f2eac8a7 FromOsprayTesting_TestScenesClipping_test_scenes_6.png.md5000066400000000000000000000000411464752671100361260ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b32fe5c7b0f6eeb98a00d2cd8b13cd47 FromOsprayTesting_TestScenesClipping_test_scenes_7.png.md5000066400000000000000000000000411464752671100361270ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX22f5e96e0df54904029c892a9a537d172 FromOsprayTesting_TestScenesClipping_test_scenes_8.png.md5000066400000000000000000000000411464752671100361300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2bd891b1b29e6e755589bf4429f43f57b FromOsprayTesting_TestScenesClipping_test_scenes_9.png.md5000066400000000000000000000000411464752671100361310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX293e2b97821c1899ca87143f4006f6f10 FromOsprayTesting_TestScenesGeometry_test_scenes_0.png.md5000066400000000000000000000000411464752671100361460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2005fedac323e30b07b476741459fe6a1 FromOsprayTesting_TestScenesGeometry_test_scenes_1.png.md5000066400000000000000000000000411464752671100361470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27617c01f530413c30407133bf21fe1d0 FromOsprayTesting_TestScenesGeometry_test_scenes_10.png.md5000066400000000000000000000000411464752671100362270ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ea89a0c952bb99600620660db1bbeed2 FromOsprayTesting_TestScenesGeometry_test_scenes_11.png.md5000066400000000000000000000000411464752671100362300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX220517dbc5ff845a99c3b29c5784c49b4 FromOsprayTesting_TestScenesGeometry_test_scenes_12.png.md5000066400000000000000000000000411464752671100362310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c28ddf5f3311ee65d7ff407f805b8102 FromOsprayTesting_TestScenesGeometry_test_scenes_13.png.md5000066400000000000000000000000411464752671100362320ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21ac1f2a6c498298c406b484b9dbfa899 FromOsprayTesting_TestScenesGeometry_test_scenes_14.png.md5000066400000000000000000000000411464752671100362330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a8c24f4c3842e40d51bc949fa399c77e FromOsprayTesting_TestScenesGeometry_test_scenes_15.png.md5000066400000000000000000000000411464752671100362340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20dfc97c10a8a792e3ef01ca74c178b37 FromOsprayTesting_TestScenesGeometry_test_scenes_16.png.md5000066400000000000000000000000411464752671100362350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX258ba677634ec1377713746c59ad2f0fd FromOsprayTesting_TestScenesGeometry_test_scenes_17.png.md5000066400000000000000000000000411464752671100362360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b2623af89221f26ffc0e011c5fd3872b FromOsprayTesting_TestScenesGeometry_test_scenes_18.png.md5000066400000000000000000000000411464752671100362370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2eaa20d7198d250f7524d875075c65523 FromOsprayTesting_TestScenesGeometry_test_scenes_19.png.md5000066400000000000000000000000411464752671100362400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX23316de2400db72ab1d02bc48f069af5a FromOsprayTesting_TestScenesGeometry_test_scenes_2.png.md5000066400000000000000000000000411464752671100361500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29495604bd4f1d826adefafae768ad9ed FromOsprayTesting_TestScenesGeometry_test_scenes_20.png.md5000066400000000000000000000000411464752671100362300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21fce83c5e8a8e32884de61f06ef189fb FromOsprayTesting_TestScenesGeometry_test_scenes_21.png.md5000066400000000000000000000000411464752671100362310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX22784c3a40b4c304f2dd67a0d226de309 FromOsprayTesting_TestScenesGeometry_test_scenes_22.png.md5000066400000000000000000000000411464752671100362320ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20ee84a9176088792016e39e64ac96105 FromOsprayTesting_TestScenesGeometry_test_scenes_23.png.md5000066400000000000000000000000411464752671100362330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20597b0908477057233b26fdac50f8c30 FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5000066400000000000000000000000411464752671100362340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ca864845643d098c79e7df59405ebc91 FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5000066400000000000000000000000411464752671100362350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2004ae0a174778bd01ff345f2e2164e9c FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5000066400000000000000000000000411464752671100362360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c97734d3966425576e1c42efd57e8f95 FromOsprayTesting_TestScenesGeometry_test_scenes_27.png.md5000066400000000000000000000000411464752671100362370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25104654864fd04fa6ba385c8467f3810 FromOsprayTesting_TestScenesGeometry_test_scenes_28.png.md5000066400000000000000000000000411464752671100362400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25104654864fd04fa6ba385c8467f3810 FromOsprayTesting_TestScenesGeometry_test_scenes_29.png.md5000066400000000000000000000000411464752671100362410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25104654864fd04fa6ba385c8467f3810 FromOsprayTesting_TestScenesGeometry_test_scenes_3.png.md5000066400000000000000000000000411464752671100361510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b529a4853c8e6481d25d47e15089614f FromOsprayTesting_TestScenesGeometry_test_scenes_30.png.md5000066400000000000000000000000411464752671100362310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2726c140b625aad18f6d1b287a55c6340 FromOsprayTesting_TestScenesGeometry_test_scenes_31.png.md5000066400000000000000000000000411464752671100362320ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29129cebceccb69ae64697d391b735d09 FromOsprayTesting_TestScenesGeometry_test_scenes_32.png.md5000066400000000000000000000000411464752671100362330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX231385985c9ee9f55aa87089f474ad60c FromOsprayTesting_TestScenesGeometry_test_scenes_33.png.md5000066400000000000000000000000411464752671100362340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d1b38a834f0f3bdd0522d98d81f127d9 FromOsprayTesting_TestScenesGeometry_test_scenes_34.png.md5000066400000000000000000000000411464752671100362350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX281ac931116d29b98475e903006d4714a FromOsprayTesting_TestScenesGeometry_test_scenes_35.png.md5000066400000000000000000000000411464752671100362360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX209979f3ae2f9fb1dd7288f58b3e17d64 FromOsprayTesting_TestScenesGeometry_test_scenes_4.png.md5000066400000000000000000000000411464752671100361520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2449624037e1ef5de3c21708ab9f5adde FromOsprayTesting_TestScenesGeometry_test_scenes_5.png.md5000066400000000000000000000000411464752671100361530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d51688c1af06a8e5c99234e43660a8c1 FromOsprayTesting_TestScenesGeometry_test_scenes_6.png.md5000066400000000000000000000000411464752671100361540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX268978d538ec04f4c4d16f6875cca9028 FromOsprayTesting_TestScenesGeometry_test_scenes_7.png.md5000066400000000000000000000000411464752671100361550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX268978d538ec04f4c4d16f6875cca9028 FromOsprayTesting_TestScenesGeometry_test_scenes_8.png.md5000066400000000000000000000000411464752671100361560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX268978d538ec04f4c4d16f6875cca9028 FromOsprayTesting_TestScenesGeometry_test_scenes_9.png.md5000066400000000000000000000000411464752671100361570ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d61e4794d9dd832af6ac97069eba2152 FromOsprayTesting_TestScenesPtMaterials_test_scenes_0.png.md5000066400000000000000000000000411464752671100366000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX28cab6629d696874271f40b6aeef16c2f FromOsprayTesting_TestScenesPtMaterials_test_scenes_1.png.md5000066400000000000000000000000411464752671100366010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24dcd848b9983daf3c767e5deafbf9f4d FromOsprayTesting_TestScenesPtMaterials_test_scenes_10.png.md5000066400000000000000000000000411464752671100366610ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2526abce1184fef470d4fbbc88a819af3 FromOsprayTesting_TestScenesPtMaterials_test_scenes_11.png.md5000066400000000000000000000000411464752671100366620ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2dd5f24a7f1cca4df0f0aeacff6f7f8f2 FromOsprayTesting_TestScenesPtMaterials_test_scenes_12.png.md5000066400000000000000000000000411464752671100366630ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ba2076c08fe9c04c9811703f0113e40b FromOsprayTesting_TestScenesPtMaterials_test_scenes_13.png.md5000066400000000000000000000000411464752671100366640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ede14f22d0bb44aa9b45d760c2f2db5f FromOsprayTesting_TestScenesPtMaterials_test_scenes_14.png.md5000066400000000000000000000000411464752671100366650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ba93b3138b7374632b3bd743c6a727d0 FromOsprayTesting_TestScenesPtMaterials_test_scenes_15.png.md5000066400000000000000000000000411464752671100366660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX297b3c16126913a972af4021d729a0f6c FromOsprayTesting_TestScenesPtMaterials_test_scenes_2.png.md5000066400000000000000000000000411464752671100366020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e76c8d0f5acf92bfff4c1ade75113f7d FromOsprayTesting_TestScenesPtMaterials_test_scenes_3.png.md5000066400000000000000000000000411464752671100366030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f288be1d0a1d78e13994c2cd21514c07 FromOsprayTesting_TestScenesPtMaterials_test_scenes_4.png.md5000066400000000000000000000000411464752671100366040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21d2f685f33019946fcf4204e3189086b FromOsprayTesting_TestScenesPtMaterials_test_scenes_5.png.md5000066400000000000000000000000411464752671100366050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX243ea7782bc77f8138fc68cae9594131d FromOsprayTesting_TestScenesPtMaterials_test_scenes_6.png.md5000066400000000000000000000000411464752671100366060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24357f8d3b44d73ecf49425354092239a FromOsprayTesting_TestScenesPtMaterials_test_scenes_7.png.md5000066400000000000000000000000411464752671100366070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25f5e4418047852b8be5270816e745fd8 FromOsprayTesting_TestScenesPtMaterials_test_scenes_8.png.md5000066400000000000000000000000411464752671100366100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e037f67b56f57fdd81930473eb993261 FromOsprayTesting_TestScenesPtMaterials_test_scenes_9.png.md5000066400000000000000000000000411464752671100366110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20667d0c04af94a41f6d2fc9fdcddf860 FromOsprayTesting_TestScenesVolumesStrictParams_test_scenes_0.png.md5000066400000000000000000000000411464752671100403420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b061e43c1f11a436cb2679f76369cfe6 FromOsprayTesting_TestScenesVolumesStrictParams_test_scenes_1.png.md5000066400000000000000000000000411464752671100403430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a8aa6c7b3ad7d899415460b772d7f6a3 FromOsprayTesting_TestScenesVolumesStrictParams_test_scenes_2.png.md5000066400000000000000000000000411464752671100403440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f1ec979e88d9b97b38efeb8d702577f4 FromOsprayTesting_TestScenesVolumes_test_scenes_0.png.md5000066400000000000000000000000411464752671100360050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX261007e9e7617dc49a8c2a2c69a5e27c9 FromOsprayTesting_TestScenesVolumes_test_scenes_1.png.md5000066400000000000000000000000411464752671100360060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d64809a94e3bf00feff142823d336267 FromOsprayTesting_TestScenesVolumes_test_scenes_10.png.md5000066400000000000000000000000411464752671100360660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27e6f247a833d34986cc7a48b31110d50 FromOsprayTesting_TestScenesVolumes_test_scenes_11.png.md5000066400000000000000000000000411464752671100360670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2bc80d51afd2d942022b1820dbc7f84e2 FromOsprayTesting_TestScenesVolumes_test_scenes_12.png.md5000066400000000000000000000000411464752671100360700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e9255f5d5978373819db855bfbaacd6e FromOsprayTesting_TestScenesVolumes_test_scenes_13.png.md5000066400000000000000000000000411464752671100360710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29f6e34fa38a366a461af4aac6693247f FromOsprayTesting_TestScenesVolumes_test_scenes_14.png.md5000066400000000000000000000000411464752671100360720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27b861d9ded7e810b8411ff5bf208bc30 FromOsprayTesting_TestScenesVolumes_test_scenes_15.png.md5000066400000000000000000000000411464752671100360730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e9255f5d5978373819db855bfbaacd6e FromOsprayTesting_TestScenesVolumes_test_scenes_16.png.md5000066400000000000000000000000411464752671100360740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29f6e34fa38a366a461af4aac6693247f FromOsprayTesting_TestScenesVolumes_test_scenes_17.png.md5000066400000000000000000000000411464752671100360750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27b861d9ded7e810b8411ff5bf208bc30 FromOsprayTesting_TestScenesVolumes_test_scenes_18.png.md5000066400000000000000000000000411464752671100360760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX29e6bfa920c7579632fd07ae633fde44a FromOsprayTesting_TestScenesVolumes_test_scenes_19.png.md5000066400000000000000000000000411464752671100360770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2bc4637abfad0b5e4823fe08dde4cc6bd FromOsprayTesting_TestScenesVolumes_test_scenes_2.png.md5000066400000000000000000000000411464752671100360070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX258aaddd509d364794807a2ffe2d058e5 FromOsprayTesting_TestScenesVolumes_test_scenes_20.png.md5000066400000000000000000000000411464752671100360670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX211d2216fd034fd9babfa629a935bf9f7 FromOsprayTesting_TestScenesVolumes_test_scenes_3.png.md5000066400000000000000000000000411464752671100360100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX244413ed71090df5f96d4cb12c0c95a43 FromOsprayTesting_TestScenesVolumes_test_scenes_4.png.md5000066400000000000000000000000411464752671100360110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX228641a39813622d38fcf423f44b1e78e FromOsprayTesting_TestScenesVolumes_test_scenes_5.png.md5000066400000000000000000000000411464752671100360120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f89eae18f4cb2a962a4d56f1dea8d28a FromOsprayTesting_TestScenesVolumes_test_scenes_6.png.md5000066400000000000000000000000411464752671100360130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2df3ff32830e74a7b3a8c43f3ea7f3c74 FromOsprayTesting_TestScenesVolumes_test_scenes_7.png.md5000066400000000000000000000000411464752671100360140ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f45e922ba3792f81694fa33746774036 FromOsprayTesting_TestScenesVolumes_test_scenes_8.png.md5000066400000000000000000000000411464752671100360150ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX23ae4d676399496d32187fa45a65f36d1 FromOsprayTesting_TestScenesVolumes_test_scenes_9.png.md5000066400000000000000000000000411464752671100360160ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24acc73d6c90c381efafe80e17251be54 FromOsprayTesting_Transparency_test_scenes_0.png.md5000066400000000000000000000000411464752671100350230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fb91084d1376b9c4b30a18a55365acd3 FromOsprayTesting_Transparency_test_scenes_1.png.md5000066400000000000000000000000411464752671100350240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX277bd568bc2bff5ff6b38c036796fd38d FromOsprayTesting_Transparency_test_scenes_2.png.md5000066400000000000000000000000411464752671100350250ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24865efcd3563cd954cdcdc887e1bead8 GeometricLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100343440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d890634b6f26ef2c69b8201c300785ec GeometricLight_LightMotionBlur_parameter_1.png.md5000066400000000000000000000000411464752671100343450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d890634b6f26ef2c69b8201c300785ec GeometricLight_LightTexture_parameter_0.png.md5000066400000000000000000000000411464752671100337120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e424922846ea4839865963033d75c402 GeometricLight_LightTexture_parameter_1.png.md5000066400000000000000000000000411464752671100337130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20e75cf118c97b5bfa55a129dba58c053 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100324100ustar00rootroot00000000000000e3dc72cf23fd9f39a0a341016a5d4b6a RenderKit-ospray-85af292/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100324110ustar00rootroot00000000000000e3dc72cf23fd9f39a0a341016a5d4b6a RenderKit-ospray-85af292/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100324120ustar00rootroot00000000000000bcf2e967bdc255d6007ec23237e65efd RenderKit-ospray-85af292/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100324130ustar00rootroot00000000000000bcf2e967bdc255d6007ec23237e65efd RenderKit-ospray-85af292/test_image_data/baseline/AVX2/HDRILight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100332330ustar00rootroot00000000000000c729d5345a0200e8cffc76e3870b2ef5 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/HDRILight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100312200ustar00rootroot000000000000001ced2b13d85f1759f41fa08af148ac64 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/HDRILight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100312210ustar00rootroot00000000000000b908fa2b10882cf56cb1f67375a3528c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_0.png.md5000066400000000000000000000000411464752671100324220ustar00rootroot0000000000000062cb7747142a598ef3806d8d8a2e7823 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_1.png.md5000066400000000000000000000000411464752671100324230ustar00rootroot00000000000000bee384f4fc25b57eba970612c0c439b3 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_2.png.md5000066400000000000000000000000411464752671100324240ustar00rootroot00000000000000c0964106cdfe0c4a236d432f15171a42 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_3.png.md5000066400000000000000000000000411464752671100324250ustar00rootroot00000000000000db162b8988ca2836706f3ddae736864a RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_4.png.md5000066400000000000000000000000411464752671100324260ustar00rootroot00000000000000c6f4ed5204ffa824d07ded1f238e552d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_5.png.md5000066400000000000000000000000411464752671100324270ustar00rootroot000000000000006ee8cc7d67dcba7e0b12a1f8ce623288 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_6.png.md5000066400000000000000000000000411464752671100324300ustar00rootroot000000000000005b901adfdeda0cf1bbf60ed834801acf RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_ObjectInstance_IDBuffer_7.png.md5000066400000000000000000000000411464752671100324310ustar00rootroot00000000000000638e987fa9568bfc7e9b4243b9c5847c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_Primitive_IDBuffer_0.png.md5000066400000000000000000000000411464752671100314770ustar00rootroot00000000000000a635c7fdb9cb0394917fa7d5369722a6 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/IDBuffer_Primitive_IDBuffer_1.png.md5000066400000000000000000000000411464752671100315000ustar00rootroot00000000000000c99f42dc0a364cdfc4e1dc347a2a84ed RenderKit-ospray-85af292/test_image_data/baseline/AVX2/ImageOp_DebugOp_ImageOp_0.png.md5000066400000000000000000000000411464752671100306420ustar00rootroot00000000000000ad46f14985a97628abd2de4ea4276f6f RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_0.png.md5000066400000000000000000000000411464752671100332070ustar00rootroot000000000000005ac362cb64845079f85d60c53237a30c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_1.png.md5000066400000000000000000000000411464752671100332100ustar00rootroot00000000000000600f9a78e23df4b21ef1cb3576c41293 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_2.png.md5000066400000000000000000000000411464752671100332110ustar00rootroot00000000000000b96e5ad22db82abfd7a96bb718b39d2c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_3.png.md5000066400000000000000000000000411464752671100332120ustar00rootroot0000000000000037bb390a60b0bfcfa5eefd11c5417400 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_4.png.md5000066400000000000000000000000411464752671100332130ustar00rootroot000000000000002dcf960bb59871a4576a24a6fa313875 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_5.png.md5000066400000000000000000000000411464752671100332140ustar00rootroot000000000000002219c6429c336540493059ba4dd21a5b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_6.png.md5000066400000000000000000000000411464752671100332150ustar00rootroot00000000000000b96e5ad22db82abfd7a96bb718b39d2c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Color_Interpolation_7.png.md5000066400000000000000000000000411464752671100332160ustar00rootroot0000000000000037bb390a60b0bfcfa5eefd11c5417400 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Normal_Interpolation_0.png.md5000066400000000000000000000000411464752671100333610ustar00rootroot00000000000000b46e1e25fabdba9962cdb1fa797ead04 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Interpolation_Normal_Interpolation_1.png.md5000066400000000000000000000000411464752671100333620ustar00rootroot0000000000000073b536d10b031c419a7f3acde81851df Interpolation_Texcoord_Interpolation_0.png.md5000066400000000000000000000000411464752671100336410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a5952191d40359ec2caef22b16dd59e9 Interpolation_Texcoord_Interpolation_1.png.md5000066400000000000000000000000411464752671100336420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b74cb26446f638d39b4395fcc3cc761a Interpolation_Texcoord_Interpolation_2.png.md5000066400000000000000000000000411464752671100336430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25791e0b989fba970b48521d80f3d997a Interpolation_Texcoord_Interpolation_3.png.md5000066400000000000000000000000411464752671100336440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a7f87e630b9b82e8e44eca2d6d6798f5 MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5000066400000000000000000000000411464752671100404030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c11af06b7ed875a6b87d1a5de0427d91 MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5000066400000000000000000000000411464752671100404040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX23da593a811d23760b111dc55c6fd93d6 MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5000066400000000000000000000000411464752671100404050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a67563d886598cc3ac2be9fdf494308a MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5000066400000000000000000000000411464752671100402420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX256338fcff16d21ad86271e3f85052436 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5000066400000000000000000000000411464752671100402430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e5c2467727ae66a9744b8cbb517d606e MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5000066400000000000000000000000411464752671100402440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25776518b2bec1f324f15c2ae3ef504a1 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5000066400000000000000000000000411464752671100402450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c76793fe11e0bfdb7f43fd0e8999b63e MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5000066400000000000000000000000411464752671100402460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fcf630625ed9a4645b6937030b802c73 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5000066400000000000000000000000411464752671100402470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2ce646854a5c595b1f7b009c40c256684 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5000066400000000000000000000000411464752671100402500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX201b17a8669d5be94696470962fcd1389 MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5000066400000000000000000000000411464752671100360470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e09a7f947946e09944af1c0ee8eb3225 MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5000066400000000000000000000000411464752671100360500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX284a327f24353d9c16b1f57cdf8738c52 MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5000066400000000000000000000000411464752671100360510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c1a6af91c50b68c06f8d97b4316f1279 MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5000066400000000000000000000000411464752671100360520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX224b27522f08c8d46b384b0c3ac834133 MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5000066400000000000000000000000411464752671100360530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27f1ca47683d8f2a8398e66e2a9a78dde MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5000066400000000000000000000000411464752671100360540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24e17234519beab039e833d481d74cf1f MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5000066400000000000000000000000411464752671100360550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2abe391f40c73fd61fee52307bbb1ff6c MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5000066400000000000000000000000411464752671100360560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2bd05dcc671fe72f741659d8438901ac6 MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5000066400000000000000000000000411464752671100372310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24f9858dff7a78b5ae508fcaf272d3795 MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5000066400000000000000000000000411464752671100347030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX220fdf05b9a77272b90133e3f2e177dce MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5000066400000000000000000000000411464752671100347040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21d093c1334f74362931d235a587b86c2 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_CameraOrtho_camera_mb_0.png.md5000066400000000000000000000000411464752671100331430ustar00rootroot00000000000000f21af1f2c408a2359254f34dc9fba77f MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5000066400000000000000000000000411464752671100361400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21ae7ba722d04dbb8c319d8018173fa1d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_0.png.md5000066400000000000000000000000411464752671100321270ustar00rootroot000000000000008b08da5bd0636a80a526846d2b6f51c9 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_1.png.md5000066400000000000000000000000411464752671100321300ustar00rootroot00000000000000a3757e91aeffc07c32406ff4ae930530 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_2.png.md5000066400000000000000000000000411464752671100321310ustar00rootroot000000000000006f5072460b8a2d60c4081de05e422347 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_3.png.md5000066400000000000000000000000411464752671100321320ustar00rootroot000000000000007140a6437c7ddf9a7939f31bfd2ed11f RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_4.png.md5000066400000000000000000000000411464752671100321330ustar00rootroot00000000000000a73fc912b5de42ebaa66d13169353591 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_5.png.md5000066400000000000000000000000411464752671100321340ustar00rootroot0000000000000067559d0c14af7c4fd2cd392fc29f9b13 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_6.png.md5000066400000000000000000000000411464752671100321350ustar00rootroot0000000000000021ca5f70a74e4209e6707f02da1896b8 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_7.png.md5000066400000000000000000000000411464752671100321360ustar00rootroot000000000000009d42974498897ad5936846ceb6ebafe1 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_8.png.md5000066400000000000000000000000411464752671100321370ustar00rootroot000000000000002f2a9890c1cb8fd9d72689814e64ea68 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_9.png.md5000066400000000000000000000000411464752671100321400ustar00rootroot00000000000000405361d8e6cde7f8278a2466b101a990 PTBackgroundRefraction_Appearance_backgroundRefraction_0.png.md5000066400000000000000000000000411464752671100371270ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24ff8f25e4eb2e84c0b469a5d43e18b44 PTBackgroundRefraction_Appearance_backgroundRefraction_1.png.md5000066400000000000000000000000411464752671100371300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX283fd955d6b4d2e213aec962d761218cd RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100327670ustar00rootroot00000000000000e3b9cc2abb4828e6183db2717a282b05 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100327700ustar00rootroot0000000000000055009c40fefcd4eb6ebf0c5467d1e6f5 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_10.png.md5000066400000000000000000000000411464752671100330500ustar00rootroot00000000000000897322dcba60a3738bb35a161f68a266 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_11.png.md5000066400000000000000000000000411464752671100330510ustar00rootroot000000000000007c7ebd0441e73b86455662920b3f5a04 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100327710ustar00rootroot0000000000000042f7b6f0bb4b17ebd2d6e2d6dfeb5a52 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100327720ustar00rootroot000000000000009122d64d2343b2ebcc7aeba86a1d3086 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_4.png.md5000066400000000000000000000000411464752671100327730ustar00rootroot0000000000000097fe194b2dcbd54d45e391449c514b4d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_5.png.md5000066400000000000000000000000411464752671100327740ustar00rootroot0000000000000044328cc612a40a65c2a8e37db15d3e32 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_6.png.md5000066400000000000000000000000411464752671100327750ustar00rootroot0000000000000063b0136d8b074c034affacc4b7545f45 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_7.png.md5000066400000000000000000000000411464752671100327760ustar00rootroot000000000000007de1516a92e6baaa83a47efd60a53086 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_8.png.md5000066400000000000000000000000411464752671100327770ustar00rootroot000000000000002c562fee621fe1043fed6bc04d187d5d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PhotometricLight_Light_parameter_9.png.md5000066400000000000000000000000411464752671100330000ustar00rootroot00000000000000089632b7f534d6b787f719c935c55a36 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_0.png.md5000066400000000000000000000000411464752671100310510ustar00rootroot000000000000002c04102ec0eb17bb823b00d08929f03c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_1.png.md5000066400000000000000000000000411464752671100310520ustar00rootroot000000000000002c5faba08250fdf541f4ad032e55711e RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_2.png.md5000066400000000000000000000000411464752671100310530ustar00rootroot00000000000000fe60964b25a399e4e814fcf64493e229 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_3.png.md5000066400000000000000000000000411464752671100310540ustar00rootroot000000000000003c7c73b43d9567f30beac9654ec6381f RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_4.png.md5000066400000000000000000000000411464752671100310550ustar00rootroot00000000000000e4563a35246501e98b85e2e6d831423b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_5.png.md5000066400000000000000000000000411464752671100310560ustar00rootroot000000000000002c04102ec0eb17bb823b00d08929f03c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_6.png.md5000066400000000000000000000000411464752671100310570ustar00rootroot00000000000000de37bf660f226d6cf4df1eb7a90be7d2 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_7.png.md5000066400000000000000000000000411464752671100310600ustar00rootroot0000000000000041b6e7f412a09c4eedc41de34c502727 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_8.png.md5000066400000000000000000000000411464752671100310610ustar00rootroot000000000000007bc51c940ede9fd6b99620fab3547a9d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/PixelFilter_Camera_test_9.png.md5000066400000000000000000000000411464752671100310620ustar00rootroot00000000000000281cf4e902bce79665ef864ccd6e08eb QuadLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100347530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX27a4647314d9e9fe52cc60f0cd88e7cc5 QuadLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100347540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX290428918977c596a76589c7e8f514b44 QuadLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100347550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20557938f2fb0111a3d89c6f18ea91cc9 QuadLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100347560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d702aa0664374d07a45294a61df22e57 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/QuadLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100333770ustar00rootroot00000000000000c14d9428c60f7f525590d4d84bfabf02 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/QuadLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100313640ustar00rootroot00000000000000d2e25a08e5f62467fff8017df239e7de RenderKit-ospray-85af292/test_image_data/baseline/AVX2/QuadLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100313650ustar00rootroot00000000000000d6dda669082cf67864c7408e7a81ec9c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/QuadLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100313660ustar00rootroot0000000000000075bc399da6fce8ceb64cab63777bd52d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/QuadLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100313670ustar00rootroot00000000000000933a54ee091711fcd8f39ef32605cea8 RendererMaterialList_MaterialLists_material_list_0.png.md5000066400000000000000000000000411464752671100360630ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX26c47ba3fd337d73f44ac05ef4767e046 RendererMaterialList_MaterialLists_material_list_1.png.md5000066400000000000000000000000411464752671100360640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2616d58357cf8ad2a950296ad7c81106d SphereLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100353070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a591333c14e5cb8ebe2b4ac8ef0e1a94 SphereLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100353100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21435a54d9a9511b4ee4a435166d11c8a SphereLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100353110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b22ea36cd0e4cdba968936a19f7883d6 SphereLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100353120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25fd4b0854345dfba7ecc4879cb78dc8f SphereLight_LightIntensityQuantity_parameter_4.png.md5000066400000000000000000000000411464752671100353130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX240d43cba12b84988edaa4b5996593ff1 SphereLight_LightIntensityQuantity_parameter_5.png.md5000066400000000000000000000000411464752671100353140ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2887aa3ac4e41aadce524615e6987a3f0 SphereLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100336540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2eac49e507d0881385bf51e8f65e6dafa RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SphereLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100317200ustar00rootroot0000000000000058a17cd519c8b5b62b1040d7f5c5f177 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SphereLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100317210ustar00rootroot00000000000000e61c3cac8839e449c1b0b9c8b430020a RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SphereLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100317220ustar00rootroot00000000000000112f3bac4b5b2f01e8fc45c3ac9d182b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SphereLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100317230ustar00rootroot000000000000009c63f65a1905e6c14064f9ab1282b662 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SphereLight_Light_parameter_4.png.md5000066400000000000000000000000411464752671100317240ustar00rootroot00000000000000ab51df87fb122cd035dbc171e375b92f RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SphereLight_Light_parameter_5.png.md5000066400000000000000000000000411464752671100317250ustar00rootroot00000000000000f6916b40a6519526299b5524ad9f0d99 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_0.png.md5000066400000000000000000000000411464752671100335110ustar00rootroot00000000000000247ddc74d65ed8fac9fed9b0bf0d6654 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_1.png.md5000066400000000000000000000000411464752671100335120ustar00rootroot000000000000007df8cd62764727b3aefd892a550683fa SpherePrecision_Intersection_sphere_10.png.md5000066400000000000000000000000411464752671100335130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24e5e23b9beb42d5b372b0b69a9c579c8 SpherePrecision_Intersection_sphere_11.png.md5000066400000000000000000000000411464752671100335140ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX26a10cd33ff4abc7b207bdc948cac0fdc SpherePrecision_Intersection_sphere_12.png.md5000066400000000000000000000000411464752671100335150ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX220e20ace063e3344eda60e844851f79c SpherePrecision_Intersection_sphere_13.png.md5000066400000000000000000000000411464752671100335160ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX26bd64faa11a725b1c35a23d9725391cf SpherePrecision_Intersection_sphere_14.png.md5000066400000000000000000000000411464752671100335170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX28634d6c2195dfa036378d9431f78b813 SpherePrecision_Intersection_sphere_15.png.md5000066400000000000000000000000411464752671100335200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2227d77fb5290d6ff2cff00bfc525dfa9 SpherePrecision_Intersection_sphere_16.png.md5000066400000000000000000000000411464752671100335210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2debc5740bb229586592099eaaeae74d8 SpherePrecision_Intersection_sphere_17.png.md5000066400000000000000000000000411464752671100335220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c19fef9d5c659c81f12ef89ae58dab1c SpherePrecision_Intersection_sphere_18.png.md5000066400000000000000000000000411464752671100335230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f0425bbc4b5ec65d55ce9c5093de5826 SpherePrecision_Intersection_sphere_19.png.md5000066400000000000000000000000411464752671100335240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX295f76cc755a2db8de71858382c2e5a7e RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_2.png.md5000066400000000000000000000000411464752671100335130ustar00rootroot000000000000003f7a6f51e50dab15e6148a821ce14099 SpherePrecision_Intersection_sphere_20.png.md5000066400000000000000000000000411464752671100335140ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f0be432cab8ec1233e4fb8eacc06ef7f SpherePrecision_Intersection_sphere_21.png.md5000066400000000000000000000000411464752671100335150ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25aa6e40c6f18a9e7b5831daa94425322 SpherePrecision_Intersection_sphere_22.png.md5000066400000000000000000000000411464752671100335160ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21c4e067fbc26d4740ff619ed770fe987 SpherePrecision_Intersection_sphere_23.png.md5000066400000000000000000000000411464752671100335170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX22dd79444276864c14eef7c65d022a8c2 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_3.png.md5000066400000000000000000000000411464752671100335140ustar00rootroot000000000000004b0ab1c23a01cb486456dde45698e5e3 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_4.png.md5000066400000000000000000000000411464752671100335150ustar00rootroot0000000000000097423b29895c7436bdde98aef741d90c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_5.png.md5000066400000000000000000000000411464752671100335160ustar00rootroot000000000000009e059202107a1d709bb658c4a204c5a8 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_6.png.md5000066400000000000000000000000411464752671100335170ustar00rootroot000000000000004df08169693b761983b00113253e13ad RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_7.png.md5000066400000000000000000000000411464752671100335200ustar00rootroot000000000000000576a41dc1e1430d4574752adc9fc7a5 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_8.png.md5000066400000000000000000000000411464752671100335210ustar00rootroot00000000000000adf9c1c9fe5b15bdfdad395526ebff83 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpherePrecision_Intersection_sphere_9.png.md5000066400000000000000000000000411464752671100335220ustar00rootroot000000000000002eed09ba298369187b5b6eea2fd8d0c7 SpotLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100350060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a591333c14e5cb8ebe2b4ac8ef0e1a94 SpotLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100350070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2544c09110ab45a7ac602286c55e621c6 SpotLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100350100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2a95f3f3e5b327efe5eea3380b3fb6716 SpotLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100350110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d86e673c6d967180a1e3688f7284a2b5 SpotLight_LightIntensityQuantity_parameter_4.png.md5000066400000000000000000000000411464752671100350120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e94f91ea9687e4229507a1798e135970 SpotLight_LightIntensityQuantity_parameter_5.png.md5000066400000000000000000000000411464752671100350130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20088dfe601ea100002424d3b2714ad68 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100334320ustar00rootroot000000000000008a0f558e1f3e271d171bc1a63a5505bd RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100314170ustar00rootroot000000000000006e69c875527b92cc344b2255d49aa543 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100314200ustar00rootroot00000000000000fdc115503b6f13ded13d1700d530387a RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100314210ustar00rootroot000000000000002071ed754e6ced5c6d7c858700c90a96 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100314220ustar00rootroot000000000000003958644d7bf8e575f2f98b5dcfc04e57 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_4.png.md5000066400000000000000000000000411464752671100314230ustar00rootroot00000000000000c2ab237527996decfee4c902281c8a7d RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_5.png.md5000066400000000000000000000000411464752671100314240ustar00rootroot000000000000007f4f37bd2a26afa9fbe4fad121c6a8a3 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_6.png.md5000066400000000000000000000000411464752671100314250ustar00rootroot000000000000004f874be7c445cf60f39330914d2492b2 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_7.png.md5000066400000000000000000000000411464752671100314260ustar00rootroot00000000000000815dbb36620ce3d9fb67af16bc45c9b8 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_8.png.md5000066400000000000000000000000411464752671100314270ustar00rootroot00000000000000926746861e6dd78f7d5a9f03d670f617 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SpotLight_Light_parameter_9.png.md5000066400000000000000000000000411464752671100314300ustar00rootroot000000000000007e6d93e0b068f62197441d61aa42eaf6 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_0.png.md5000066400000000000000000000000411464752671100304050ustar00rootroot00000000000000a101b64cd3f63170e00890b65c8a5499 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_1.png.md5000066400000000000000000000000411464752671100304060ustar00rootroot0000000000000085bf732703518cfc9af270da6c5531c1 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_2.png.md5000066400000000000000000000000411464752671100304070ustar00rootroot00000000000000814b7d3d8e2e8fbc6ed539f0de1acf91 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_3.png.md5000066400000000000000000000000411464752671100304100ustar00rootroot000000000000006d15e4bcbdd9037dd5b72e442dc6cf93 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_4.png.md5000066400000000000000000000000411464752671100304110ustar00rootroot00000000000000216abc0d5abdfaa56b236bc2aaecf1bd RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_5.png.md5000066400000000000000000000000411464752671100304120ustar00rootroot0000000000000006e33d2badc11d81a02a6dda018f7e72 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_6.png.md5000066400000000000000000000000411464752671100304130ustar00rootroot00000000000000ffdbe2cb2e7a3b5cc958906ad8391021 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Stereo_Camera_stereo_7.png.md5000066400000000000000000000000411464752671100304140ustar00rootroot000000000000006aafd5dac141de5d94be9936c6f598be RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light2_parameter_0.png.md5000066400000000000000000000000411464752671100310200ustar00rootroot00000000000000d3d1f71a73213e21c0853cd2fb81ea14 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light2_parameter_1.png.md5000066400000000000000000000000411464752671100310210ustar00rootroot0000000000000030f6a8fed556c2144e82d6af3bf38413 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light2_parameter_2.png.md5000066400000000000000000000000411464752671100310220ustar00rootroot0000000000000003aada0ffd5f4d08794c04676b487c4b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light2_parameter_3.png.md5000066400000000000000000000000411464752671100310230ustar00rootroot00000000000000d4524ef0043c8b30d2d400305e40f555 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100327510ustar00rootroot000000000000009cf7f96c35bc92e830a17fc1dcd78732 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_0.png.md5000066400000000000000000000000411464752671100307360ustar00rootroot000000000000003e5b56f70cbfd4b75d06c58dae33318b RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_1.png.md5000066400000000000000000000000411464752671100307370ustar00rootroot00000000000000e761d9960abbcc86d6b56cc59a488e23 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_10.png.md5000066400000000000000000000000411464752671100310170ustar00rootroot00000000000000542f88cea0156ffeffe12bf2fdb4e624 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_11.png.md5000066400000000000000000000000411464752671100310200ustar00rootroot000000000000008bd2c59521aabd1b8fafb2aead66d5d0 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_12.png.md5000066400000000000000000000000411464752671100310210ustar00rootroot0000000000000010532d993fa72bbc1bdd55cbfa9d3bc3 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_13.png.md5000066400000000000000000000000411464752671100310220ustar00rootroot00000000000000aecfc8c25556df822ecd47353b9d4f66 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_14.png.md5000066400000000000000000000000411464752671100310230ustar00rootroot0000000000000001f1dc126f663ad542eb6ba2384945e7 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_2.png.md5000066400000000000000000000000411464752671100307400ustar00rootroot00000000000000156f6d2141cc34bf7e917d621ddcb333 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_3.png.md5000066400000000000000000000000411464752671100307410ustar00rootroot0000000000000030350a0d29420a0d0c8a295a05ca5c3a RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_4.png.md5000066400000000000000000000000411464752671100307420ustar00rootroot00000000000000e5c1dae4027b9620f3345fe074974e4c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_5.png.md5000066400000000000000000000000411464752671100307430ustar00rootroot00000000000000e7092c6f33a9236be32d9dabce7b5c85 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_6.png.md5000066400000000000000000000000411464752671100307440ustar00rootroot00000000000000e6bf2e10e28c4d5a5688464199904442 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_7.png.md5000066400000000000000000000000411464752671100307450ustar00rootroot00000000000000cab3383424c3cdc30688548e2e0f4ee7 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_8.png.md5000066400000000000000000000000411464752671100307460ustar00rootroot0000000000000092eec847bfceba0cb9a9d6683e4d2728 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/SunSky_Light_parameter_9.png.md5000066400000000000000000000000411464752671100307470ustar00rootroot00000000000000fa33379b0fa06fedb530f7189e06b780 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/TestAssignedCopy_deleterCallbacks.png.md5000066400000000000000000000000411464752671100326300ustar00rootroot00000000000000c38d798d36f03061d5a9fc0a0a3a3e6d TestUSMSharing_SharedData_structured_regular_0.png.md5000066400000000000000000000000411464752671100351410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b19ecf9ed96fa82be56387b70909b261 TestUSMSharing_SharedData_structured_regular_1.png.md5000066400000000000000000000000411464752671100351420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b19ecf9ed96fa82be56387b70909b261 TestUSMSharing_SharedData_structured_regular_2.png.md5000066400000000000000000000000411464752671100351430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b19ecf9ed96fa82be56387b70909b261 Texture2DMipMapping_MipMapCamera_mipMapping_0.png.md5000066400000000000000000000000411464752671100346010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMapCamera_mipMapping_1.png.md5000066400000000000000000000000411464752671100346020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX22ee8470860a4324347b07121c1fff1b5 Texture2DMipMapping_MipMapCamera_mipMapping_2.png.md5000066400000000000000000000000411464752671100346030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2f3bc031bb4e5a74b6829f7f64da066d5 Texture2DMipMapping_MipMapCamera_mipMapping_3.png.md5000066400000000000000000000000411464752671100346040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX242b1893f86f457c332f692bf7fcf21ef Texture2DMipMapping_MipMapCamera_mipMapping_4.png.md5000066400000000000000000000000411464752671100346050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2c5b9f0fb24ba92148fce4ebd096c0d80 Texture2DMipMapping_MipMapCamera_mipMapping_5.png.md5000066400000000000000000000000411464752671100346060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2139daf3374a4220f03b7f11eed96f90d Texture2DMipMapping_MipMapScale_mipMapping_0.png.md5000066400000000000000000000000411464752671100344400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMapScale_mipMapping_1.png.md5000066400000000000000000000000411464752671100344410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMap_mipMapping_0.png.md5000066400000000000000000000000411464752671100334700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2b3b6b8e4f9100e2b4c3eaae358eb5ba6 Texture2DMipMapping_MipMap_mipMapping_1.png.md5000066400000000000000000000000411464752671100334710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2452c6434d48d7e7cb3dbab35199e9f76 Texture2DMipMapping_MipMap_mipMapping_10.png.md5000066400000000000000000000000411464752671100335510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX249fe3bc99087e1dfe39d4510876da09d Texture2DMipMapping_MipMap_mipMapping_11.png.md5000066400000000000000000000000411464752671100335520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX22ccab6b423cde43e582fb6132884a17c Texture2DMipMapping_MipMap_mipMapping_2.png.md5000066400000000000000000000000411464752671100334720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX205206347a52342a4cdfc5870024aaaf9 Texture2DMipMapping_MipMap_mipMapping_3.png.md5000066400000000000000000000000411464752671100334730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24d006becc5c732ec9ee34a7c2d5711a6 Texture2DMipMapping_MipMap_mipMapping_4.png.md5000066400000000000000000000000411464752671100334740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX202c55729dd57be28d2dcffb0156d4ffd Texture2DMipMapping_MipMap_mipMapping_5.png.md5000066400000000000000000000000411464752671100334750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX24898d5af5acc6885e06365ec3c6efd73 Texture2DMipMapping_MipMap_mipMapping_6.png.md5000066400000000000000000000000411464752671100334760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25f6b35405e089aa666d96e3b8a0ebb26 Texture2DMipMapping_MipMap_mipMapping_7.png.md5000066400000000000000000000000411464752671100334770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2fbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMap_mipMapping_8.png.md5000066400000000000000000000000411464752671100335000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2d3ff011da4f7ab85082d113bc509ddd7 Texture2DMipMapping_MipMap_mipMapping_9.png.md5000066400000000000000000000000411464752671100335010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX279aac9a9f73b8db960983083223ecde4 Texture2DTransform_Appearance_simple_0.png.md5000066400000000000000000000000411464752671100334460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX23614ce01a214ecd1e4ff942ebe51162f RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2DWrapMode_Appearance_wrap_0.png.md5000066400000000000000000000000401464752671100327470ustar00rootroot0000000000000097731c498a8be29419817d89b04f2dbfRenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2DWrapMode_Appearance_wrap_1.png.md5000066400000000000000000000000401464752671100327500ustar00rootroot00000000000000878d5bb7e434080a24a9c284068041dbRenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2DWrapMode_Appearance_wrap_2.png.md5000066400000000000000000000000411464752671100327520ustar00rootroot0000000000000048e6abc7ca47afba486dfa7931720474 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2DWrapMode_Appearance_wrap_3.png.md5000066400000000000000000000000411464752671100327530ustar00rootroot000000000000009ebc5695b54d4f49fc1efb2b7f9424b8 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_AppearanceMipMap_filter_0.png.md5000066400000000000000000000000411464752671100327310ustar00rootroot00000000000000d4c0b806767e8c1c602119eb8a9b518f RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_AppearanceMipMap_filter_1.png.md5000066400000000000000000000000411464752671100327320ustar00rootroot0000000000000033e33e036c76a22c54e8ef50c09624de RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_AppearanceMipMap_filter_2.png.md5000066400000000000000000000000411464752671100327330ustar00rootroot00000000000000a72c557405989810433e6e224c24620e RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_AppearanceMipMap_filter_3.png.md5000066400000000000000000000000411464752671100327340ustar00rootroot0000000000000038a6d498ee18df22cc4ae0327dd7a1fc RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_0.png.md5000066400000000000000000000000411464752671100316250ustar00rootroot00000000000000d85b631ed7db2cf505751fff15f1a468 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_1.png.md5000066400000000000000000000000411464752671100316260ustar00rootroot00000000000000d85b631ed7db2cf505751fff15f1a468 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_2.png.md5000066400000000000000000000000411464752671100316270ustar00rootroot000000000000009e80fd2d73f0f6f91741679f43a4a093 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_3.png.md5000066400000000000000000000000411464752671100316300ustar00rootroot000000000000009e80fd2d73f0f6f91741679f43a4a093 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_4.png.md5000066400000000000000000000000411464752671100316310ustar00rootroot00000000000000abf592aa4f38e18c149e190f425e2b20 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_5.png.md5000066400000000000000000000000411464752671100316320ustar00rootroot00000000000000abf592aa4f38e18c149e190f425e2b20 RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_6.png.md5000066400000000000000000000000411464752671100316330ustar00rootroot000000000000000a473e6f77ebe81502c06f10cd055b5c RenderKit-ospray-85af292/test_image_data/baseline/AVX2/Texture2D_Appearance_filter_7.png.md5000066400000000000000000000000411464752671100316340ustar00rootroot000000000000000a473e6f77ebe81502c06f10cd055b5c TextureVolumeTransform_Renderers_simple_0.png.md5000066400000000000000000000000411464752671100343420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25ca76f28d3cca6fdf5b3037ac1da64fc TextureVolumeTransform_deprecated_Renderers_simple_0.png.md5000066400000000000000000000000411464752671100365220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25ca76f28d3cca6fdf5b3037ac1da64fc UnstructuredVolume_TestScenesVolumes_simple_0.png.md5000066400000000000000000000000411464752671100352170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2e84d5badebebaab3d5c24c5706707e91 UnstructuredVolume_TestScenesVolumes_simple_1.png.md5000066400000000000000000000000411464752671100352200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX21b32c9097c03764a947ccb916ce5a1e2 UnstructuredVolume_TestScenesVolumes_simple_2.png.md5000066400000000000000000000000411464752671100352210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX20985056e376af1dbbf72818dde10613c UnstructuredVolume_TestScenesVolumes_simple_3.png.md5000066400000000000000000000000411464752671100352220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX25a5ebc39ddcc3a2f3355ef3bc5ae5753 UnstructuredVolume_TestScenesVolumes_simple_4.png.md5000066400000000000000000000000411464752671100352230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX26572ac88ba74b7b4ac97ea8fc0e7469f UnstructuredVolume_TestScenesVolumes_simple_5.png.md5000066400000000000000000000000411464752671100352240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX2361ab2e6a1e005d20400fd02bf9f42fd RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/000077500000000000000000000000001464752671100234435ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/AmbientLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100326050ustar00rootroot0000000000000067daf471b763cf03d3b0d17226f5a166 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/AmbientLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100326060ustar00rootroot00000000000000aa59d7082ec8cb93dfc9b95cb01cf37d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/ClippingParallel_planes.png.md5000066400000000000000000000000411464752671100314140ustar00rootroot0000000000000024936b121705fd9cc9fdc59c216a1c53 Curves_TestScenesGeometry_test_scenes_0.png.md5000066400000000000000000000000411464752671100345120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX882ba977f68b0815293c44d604618fb8 Curves_TestScenesGeometry_test_scenes_1.png.md5000066400000000000000000000000411464752671100345130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa22b984373be41e86feff5b2a4121b49 Curves_TestScenesGeometry_test_scenes_10.png.md5000066400000000000000000000000411464752671100345730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7441623be7aafd6b19f70fbc69d89fc1 Curves_TestScenesGeometry_test_scenes_11.png.md5000066400000000000000000000000411464752671100345740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0fc866fc4291ff9f79a1f64571cd134a Curves_TestScenesGeometry_test_scenes_12.png.md5000066400000000000000000000000411464752671100345750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa2e926faa3c76d63aaa1aef9dede7ec0 Curves_TestScenesGeometry_test_scenes_13.png.md5000066400000000000000000000000411464752671100345760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX422f6f8d2a4805b7e3b42e2cdae8eeea Curves_TestScenesGeometry_test_scenes_14.png.md5000066400000000000000000000000411464752671100345770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2a7cf802e75f7efb90fbaf7f8457c1d8 Curves_TestScenesGeometry_test_scenes_15.png.md5000066400000000000000000000000411464752671100346000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4dcd72951efa109e66baf42d74326654 Curves_TestScenesGeometry_test_scenes_16.png.md5000066400000000000000000000000411464752671100346010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa1d1028d099c8cf32ab813c826058b32 Curves_TestScenesGeometry_test_scenes_17.png.md5000066400000000000000000000000411464752671100346020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfc3e7ad06241fc50d397870252d495ae Curves_TestScenesGeometry_test_scenes_18.png.md5000066400000000000000000000000411464752671100346030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX917bce6953c64095755c5583c53fb6b5 Curves_TestScenesGeometry_test_scenes_19.png.md5000066400000000000000000000000411464752671100346040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX43a4e65c47032d6201fe1e347a19f1ef Curves_TestScenesGeometry_test_scenes_2.png.md5000066400000000000000000000000411464752671100345140ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa1e97368016cd291e17e4e1cac325234 Curves_TestScenesGeometry_test_scenes_20.png.md5000066400000000000000000000000411464752671100345740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX043c3d27a805f43b8da9321e2e59e22c Curves_TestScenesGeometry_test_scenes_3.png.md5000066400000000000000000000000411464752671100345150ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX448c61a8278f76a94c2ae633b3f2359b Curves_TestScenesGeometry_test_scenes_4.png.md5000066400000000000000000000000411464752671100345160ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc6309ef9c9ebcae988e05694dc05c2e7 Curves_TestScenesGeometry_test_scenes_5.png.md5000066400000000000000000000000411464752671100345170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb5ffc718870ba5359b30c7aaa4ea9382 Curves_TestScenesGeometry_test_scenes_6.png.md5000066400000000000000000000000411464752671100345200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX38c517740d03a70167bea3951d53ab30 Curves_TestScenesGeometry_test_scenes_7.png.md5000066400000000000000000000000411464752671100345210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf427e56260493351bba7e022486a1587 Curves_TestScenesGeometry_test_scenes_8.png.md5000066400000000000000000000000411464752671100345220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa7c662a4681783bd466a6e864d538d55 Curves_TestScenesGeometry_test_scenes_9.png.md5000066400000000000000000000000411464752671100345230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf70f5b320125c2b5363e7783ab4a8b06 CylinderLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100363660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX73ed3d47eeac3a9b6fc673060c1c5328 CylinderLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100363670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4a7ebb5f6043f46912d9b1c4f35499bf CylinderLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100363700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3ea087abfcc25b0ae4c7be49462e4c78 CylinderLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100363710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe4ed1ed1f60faca8502105cbe2291a95 CylinderLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100347330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXdac74a13cc7f155a14b31ad33ec9b3c4 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100327770ustar00rootroot0000000000000011b1e39e738a027d748ed001602cf13d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100330000ustar00rootroot0000000000000084a7c4de39de086a654eda24ea5a141d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100330010ustar00rootroot000000000000000e5e30af1a3e4c3e352e2af2996697be RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100330020ustar00rootroot00000000000000a600e9c329322c20bd93995c4cf2ce9e DenoiserOp_DenoiserOp_DenoiserOp_0.png.md5000066400000000000000000000000411464752671100333150ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXded988069e8394b26dbe0ea554b4149b DenoiserOp_DenoiserOp_DenoiserOp_1.png.md5000066400000000000000000000000411464752671100333160ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe9e4a9c5dee535fe8e7996a519b67156 DenoiserOp_DenoiserOp_DenoiserOp_2.png.md5000066400000000000000000000000411464752671100333170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc384bd9efbe58c20f14dd01d73f0b069 DenoiserOp_DenoiserOp_DenoiserOp_3.png.md5000066400000000000000000000000411464752671100333200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX69041af4dcb8bce523679bcb5f7436d4 DenoiserOp_DenoiserOp_DenoiserOp_4.png.md5000066400000000000000000000000411464752671100333210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX6278286a6b4504277e4420ade3aebc9b DenoiserOp_DenoiserOp_DenoiserOp_5.png.md5000066400000000000000000000000411464752671100333220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc75f4ef7cb81362bdf1f9a37033faf77 DepthCompositeVolume_Renderers_simple_0.png.md5000066400000000000000000000000411464752671100344710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX642603a3031518fe9f21bf6d07835528 DepthCompositeVolume_Renderers_simple_1.png.md5000066400000000000000000000000411464752671100344720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa48a2b26a51f0ccab651ef1dfa48c061 DepthCompositeVolume_Renderers_simple_2.png.md5000066400000000000000000000000411464752671100344730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX56089ffe487951c01a12eb629198ed8e DepthCompositeVolume_Renderers_simple_3.png.md5000066400000000000000000000000411464752671100344740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXff857fab1a8f9325760f08851316501b DistantLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100345700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX323173a42d4f374d660cffaf5ec2df44 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/DistantLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100326340ustar00rootroot0000000000000012c66430113874ba4d795c2a5335f897 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/DistantLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100326350ustar00rootroot00000000000000d2851bae6777011ed87fa5b6d64ff7c8 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/DistantLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100326360ustar00rootroot00000000000000368189c68d2e689d830a566c6880a839 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/DistantLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100326370ustar00rootroot000000000000004cb53696a83b0c7326c6888c002828a3 FromOsprayTestingLightSamples_TestScenesLightSamples_testScenes_0.png.md5000066400000000000000000000000411464752671100416210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX229965d72a3a5a964302dbd8395ebc1d FromOsprayTestingLightSamples_TestScenesLightSamples_testScenes_1.png.md5000066400000000000000000000000411464752671100416220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX8b083f2e31e097dbfc51568d4cc80e5b FromOsprayTestingMaxDepth_TestScenesMaxDepth_test_scenes_0.png.md5000066400000000000000000000000411464752671100402540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7b145567101fa685ef4fd3d9318e0ab8 FromOsprayTestingMaxDepth_TestScenesMaxDepth_test_scenes_1.png.md5000066400000000000000000000000411464752671100402550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfdfdeaf9cf2b46b75164a382d1392a24 FromOsprayTestingMaxDepth_TestScenesMaxDepth_test_scenes_2.png.md5000066400000000000000000000000411464752671100402560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0ca1c6949e3509a4c0286a1cb0935446 FromOsprayTestingVariance_TestScenesVariance_testScenes_0.png.md5000066400000000000000000000000411464752671100401110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7f2868db0487194db7cf7a8d945680f9 FromOsprayTesting_TestScenesClipping_test_scenes_0.png.md5000066400000000000000000000000411464752671100366540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0296157028674dc93d72d85d0e965818 FromOsprayTesting_TestScenesClipping_test_scenes_1.png.md5000066400000000000000000000000411464752671100366550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0fd1877c94ac8514b0dfbd9e30726421 FromOsprayTesting_TestScenesClipping_test_scenes_10.png.md5000066400000000000000000000000411464752671100367350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfc569947d28c532f62adc96ec4785828 FromOsprayTesting_TestScenesClipping_test_scenes_11.png.md5000066400000000000000000000000411464752671100367360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX888d98f1dd39afaecb178993b0d746ad FromOsprayTesting_TestScenesClipping_test_scenes_12.png.md5000066400000000000000000000000411464752671100367370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX6fdf5191f445f07d244e8e6d082f84bf FromOsprayTesting_TestScenesClipping_test_scenes_13.png.md5000066400000000000000000000000411464752671100367400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXdf8a811a67c3433067c9a6a48aa4c2ba FromOsprayTesting_TestScenesClipping_test_scenes_14.png.md5000066400000000000000000000000411464752671100367410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9ff00941883291ec044226779055cef2 FromOsprayTesting_TestScenesClipping_test_scenes_15.png.md5000066400000000000000000000000411464752671100367420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX82791520206ee937d3cc1b7c2e196cb5 FromOsprayTesting_TestScenesClipping_test_scenes_16.png.md5000066400000000000000000000000411464752671100367430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb49014c001b9bcccc647809993fece68 FromOsprayTesting_TestScenesClipping_test_scenes_17.png.md5000066400000000000000000000000411464752671100367440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0f9fb5b8cc9667e4dece6fc4a43de759 FromOsprayTesting_TestScenesClipping_test_scenes_18.png.md5000066400000000000000000000000411464752671100367450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX29796dae1e53914c740c14d130005f81 FromOsprayTesting_TestScenesClipping_test_scenes_19.png.md5000066400000000000000000000000411464752671100367460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe016efcd24a7f94c326ff1e3fcf4f36c FromOsprayTesting_TestScenesClipping_test_scenes_2.png.md5000066400000000000000000000000411464752671100366560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3941e408aef3ce9f87d8cacf1ebe9504 FromOsprayTesting_TestScenesClipping_test_scenes_20.png.md5000066400000000000000000000000411464752671100367360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX87174ee15065c15b9687ad1b8713ef92 FromOsprayTesting_TestScenesClipping_test_scenes_21.png.md5000066400000000000000000000000411464752671100367370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9c746c040621f1889075118e35fe2b7d FromOsprayTesting_TestScenesClipping_test_scenes_22.png.md5000066400000000000000000000000411464752671100367400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX8ab32391e78a4e9baa94fa66c4228ded FromOsprayTesting_TestScenesClipping_test_scenes_23.png.md5000066400000000000000000000000411464752671100367410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX00674517ea25290fefdb1eb341a122b0 FromOsprayTesting_TestScenesClipping_test_scenes_24.png.md5000066400000000000000000000000411464752671100367420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX43adbf11389d8ad144d2b36f2a25470a FromOsprayTesting_TestScenesClipping_test_scenes_25.png.md5000066400000000000000000000000411464752671100367430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX440c14728d370912fe9b804bbc956d83 FromOsprayTesting_TestScenesClipping_test_scenes_26.png.md5000066400000000000000000000000411464752671100367440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1b5caed59b3f0331dc480dc001195e27 FromOsprayTesting_TestScenesClipping_test_scenes_3.png.md5000066400000000000000000000000411464752671100366570ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa5ad0f0c20eafe1b6403062357bce181 FromOsprayTesting_TestScenesClipping_test_scenes_4.png.md5000066400000000000000000000000411464752671100366600ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXef40d7d0b2f00e247bc25b4c9e65a130 FromOsprayTesting_TestScenesClipping_test_scenes_5.png.md5000066400000000000000000000000411464752671100366610ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXbc95c3ddc66b3e79f6c8e982f2eac8a7 FromOsprayTesting_TestScenesClipping_test_scenes_6.png.md5000066400000000000000000000000411464752671100366620ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb32fe5c7b0f6eeb98a00d2cd8b13cd47 FromOsprayTesting_TestScenesClipping_test_scenes_7.png.md5000066400000000000000000000000411464752671100366630ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2f5e96e0df54904029c892a9a537d172 FromOsprayTesting_TestScenesClipping_test_scenes_8.png.md5000066400000000000000000000000411464752671100366640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXbd891b1b29e6e755589bf4429f43f57b FromOsprayTesting_TestScenesClipping_test_scenes_9.png.md5000066400000000000000000000000411464752671100366650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX93e2b97821c1899ca87143f4006f6f10 FromOsprayTesting_TestScenesGeometry_test_scenes_0.png.md5000066400000000000000000000000411464752671100367020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX005fedac323e30b07b476741459fe6a1 FromOsprayTesting_TestScenesGeometry_test_scenes_1.png.md5000066400000000000000000000000411464752671100367030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7617c01f530413c30407133bf21fe1d0 FromOsprayTesting_TestScenesGeometry_test_scenes_10.png.md5000066400000000000000000000000411464752671100367630ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXea89a0c952bb99600620660db1bbeed2 FromOsprayTesting_TestScenesGeometry_test_scenes_11.png.md5000066400000000000000000000000411464752671100367640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX20517dbc5ff845a99c3b29c5784c49b4 FromOsprayTesting_TestScenesGeometry_test_scenes_12.png.md5000066400000000000000000000000411464752671100367650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc28ddf5f3311ee65d7ff407f805b8102 FromOsprayTesting_TestScenesGeometry_test_scenes_13.png.md5000066400000000000000000000000411464752671100367660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1ac1f2a6c498298c406b484b9dbfa899 FromOsprayTesting_TestScenesGeometry_test_scenes_14.png.md5000066400000000000000000000000411464752671100367670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa8c24f4c3842e40d51bc949fa399c77e FromOsprayTesting_TestScenesGeometry_test_scenes_15.png.md5000066400000000000000000000000411464752671100367700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0dfc97c10a8a792e3ef01ca74c178b37 FromOsprayTesting_TestScenesGeometry_test_scenes_16.png.md5000066400000000000000000000000411464752671100367710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX58ba677634ec1377713746c59ad2f0fd FromOsprayTesting_TestScenesGeometry_test_scenes_17.png.md5000066400000000000000000000000411464752671100367720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb2623af89221f26ffc0e011c5fd3872b FromOsprayTesting_TestScenesGeometry_test_scenes_18.png.md5000066400000000000000000000000411464752671100367730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXeaa20d7198d250f7524d875075c65523 FromOsprayTesting_TestScenesGeometry_test_scenes_19.png.md5000066400000000000000000000000411464752671100367740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3316de2400db72ab1d02bc48f069af5a FromOsprayTesting_TestScenesGeometry_test_scenes_2.png.md5000066400000000000000000000000411464752671100367040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9495604bd4f1d826adefafae768ad9ed FromOsprayTesting_TestScenesGeometry_test_scenes_20.png.md5000066400000000000000000000000411464752671100367640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1fce83c5e8a8e32884de61f06ef189fb FromOsprayTesting_TestScenesGeometry_test_scenes_21.png.md5000066400000000000000000000000411464752671100367650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2784c3a40b4c304f2dd67a0d226de309 FromOsprayTesting_TestScenesGeometry_test_scenes_22.png.md5000066400000000000000000000000411464752671100367660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0ee84a9176088792016e39e64ac96105 FromOsprayTesting_TestScenesGeometry_test_scenes_23.png.md5000066400000000000000000000000411464752671100367670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0597b0908477057233b26fdac50f8c30 FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5000066400000000000000000000000411464752671100367700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXca864845643d098c79e7df59405ebc91 FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5000066400000000000000000000000411464752671100367710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX004ae0a174778bd01ff345f2e2164e9c FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5000066400000000000000000000000411464752671100367720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc97734d3966425576e1c42efd57e8f95 FromOsprayTesting_TestScenesGeometry_test_scenes_27.png.md5000066400000000000000000000000411464752671100367730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5104654864fd04fa6ba385c8467f3810 FromOsprayTesting_TestScenesGeometry_test_scenes_28.png.md5000066400000000000000000000000411464752671100367740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5104654864fd04fa6ba385c8467f3810 FromOsprayTesting_TestScenesGeometry_test_scenes_29.png.md5000066400000000000000000000000411464752671100367750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5104654864fd04fa6ba385c8467f3810 FromOsprayTesting_TestScenesGeometry_test_scenes_3.png.md5000066400000000000000000000000411464752671100367050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb529a4853c8e6481d25d47e15089614f FromOsprayTesting_TestScenesGeometry_test_scenes_30.png.md5000066400000000000000000000000411464752671100367650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX726c140b625aad18f6d1b287a55c6340 FromOsprayTesting_TestScenesGeometry_test_scenes_31.png.md5000066400000000000000000000000411464752671100367660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9129cebceccb69ae64697d391b735d09 FromOsprayTesting_TestScenesGeometry_test_scenes_32.png.md5000066400000000000000000000000411464752671100367670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX31385985c9ee9f55aa87089f474ad60c FromOsprayTesting_TestScenesGeometry_test_scenes_33.png.md5000066400000000000000000000000411464752671100367700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd1b38a834f0f3bdd0522d98d81f127d9 FromOsprayTesting_TestScenesGeometry_test_scenes_34.png.md5000066400000000000000000000000411464752671100367710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX81ac931116d29b98475e903006d4714a FromOsprayTesting_TestScenesGeometry_test_scenes_35.png.md5000066400000000000000000000000411464752671100367720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX09979f3ae2f9fb1dd7288f58b3e17d64 FromOsprayTesting_TestScenesGeometry_test_scenes_4.png.md5000066400000000000000000000000411464752671100367060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX449624037e1ef5de3c21708ab9f5adde FromOsprayTesting_TestScenesGeometry_test_scenes_5.png.md5000066400000000000000000000000411464752671100367070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd51688c1af06a8e5c99234e43660a8c1 FromOsprayTesting_TestScenesGeometry_test_scenes_6.png.md5000066400000000000000000000000411464752671100367100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX68978d538ec04f4c4d16f6875cca9028 FromOsprayTesting_TestScenesGeometry_test_scenes_7.png.md5000066400000000000000000000000411464752671100367110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX68978d538ec04f4c4d16f6875cca9028 FromOsprayTesting_TestScenesGeometry_test_scenes_8.png.md5000066400000000000000000000000411464752671100367120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX68978d538ec04f4c4d16f6875cca9028 FromOsprayTesting_TestScenesGeometry_test_scenes_9.png.md5000066400000000000000000000000411464752671100367130ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd61e4794d9dd832af6ac97069eba2152 FromOsprayTesting_TestScenesPtMaterials_test_scenes_0.png.md5000066400000000000000000000000411464752671100373340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX8cab6629d696874271f40b6aeef16c2f FromOsprayTesting_TestScenesPtMaterials_test_scenes_1.png.md5000066400000000000000000000000411464752671100373350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4dcd848b9983daf3c767e5deafbf9f4d FromOsprayTesting_TestScenesPtMaterials_test_scenes_10.png.md5000066400000000000000000000000411464752671100374150ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX526abce1184fef470d4fbbc88a819af3 FromOsprayTesting_TestScenesPtMaterials_test_scenes_11.png.md5000066400000000000000000000000411464752671100374160ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXdd5f24a7f1cca4df0f0aeacff6f7f8f2 FromOsprayTesting_TestScenesPtMaterials_test_scenes_12.png.md5000066400000000000000000000000411464752671100374170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXba2076c08fe9c04c9811703f0113e40b FromOsprayTesting_TestScenesPtMaterials_test_scenes_13.png.md5000066400000000000000000000000411464752671100374200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXede14f22d0bb44aa9b45d760c2f2db5f FromOsprayTesting_TestScenesPtMaterials_test_scenes_14.png.md5000066400000000000000000000000411464752671100374210ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXba93b3138b7374632b3bd743c6a727d0 FromOsprayTesting_TestScenesPtMaterials_test_scenes_15.png.md5000066400000000000000000000000411464752671100374220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX97b3c16126913a972af4021d729a0f6c FromOsprayTesting_TestScenesPtMaterials_test_scenes_2.png.md5000066400000000000000000000000411464752671100373360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe76c8d0f5acf92bfff4c1ade75113f7d FromOsprayTesting_TestScenesPtMaterials_test_scenes_3.png.md5000066400000000000000000000000411464752671100373370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf288be1d0a1d78e13994c2cd21514c07 FromOsprayTesting_TestScenesPtMaterials_test_scenes_4.png.md5000066400000000000000000000000411464752671100373400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1d2f685f33019946fcf4204e3189086b FromOsprayTesting_TestScenesPtMaterials_test_scenes_5.png.md5000066400000000000000000000000411464752671100373410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX43ea7782bc77f8138fc68cae9594131d FromOsprayTesting_TestScenesPtMaterials_test_scenes_6.png.md5000066400000000000000000000000411464752671100373420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4357f8d3b44d73ecf49425354092239a FromOsprayTesting_TestScenesPtMaterials_test_scenes_7.png.md5000066400000000000000000000000411464752671100373430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5f5e4418047852b8be5270816e745fd8 FromOsprayTesting_TestScenesPtMaterials_test_scenes_8.png.md5000066400000000000000000000000411464752671100373440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe037f67b56f57fdd81930473eb993261 FromOsprayTesting_TestScenesPtMaterials_test_scenes_9.png.md5000066400000000000000000000000411464752671100373450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0667d0c04af94a41f6d2fc9fdcddf860 FromOsprayTesting_TestScenesVolumesStrictParams_test_scenes_0.png.md5000066400000000000000000000000411464752671100410760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb061e43c1f11a436cb2679f76369cfe6 FromOsprayTesting_TestScenesVolumesStrictParams_test_scenes_1.png.md5000066400000000000000000000000411464752671100410770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa8aa6c7b3ad7d899415460b772d7f6a3 FromOsprayTesting_TestScenesVolumesStrictParams_test_scenes_2.png.md5000066400000000000000000000000411464752671100411000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf1ec979e88d9b97b38efeb8d702577f4 FromOsprayTesting_TestScenesVolumes_test_scenes_0.png.md5000066400000000000000000000000411464752671100365410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX61007e9e7617dc49a8c2a2c69a5e27c9 FromOsprayTesting_TestScenesVolumes_test_scenes_1.png.md5000066400000000000000000000000411464752671100365420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd64809a94e3bf00feff142823d336267 FromOsprayTesting_TestScenesVolumes_test_scenes_10.png.md5000066400000000000000000000000411464752671100366220ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7e6f247a833d34986cc7a48b31110d50 FromOsprayTesting_TestScenesVolumes_test_scenes_11.png.md5000066400000000000000000000000411464752671100366230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXbc80d51afd2d942022b1820dbc7f84e2 FromOsprayTesting_TestScenesVolumes_test_scenes_12.png.md5000066400000000000000000000000411464752671100366240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe9255f5d5978373819db855bfbaacd6e FromOsprayTesting_TestScenesVolumes_test_scenes_13.png.md5000066400000000000000000000000411464752671100366250ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9f6e34fa38a366a461af4aac6693247f FromOsprayTesting_TestScenesVolumes_test_scenes_14.png.md5000066400000000000000000000000411464752671100366260ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7b861d9ded7e810b8411ff5bf208bc30 FromOsprayTesting_TestScenesVolumes_test_scenes_15.png.md5000066400000000000000000000000411464752671100366270ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe9255f5d5978373819db855bfbaacd6e FromOsprayTesting_TestScenesVolumes_test_scenes_16.png.md5000066400000000000000000000000411464752671100366300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9f6e34fa38a366a461af4aac6693247f FromOsprayTesting_TestScenesVolumes_test_scenes_17.png.md5000066400000000000000000000000411464752671100366310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7b861d9ded7e810b8411ff5bf208bc30 FromOsprayTesting_TestScenesVolumes_test_scenes_18.png.md5000066400000000000000000000000411464752671100366320ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9e6bfa920c7579632fd07ae633fde44a FromOsprayTesting_TestScenesVolumes_test_scenes_19.png.md5000066400000000000000000000000411464752671100366330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXbc4637abfad0b5e4823fe08dde4cc6bd FromOsprayTesting_TestScenesVolumes_test_scenes_2.png.md5000066400000000000000000000000411464752671100365430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX58aaddd509d364794807a2ffe2d058e5 FromOsprayTesting_TestScenesVolumes_test_scenes_20.png.md5000066400000000000000000000000411464752671100366230ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX11d2216fd034fd9babfa629a935bf9f7 FromOsprayTesting_TestScenesVolumes_test_scenes_3.png.md5000066400000000000000000000000411464752671100365440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX44413ed71090df5f96d4cb12c0c95a43 FromOsprayTesting_TestScenesVolumes_test_scenes_4.png.md5000066400000000000000000000000411464752671100365450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX28641a39813622d38fcf423f44b1e78e FromOsprayTesting_TestScenesVolumes_test_scenes_5.png.md5000066400000000000000000000000411464752671100365460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf89eae18f4cb2a962a4d56f1dea8d28a FromOsprayTesting_TestScenesVolumes_test_scenes_6.png.md5000066400000000000000000000000411464752671100365470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXdf3ff32830e74a7b3a8c43f3ea7f3c74 FromOsprayTesting_TestScenesVolumes_test_scenes_7.png.md5000066400000000000000000000000411464752671100365500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf45e922ba3792f81694fa33746774036 FromOsprayTesting_TestScenesVolumes_test_scenes_8.png.md5000066400000000000000000000000411464752671100365510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3ae4d676399496d32187fa45a65f36d1 FromOsprayTesting_TestScenesVolumes_test_scenes_9.png.md5000066400000000000000000000000411464752671100365520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4acc73d6c90c381efafe80e17251be54 FromOsprayTesting_Transparency_test_scenes_0.png.md5000066400000000000000000000000411464752671100355570ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfb91084d1376b9c4b30a18a55365acd3 FromOsprayTesting_Transparency_test_scenes_1.png.md5000066400000000000000000000000411464752671100355600ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX77bd568bc2bff5ff6b38c036796fd38d FromOsprayTesting_Transparency_test_scenes_2.png.md5000066400000000000000000000000411464752671100355610ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4865efcd3563cd954cdcdc887e1bead8 GeometricLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100351000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd890634b6f26ef2c69b8201c300785ec GeometricLight_LightMotionBlur_parameter_1.png.md5000066400000000000000000000000411464752671100351010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd890634b6f26ef2c69b8201c300785ec GeometricLight_LightTexture_parameter_0.png.md5000066400000000000000000000000411464752671100344460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe424922846ea4839865963033d75c402 GeometricLight_LightTexture_parameter_1.png.md5000066400000000000000000000000411464752671100344470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0e75cf118c97b5bfa55a129dba58c053 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100331440ustar00rootroot00000000000000e3dc72cf23fd9f39a0a341016a5d4b6a RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100331450ustar00rootroot00000000000000e3dc72cf23fd9f39a0a341016a5d4b6a RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100331460ustar00rootroot00000000000000bcf2e967bdc255d6007ec23237e65efd RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100331470ustar00rootroot00000000000000bcf2e967bdc255d6007ec23237e65efd HDRILight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100337100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc729d5345a0200e8cffc76e3870b2ef5 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/HDRILight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100317540ustar00rootroot000000000000001ced2b13d85f1759f41fa08af148ac64 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/HDRILight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100317550ustar00rootroot00000000000000b908fa2b10882cf56cb1f67375a3528c IDBuffer_ObjectInstance_IDBuffer_0.png.md5000066400000000000000000000000411464752671100330770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX62cb7747142a598ef3806d8d8a2e7823 IDBuffer_ObjectInstance_IDBuffer_1.png.md5000066400000000000000000000000411464752671100331000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXbee384f4fc25b57eba970612c0c439b3 IDBuffer_ObjectInstance_IDBuffer_2.png.md5000066400000000000000000000000411464752671100331010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc0964106cdfe0c4a236d432f15171a42 IDBuffer_ObjectInstance_IDBuffer_3.png.md5000066400000000000000000000000411464752671100331020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXdb162b8988ca2836706f3ddae736864a IDBuffer_ObjectInstance_IDBuffer_4.png.md5000066400000000000000000000000411464752671100331030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc6f4ed5204ffa824d07ded1f238e552d IDBuffer_ObjectInstance_IDBuffer_5.png.md5000066400000000000000000000000411464752671100331040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX6ee8cc7d67dcba7e0b12a1f8ce623288 IDBuffer_ObjectInstance_IDBuffer_6.png.md5000066400000000000000000000000411464752671100331050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5b901adfdeda0cf1bbf60ed834801acf IDBuffer_ObjectInstance_IDBuffer_7.png.md5000066400000000000000000000000411464752671100331060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX638e987fa9568bfc7e9b4243b9c5847c RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/IDBuffer_Primitive_IDBuffer_0.png.md5000066400000000000000000000000411464752671100322330ustar00rootroot00000000000000a635c7fdb9cb0394917fa7d5369722a6 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/IDBuffer_Primitive_IDBuffer_1.png.md5000066400000000000000000000000411464752671100322340ustar00rootroot00000000000000c99f42dc0a364cdfc4e1dc347a2a84ed RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/ImageOp_DebugOp_ImageOp_0.png.md5000066400000000000000000000000411464752671100313760ustar00rootroot00000000000000ad46f14985a97628abd2de4ea4276f6f Interpolation_Color_Interpolation_0.png.md5000066400000000000000000000000411464752671100336640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5ac362cb64845079f85d60c53237a30c Interpolation_Color_Interpolation_1.png.md5000066400000000000000000000000411464752671100336650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX600f9a78e23df4b21ef1cb3576c41293 Interpolation_Color_Interpolation_2.png.md5000066400000000000000000000000411464752671100336660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb96e5ad22db82abfd7a96bb718b39d2c Interpolation_Color_Interpolation_3.png.md5000066400000000000000000000000411464752671100336670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX37bb390a60b0bfcfa5eefd11c5417400 Interpolation_Color_Interpolation_4.png.md5000066400000000000000000000000411464752671100336700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2dcf960bb59871a4576a24a6fa313875 Interpolation_Color_Interpolation_5.png.md5000066400000000000000000000000411464752671100336710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2219c6429c336540493059ba4dd21a5b Interpolation_Color_Interpolation_6.png.md5000066400000000000000000000000411464752671100336720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb96e5ad22db82abfd7a96bb718b39d2c Interpolation_Color_Interpolation_7.png.md5000066400000000000000000000000411464752671100336730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX37bb390a60b0bfcfa5eefd11c5417400 Interpolation_Normal_Interpolation_0.png.md5000066400000000000000000000000411464752671100340360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb46e1e25fabdba9962cdb1fa797ead04 Interpolation_Normal_Interpolation_1.png.md5000066400000000000000000000000411464752671100340370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX73b536d10b031c419a7f3acde81851df Interpolation_Texcoord_Interpolation_0.png.md5000066400000000000000000000000411464752671100343750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa5952191d40359ec2caef22b16dd59e9 Interpolation_Texcoord_Interpolation_1.png.md5000066400000000000000000000000411464752671100343760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb74cb26446f638d39b4395fcc3cc761a Interpolation_Texcoord_Interpolation_2.png.md5000066400000000000000000000000411464752671100343770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5791e0b989fba970b48521d80f3d997a Interpolation_Texcoord_Interpolation_3.png.md5000066400000000000000000000000411464752671100344000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa7f87e630b9b82e8e44eca2d6d6798f5 MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5000066400000000000000000000000411464752671100411370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc11af06b7ed875a6b87d1a5de0427d91 MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5000066400000000000000000000000411464752671100411400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3da593a811d23760b111dc55c6fd93d6 MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5000066400000000000000000000000411464752671100411410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa67563d886598cc3ac2be9fdf494308a MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5000066400000000000000000000000411464752671100407760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX56338fcff16d21ad86271e3f85052436 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5000066400000000000000000000000411464752671100407770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe5c2467727ae66a9744b8cbb517d606e MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5000066400000000000000000000000411464752671100410000ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5776518b2bec1f324f15c2ae3ef504a1 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5000066400000000000000000000000411464752671100410010ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc76793fe11e0bfdb7f43fd0e8999b63e MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5000066400000000000000000000000411464752671100410020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfcf630625ed9a4645b6937030b802c73 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5000066400000000000000000000000411464752671100410030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXce646854a5c595b1f7b009c40c256684 MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5000066400000000000000000000000411464752671100410040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX01b17a8669d5be94696470962fcd1389 MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5000066400000000000000000000000411464752671100366030ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe09a7f947946e09944af1c0ee8eb3225 MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5000066400000000000000000000000411464752671100366040ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX84a327f24353d9c16b1f57cdf8738c52 MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5000066400000000000000000000000411464752671100366050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc1a6af91c50b68c06f8d97b4316f1279 MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5000066400000000000000000000000411464752671100366060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX24b27522f08c8d46b384b0c3ac834133 MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5000066400000000000000000000000411464752671100366070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7f1ca47683d8f2a8398e66e2a9a78dde MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5000066400000000000000000000000411464752671100366100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4e17234519beab039e833d481d74cf1f MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5000066400000000000000000000000411464752671100366110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXabe391f40c73fd61fee52307bbb1ff6c MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5000066400000000000000000000000411464752671100366120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXbd05dcc671fe72f741659d8438901ac6 MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5000066400000000000000000000000411464752671100377650ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4f9858dff7a78b5ae508fcaf272d3795 MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5000066400000000000000000000000411464752671100354370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX20fdf05b9a77272b90133e3f2e177dce MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5000066400000000000000000000000411464752671100354400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1d093c1334f74362931d235a587b86c2 MotionCamera_CameraOrtho_camera_mb_0.png.md5000066400000000000000000000000411464752671100336200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf21af1f2c408a2359254f34dc9fba77f MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5000066400000000000000000000000411464752671100366740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1ae7ba722d04dbb8c319d8018173fa1d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_0.png.md5000066400000000000000000000000411464752671100326630ustar00rootroot000000000000008b08da5bd0636a80a526846d2b6f51c9 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_1.png.md5000066400000000000000000000000411464752671100326640ustar00rootroot00000000000000a3757e91aeffc07c32406ff4ae930530 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_2.png.md5000066400000000000000000000000411464752671100326650ustar00rootroot000000000000006f5072460b8a2d60c4081de05e422347 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_3.png.md5000066400000000000000000000000411464752671100326660ustar00rootroot000000000000007140a6437c7ddf9a7939f31bfd2ed11f RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_4.png.md5000066400000000000000000000000411464752671100326670ustar00rootroot00000000000000a73fc912b5de42ebaa66d13169353591 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_5.png.md5000066400000000000000000000000411464752671100326700ustar00rootroot0000000000000067559d0c14af7c4fd2cd392fc29f9b13 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_6.png.md5000066400000000000000000000000411464752671100326710ustar00rootroot0000000000000021ca5f70a74e4209e6707f02da1896b8 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_7.png.md5000066400000000000000000000000411464752671100326720ustar00rootroot000000000000009d42974498897ad5936846ceb6ebafe1 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_8.png.md5000066400000000000000000000000411464752671100326730ustar00rootroot000000000000002f2a9890c1cb8fd9d72689814e64ea68 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_9.png.md5000066400000000000000000000000411464752671100326740ustar00rootroot00000000000000405361d8e6cde7f8278a2466b101a990 PTBackgroundRefraction_Appearance_backgroundRefraction_0.png.md5000066400000000000000000000000411464752671100376630ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4ff8f25e4eb2e84c0b469a5d43e18b44 PTBackgroundRefraction_Appearance_backgroundRefraction_1.png.md5000066400000000000000000000000411464752671100376640ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX83fd955d6b4d2e213aec962d761218cd PhotometricLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100334440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe3b9cc2abb4828e6183db2717a282b05 PhotometricLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100334450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX55009c40fefcd4eb6ebf0c5467d1e6f5 PhotometricLight_Light_parameter_10.png.md5000066400000000000000000000000411464752671100335250ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX897322dcba60a3738bb35a161f68a266 PhotometricLight_Light_parameter_11.png.md5000066400000000000000000000000411464752671100335260ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7c7ebd0441e73b86455662920b3f5a04 PhotometricLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100334460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX42f7b6f0bb4b17ebd2d6e2d6dfeb5a52 PhotometricLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100334470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9122d64d2343b2ebcc7aeba86a1d3086 PhotometricLight_Light_parameter_4.png.md5000066400000000000000000000000411464752671100334500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX97fe194b2dcbd54d45e391449c514b4d PhotometricLight_Light_parameter_5.png.md5000066400000000000000000000000411464752671100334510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX44328cc612a40a65c2a8e37db15d3e32 PhotometricLight_Light_parameter_6.png.md5000066400000000000000000000000411464752671100334520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX63b0136d8b074c034affacc4b7545f45 PhotometricLight_Light_parameter_7.png.md5000066400000000000000000000000411464752671100334530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7de1516a92e6baaa83a47efd60a53086 PhotometricLight_Light_parameter_8.png.md5000066400000000000000000000000411464752671100334540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2c562fee621fe1043fed6bc04d187d5d PhotometricLight_Light_parameter_9.png.md5000066400000000000000000000000411464752671100334550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX089632b7f534d6b787f719c935c55a36 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_0.png.md5000066400000000000000000000000411464752671100316050ustar00rootroot000000000000002c04102ec0eb17bb823b00d08929f03c RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_1.png.md5000066400000000000000000000000411464752671100316060ustar00rootroot000000000000002c5faba08250fdf541f4ad032e55711e RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_2.png.md5000066400000000000000000000000411464752671100316070ustar00rootroot00000000000000fe60964b25a399e4e814fcf64493e229 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_3.png.md5000066400000000000000000000000411464752671100316100ustar00rootroot000000000000003c7c73b43d9567f30beac9654ec6381f RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_4.png.md5000066400000000000000000000000411464752671100316110ustar00rootroot00000000000000e4563a35246501e98b85e2e6d831423b RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_5.png.md5000066400000000000000000000000411464752671100316120ustar00rootroot000000000000002c04102ec0eb17bb823b00d08929f03c RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_6.png.md5000066400000000000000000000000411464752671100316130ustar00rootroot00000000000000de37bf660f226d6cf4df1eb7a90be7d2 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_7.png.md5000066400000000000000000000000411464752671100316140ustar00rootroot0000000000000041b6e7f412a09c4eedc41de34c502727 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_8.png.md5000066400000000000000000000000411464752671100316150ustar00rootroot000000000000007bc51c940ede9fd6b99620fab3547a9d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/PixelFilter_Camera_test_9.png.md5000066400000000000000000000000411464752671100316160ustar00rootroot00000000000000281cf4e902bce79665ef864ccd6e08eb QuadLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100355070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7a4647314d9e9fe52cc60f0cd88e7cc5 QuadLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100355100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX90428918977c596a76589c7e8f514b44 QuadLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100355110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0557938f2fb0111a3d89c6f18ea91cc9 QuadLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100355120ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd702aa0664374d07a45294a61df22e57 QuadLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100340540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc14d9428c60f7f525590d4d84bfabf02 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/QuadLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100321200ustar00rootroot00000000000000d2e25a08e5f62467fff8017df239e7de RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/QuadLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100321210ustar00rootroot00000000000000d6dda669082cf67864c7408e7a81ec9c RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/QuadLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100321220ustar00rootroot0000000000000075bc399da6fce8ceb64cab63777bd52d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/QuadLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100321230ustar00rootroot00000000000000933a54ee091711fcd8f39ef32605cea8 RendererMaterialList_MaterialLists_material_list_0.png.md5000066400000000000000000000000411464752671100366170ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX6c47ba3fd337d73f44ac05ef4767e046 RendererMaterialList_MaterialLists_material_list_1.png.md5000066400000000000000000000000411464752671100366200ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX616d58357cf8ad2a950296ad7c81106d SphereLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100360430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa591333c14e5cb8ebe2b4ac8ef0e1a94 SphereLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100360440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1435a54d9a9511b4ee4a435166d11c8a SphereLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100360450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb22ea36cd0e4cdba968936a19f7883d6 SphereLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100360460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5fd4b0854345dfba7ecc4879cb78dc8f SphereLight_LightIntensityQuantity_parameter_4.png.md5000066400000000000000000000000411464752671100360470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX40d43cba12b84988edaa4b5996593ff1 SphereLight_LightIntensityQuantity_parameter_5.png.md5000066400000000000000000000000411464752671100360500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX887aa3ac4e41aadce524615e6987a3f0 SphereLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100344100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXeac49e507d0881385bf51e8f65e6dafa RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SphereLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100324540ustar00rootroot0000000000000058a17cd519c8b5b62b1040d7f5c5f177 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SphereLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100324550ustar00rootroot00000000000000e61c3cac8839e449c1b0b9c8b430020a RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SphereLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100324560ustar00rootroot00000000000000112f3bac4b5b2f01e8fc45c3ac9d182b RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SphereLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100324570ustar00rootroot000000000000009c63f65a1905e6c14064f9ab1282b662 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SphereLight_Light_parameter_4.png.md5000066400000000000000000000000411464752671100324600ustar00rootroot00000000000000ab51df87fb122cd035dbc171e375b92f RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SphereLight_Light_parameter_5.png.md5000066400000000000000000000000411464752671100324610ustar00rootroot00000000000000f6916b40a6519526299b5524ad9f0d99 SpherePrecision_Intersection_sphere_0.png.md5000066400000000000000000000000411464752671100341660ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX247ddc74d65ed8fac9fed9b0bf0d6654 SpherePrecision_Intersection_sphere_1.png.md5000066400000000000000000000000411464752671100341670ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7df8cd62764727b3aefd892a550683fa SpherePrecision_Intersection_sphere_10.png.md5000066400000000000000000000000411464752671100342470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc4f3b4d179efcc9a72ca9954ee89d1a3 SpherePrecision_Intersection_sphere_11.png.md5000066400000000000000000000000411464752671100342500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX09653d1885e661a7fd96d3b4f28dce1d SpherePrecision_Intersection_sphere_12.png.md5000066400000000000000000000000411464752671100342510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX20e20ace063e3344eda60e844851f79c SpherePrecision_Intersection_sphere_13.png.md5000066400000000000000000000000411464752671100342520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX6bd64faa11a725b1c35a23d9725391cf SpherePrecision_Intersection_sphere_14.png.md5000066400000000000000000000000411464752671100342530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX8634d6c2195dfa036378d9431f78b813 SpherePrecision_Intersection_sphere_15.png.md5000066400000000000000000000000411464752671100342540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX227d77fb5290d6ff2cff00bfc525dfa9 SpherePrecision_Intersection_sphere_16.png.md5000066400000000000000000000000411464752671100342550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX60c4c0f0cf5e03ad5e96205edfc200b7 SpherePrecision_Intersection_sphere_17.png.md5000066400000000000000000000000411464752671100342560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc19fef9d5c659c81f12ef89ae58dab1c SpherePrecision_Intersection_sphere_18.png.md5000066400000000000000000000000411464752671100342570ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe758302f17774ba7acd5dbf9997d36ea SpherePrecision_Intersection_sphere_19.png.md5000066400000000000000000000000411464752671100342600ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX95f76cc755a2db8de71858382c2e5a7e SpherePrecision_Intersection_sphere_2.png.md5000066400000000000000000000000411464752671100341700ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3f7a6f51e50dab15e6148a821ce14099 SpherePrecision_Intersection_sphere_20.png.md5000066400000000000000000000000411464752671100342500ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5ec0317b36e1b7df997f4632b9cb7039 SpherePrecision_Intersection_sphere_21.png.md5000066400000000000000000000000411464752671100342510ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX737c26bad2befc43eba7279e3e68e57c SpherePrecision_Intersection_sphere_22.png.md5000066400000000000000000000000411464752671100342520ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa612389a72e432c4892f816e0ac9d6af SpherePrecision_Intersection_sphere_23.png.md5000066400000000000000000000000411464752671100342530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe891677d9ae7dc258cfd5fa71a6360a8 SpherePrecision_Intersection_sphere_3.png.md5000066400000000000000000000000411464752671100341710ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4b0ab1c23a01cb486456dde45698e5e3 SpherePrecision_Intersection_sphere_4.png.md5000066400000000000000000000000411464752671100341720ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX8e3d357fed8c4069badb6e90218676f3 SpherePrecision_Intersection_sphere_5.png.md5000066400000000000000000000000411464752671100341730ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9e059202107a1d709bb658c4a204c5a8 SpherePrecision_Intersection_sphere_6.png.md5000066400000000000000000000000411464752671100341740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2693fd8082f4746e14228d14823c8215 SpherePrecision_Intersection_sphere_7.png.md5000066400000000000000000000000411464752671100341750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0576a41dc1e1430d4574752adc9fc7a5 SpherePrecision_Intersection_sphere_8.png.md5000066400000000000000000000000411464752671100341760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX7378847974ba02f14ed1c07484d20d93 SpherePrecision_Intersection_sphere_9.png.md5000066400000000000000000000000411464752671100341770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXac6c5a4f7f495f613611147a4109fe7e SpotLight_LightIntensityQuantity_parameter_0.png.md5000066400000000000000000000000411464752671100355420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa591333c14e5cb8ebe2b4ac8ef0e1a94 SpotLight_LightIntensityQuantity_parameter_1.png.md5000066400000000000000000000000411464752671100355430ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX544c09110ab45a7ac602286c55e621c6 SpotLight_LightIntensityQuantity_parameter_2.png.md5000066400000000000000000000000411464752671100355440ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa95f3f3e5b327efe5eea3380b3fb6716 SpotLight_LightIntensityQuantity_parameter_3.png.md5000066400000000000000000000000411464752671100355450ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd86e673c6d967180a1e3688f7284a2b5 SpotLight_LightIntensityQuantity_parameter_4.png.md5000066400000000000000000000000411464752671100355460ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe94f91ea9687e4229507a1798e135970 SpotLight_LightIntensityQuantity_parameter_5.png.md5000066400000000000000000000000411464752671100355470ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0088dfe601ea100002424d3b2714ad68 SpotLight_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100341070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX8a0f558e1f3e271d171bc1a63a5505bd RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_0.png.md5000066400000000000000000000000411464752671100321530ustar00rootroot000000000000006e69c875527b92cc344b2255d49aa543 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_1.png.md5000066400000000000000000000000411464752671100321540ustar00rootroot00000000000000fdc115503b6f13ded13d1700d530387a RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_2.png.md5000066400000000000000000000000411464752671100321550ustar00rootroot000000000000002071ed754e6ced5c6d7c858700c90a96 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_3.png.md5000066400000000000000000000000411464752671100321560ustar00rootroot000000000000003958644d7bf8e575f2f98b5dcfc04e57 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_4.png.md5000066400000000000000000000000411464752671100321570ustar00rootroot00000000000000c2ab237527996decfee4c902281c8a7d RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_5.png.md5000066400000000000000000000000411464752671100321600ustar00rootroot000000000000007f4f37bd2a26afa9fbe4fad121c6a8a3 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_6.png.md5000066400000000000000000000000411464752671100321610ustar00rootroot000000000000004f874be7c445cf60f39330914d2492b2 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_7.png.md5000066400000000000000000000000411464752671100321620ustar00rootroot00000000000000815dbb36620ce3d9fb67af16bc45c9b8 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_8.png.md5000066400000000000000000000000411464752671100321630ustar00rootroot00000000000000926746861e6dd78f7d5a9f03d670f617 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SpotLight_Light_parameter_9.png.md5000066400000000000000000000000411464752671100321640ustar00rootroot000000000000007e6d93e0b068f62197441d61aa42eaf6 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_0.png.md5000066400000000000000000000000411464752671100311410ustar00rootroot00000000000000a101b64cd3f63170e00890b65c8a5499 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_1.png.md5000066400000000000000000000000411464752671100311420ustar00rootroot0000000000000085bf732703518cfc9af270da6c5531c1 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_2.png.md5000066400000000000000000000000411464752671100311430ustar00rootroot00000000000000814b7d3d8e2e8fbc6ed539f0de1acf91 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_3.png.md5000066400000000000000000000000411464752671100311440ustar00rootroot000000000000006d15e4bcbdd9037dd5b72e442dc6cf93 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_4.png.md5000066400000000000000000000000411464752671100311450ustar00rootroot00000000000000216abc0d5abdfaa56b236bc2aaecf1bd RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_5.png.md5000066400000000000000000000000411464752671100311460ustar00rootroot0000000000000006e33d2badc11d81a02a6dda018f7e72 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_6.png.md5000066400000000000000000000000411464752671100311470ustar00rootroot00000000000000ffdbe2cb2e7a3b5cc958906ad8391021 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Stereo_Camera_stereo_7.png.md5000066400000000000000000000000411464752671100311500ustar00rootroot000000000000006aafd5dac141de5d94be9936c6f598be RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light2_parameter_0.png.md5000066400000000000000000000000411464752671100315540ustar00rootroot00000000000000d3d1f71a73213e21c0853cd2fb81ea14 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light2_parameter_1.png.md5000066400000000000000000000000411464752671100315550ustar00rootroot0000000000000030f6a8fed556c2144e82d6af3bf38413 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light2_parameter_2.png.md5000066400000000000000000000000411464752671100315560ustar00rootroot0000000000000003aada0ffd5f4d08794c04676b487c4b RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light2_parameter_3.png.md5000066400000000000000000000000411464752671100315570ustar00rootroot00000000000000d4524ef0043c8b30d2d400305e40f555 SunSky_LightMotionBlur_parameter_0.png.md5000066400000000000000000000000411464752671100334260ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9cf7f96c35bc92e830a17fc1dcd78732 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_0.png.md5000066400000000000000000000000411464752671100314720ustar00rootroot000000000000003e5b56f70cbfd4b75d06c58dae33318b RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_1.png.md5000066400000000000000000000000411464752671100314730ustar00rootroot00000000000000e761d9960abbcc86d6b56cc59a488e23 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_10.png.md5000066400000000000000000000000411464752671100315530ustar00rootroot00000000000000542f88cea0156ffeffe12bf2fdb4e624 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_11.png.md5000066400000000000000000000000411464752671100315540ustar00rootroot000000000000008bd2c59521aabd1b8fafb2aead66d5d0 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_12.png.md5000066400000000000000000000000411464752671100315550ustar00rootroot0000000000000010532d993fa72bbc1bdd55cbfa9d3bc3 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_13.png.md5000066400000000000000000000000411464752671100315560ustar00rootroot00000000000000aecfc8c25556df822ecd47353b9d4f66 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_14.png.md5000066400000000000000000000000411464752671100315570ustar00rootroot0000000000000001f1dc126f663ad542eb6ba2384945e7 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_2.png.md5000066400000000000000000000000411464752671100314740ustar00rootroot00000000000000156f6d2141cc34bf7e917d621ddcb333 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_3.png.md5000066400000000000000000000000411464752671100314750ustar00rootroot0000000000000030350a0d29420a0d0c8a295a05ca5c3a RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_4.png.md5000066400000000000000000000000411464752671100314760ustar00rootroot00000000000000e5c1dae4027b9620f3345fe074974e4c RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_5.png.md5000066400000000000000000000000411464752671100314770ustar00rootroot00000000000000e7092c6f33a9236be32d9dabce7b5c85 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_6.png.md5000066400000000000000000000000411464752671100315000ustar00rootroot00000000000000e6bf2e10e28c4d5a5688464199904442 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_7.png.md5000066400000000000000000000000411464752671100315010ustar00rootroot00000000000000cab3383424c3cdc30688548e2e0f4ee7 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_8.png.md5000066400000000000000000000000411464752671100315020ustar00rootroot0000000000000092eec847bfceba0cb9a9d6683e4d2728 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/SunSky_Light_parameter_9.png.md5000066400000000000000000000000411464752671100315030ustar00rootroot00000000000000fa33379b0fa06fedb530f7189e06b780 TestAssignedCopy_deleterCallbacks.png.md5000066400000000000000000000000411464752671100333050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc38d798d36f03061d5a9fc0a0a3a3e6d TestUSMSharing_SharedData_structured_regular_0.png.md5000066400000000000000000000000411464752671100356750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb19ecf9ed96fa82be56387b70909b261 TestUSMSharing_SharedData_structured_regular_1.png.md5000066400000000000000000000000411464752671100356760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb19ecf9ed96fa82be56387b70909b261 TestUSMSharing_SharedData_structured_regular_2.png.md5000066400000000000000000000000411464752671100356770ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb19ecf9ed96fa82be56387b70909b261 Texture2DMipMapping_MipMapCamera_mipMapping_0.png.md5000066400000000000000000000000411464752671100353350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMapCamera_mipMapping_1.png.md5000066400000000000000000000000411464752671100353360ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2ee8470860a4324347b07121c1fff1b5 Texture2DMipMapping_MipMapCamera_mipMapping_2.png.md5000066400000000000000000000000411464752671100353370ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXf3bc031bb4e5a74b6829f7f64da066d5 Texture2DMipMapping_MipMapCamera_mipMapping_3.png.md5000066400000000000000000000000411464752671100353400ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX42b1893f86f457c332f692bf7fcf21ef Texture2DMipMapping_MipMapCamera_mipMapping_4.png.md5000066400000000000000000000000411464752671100353410ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXc5b9f0fb24ba92148fce4ebd096c0d80 Texture2DMipMapping_MipMapCamera_mipMapping_5.png.md5000066400000000000000000000000411464752671100353420ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX139daf3374a4220f03b7f11eed96f90d Texture2DMipMapping_MipMapScale_mipMapping_0.png.md5000066400000000000000000000000411464752671100351740ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMapScale_mipMapping_1.png.md5000066400000000000000000000000411464752671100351750ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMap_mipMapping_0.png.md5000066400000000000000000000000411464752671100342240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXb3b6b8e4f9100e2b4c3eaae358eb5ba6 Texture2DMipMapping_MipMap_mipMapping_1.png.md5000066400000000000000000000000411464752671100342250ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX452c6434d48d7e7cb3dbab35199e9f76 Texture2DMipMapping_MipMap_mipMapping_10.png.md5000066400000000000000000000000411464752671100343050ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX49fe3bc99087e1dfe39d4510876da09d Texture2DMipMapping_MipMap_mipMapping_11.png.md5000066400000000000000000000000411464752671100343060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX2ccab6b423cde43e582fb6132884a17c Texture2DMipMapping_MipMap_mipMapping_2.png.md5000066400000000000000000000000411464752671100342260ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX05206347a52342a4cdfc5870024aaaf9 Texture2DMipMapping_MipMap_mipMapping_3.png.md5000066400000000000000000000000411464752671100342270ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4d006becc5c732ec9ee34a7c2d5711a6 Texture2DMipMapping_MipMap_mipMapping_4.png.md5000066400000000000000000000000411464752671100342300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX02c55729dd57be28d2dcffb0156d4ffd Texture2DMipMapping_MipMap_mipMapping_5.png.md5000066400000000000000000000000411464752671100342310ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX4898d5af5acc6885e06365ec3c6efd73 Texture2DMipMapping_MipMap_mipMapping_6.png.md5000066400000000000000000000000411464752671100342320ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5f6b35405e089aa666d96e3b8a0ebb26 Texture2DMipMapping_MipMap_mipMapping_7.png.md5000066400000000000000000000000411464752671100342330ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXfbe0be543b8824cfa230c6ee6f194d52 Texture2DMipMapping_MipMap_mipMapping_8.png.md5000066400000000000000000000000411464752671100342340ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd3ff011da4f7ab85082d113bc509ddd7 Texture2DMipMapping_MipMap_mipMapping_9.png.md5000066400000000000000000000000411464752671100342350ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX79aac9a9f73b8db960983083223ecde4 Texture2DTransform_Appearance_simple_0.png.md5000066400000000000000000000000411464752671100342020ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX3614ce01a214ecd1e4ff942ebe51162f Texture2DWrapMode_Appearance_wrap_0.png.md5000066400000000000000000000000401464752671100334240ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX97731c498a8be29419817d89b04f2dbfTexture2DWrapMode_Appearance_wrap_1.png.md5000066400000000000000000000000401464752671100334250ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX878d5bb7e434080a24a9c284068041dbTexture2DWrapMode_Appearance_wrap_2.png.md5000066400000000000000000000000411464752671100334270ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX48e6abc7ca47afba486dfa7931720474 Texture2DWrapMode_Appearance_wrap_3.png.md5000066400000000000000000000000411464752671100334300ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX9ebc5695b54d4f49fc1efb2b7f9424b8 Texture2D_AppearanceMipMap_filter_0.png.md5000066400000000000000000000000411464752671100334060ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXd4c0b806767e8c1c602119eb8a9b518f Texture2D_AppearanceMipMap_filter_1.png.md5000066400000000000000000000000411464752671100334070ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX33e33e036c76a22c54e8ef50c09624de Texture2D_AppearanceMipMap_filter_2.png.md5000066400000000000000000000000411464752671100334100ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXa72c557405989810433e6e224c24620e Texture2D_AppearanceMipMap_filter_3.png.md5000066400000000000000000000000411464752671100334110ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX38a6d498ee18df22cc4ae0327dd7a1fc RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_0.png.md5000066400000000000000000000000411464752671100323610ustar00rootroot00000000000000d85b631ed7db2cf505751fff15f1a468 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_1.png.md5000066400000000000000000000000411464752671100323620ustar00rootroot00000000000000d85b631ed7db2cf505751fff15f1a468 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_2.png.md5000066400000000000000000000000411464752671100323630ustar00rootroot000000000000009e80fd2d73f0f6f91741679f43a4a093 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_3.png.md5000066400000000000000000000000411464752671100323640ustar00rootroot000000000000009e80fd2d73f0f6f91741679f43a4a093 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_4.png.md5000066400000000000000000000000411464752671100323650ustar00rootroot00000000000000abf592aa4f38e18c149e190f425e2b20 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_5.png.md5000066400000000000000000000000411464752671100323660ustar00rootroot00000000000000abf592aa4f38e18c149e190f425e2b20 RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_6.png.md5000066400000000000000000000000411464752671100323670ustar00rootroot000000000000000a473e6f77ebe81502c06f10cd055b5c RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX/Texture2D_Appearance_filter_7.png.md5000066400000000000000000000000411464752671100323700ustar00rootroot000000000000000a473e6f77ebe81502c06f10cd055b5c TextureVolumeTransform_Renderers_simple_0.png.md5000066400000000000000000000000411464752671100350760ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5ca76f28d3cca6fdf5b3037ac1da64fc TextureVolumeTransform_deprecated_Renderers_simple_0.png.md5000066400000000000000000000000411464752671100372560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5ca76f28d3cca6fdf5b3037ac1da64fc UnstructuredVolume_TestScenesVolumes_simple_0.png.md5000066400000000000000000000000411464752671100357530ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKXe84d5badebebaab3d5c24c5706707e91 UnstructuredVolume_TestScenesVolumes_simple_1.png.md5000066400000000000000000000000411464752671100357540ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX1b32c9097c03764a947ccb916ce5a1e2 UnstructuredVolume_TestScenesVolumes_simple_2.png.md5000066400000000000000000000000411464752671100357550ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX0985056e376af1dbbf72818dde10613c UnstructuredVolume_TestScenesVolumes_simple_3.png.md5000066400000000000000000000000411464752671100357560ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX5a5ebc39ddcc3a2f3355ef3bc5ae5753 UnstructuredVolume_TestScenesVolumes_simple_4.png.md5000066400000000000000000000000411464752671100357570ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX6572ac88ba74b7b4ac97ea8fc0e7469f UnstructuredVolume_TestScenesVolumes_simple_5.png.md5000066400000000000000000000000411464752671100357600ustar00rootroot00000000000000RenderKit-ospray-85af292/test_image_data/baseline/AVX512SKX361ab2e6a1e005d20400fd02bf9f42fd RenderKit-ospray-85af292/third-party-programs-DPCPP.txt000066400000000000000000000135661464752671100230120ustar00rootroot00000000000000 The oneAPI DPC++ Compiler can be found here: https://github.com/intel/llvm It uses various components with following licenses: https://github.com/intel/llvm/blob/master/flang/LICENSE.TXT https://github.com/intel/llvm/blob/master/compiler-rt/LICENSE.TXT https://github.com/intel/llvm/blob/master/mlir/LICENSE.TXT https://github.com/intel/llvm/blob/master/libclc/LICENSE.TXT https://github.com/intel/llvm/blob/master/libcxxabi/LICENSE.TXT https://github.com/intel/llvm/blob/master/lld/LICENSE.TXT https://github.com/intel/llvm/blob/master/cross-project-tests/debuginfo-tests/dexter/LICENSE.txt https://github.com/intel/llvm/blob/master/libc/LICENSE.TXT https://github.com/intel/llvm/blob/master/clang-tools-extra/LICENSE.TXT https://github.com/intel/llvm/blob/master/clang-tools-extra/clang-tidy/cert/LICENSE.TXT https://github.com/intel/llvm/blob/master/clang-tools-extra/clang-tidy/hicpp/LICENSE.TXT https://github.com/intel/llvm/blob/master/lldb/LICENSE.TXT https://github.com/intel/llvm/blob/master/lldb/third_party/Python/module/ptyprocess-0.6.0/LICENSE https://github.com/intel/llvm/blob/master/lldb/third_party/Python/module/six/LICENSE https://github.com/intel/llvm/blob/master/lldb/third_party/Python/module/pexpect-4.6/LICENSE https://github.com/intel/llvm/blob/master/polly/LICENSE.TXT https://github.com/intel/llvm/blob/master/polly/lib/External/isl/LICENSE https://github.com/intel/llvm/blob/master/polly/lib/External/isl/imath/LICENSE https://github.com/intel/llvm/blob/master/polly/tools/GPURuntime/LICENSE.TXT https://github.com/intel/llvm/blob/master/sycl/LICENSE.TXT https://github.com/intel/llvm/blob/master/llvm-spirv/LICENSE.TXT https://github.com/intel/llvm/blob/master/bolt/LICENSE.TXT https://github.com/intel/llvm/blob/master/pstl/LICENSE.TXT https://github.com/intel/llvm/blob/master/clang/LICENSE.TXT https://github.com/intel/llvm/blob/master/llvm/utils/lit/LICENSE.TXT https://github.com/intel/llvm/blob/master/llvm/utils/unittest/googletest/LICENSE.TXT https://github.com/intel/llvm/blob/master/llvm/utils/unittest/googlemock/LICENSE.txt https://github.com/intel/llvm/blob/master/llvm/LICENSE.TXT https://github.com/intel/llvm/blob/master/llvm/include/llvm/Support/LICENSE.TXT https://github.com/intel/llvm/blob/master/llvm/lib/Support/BLAKE3/LICENSE https://github.com/intel/llvm/blob/master/llvm/test/YAMLParser/LICENSE.txt https://github.com/intel/llvm/blob/master/libunwind/LICENSE.TXT https://github.com/intel/llvm/blob/master/openmp/LICENSE.TXT https://github.com/intel/llvm/blob/master/openmp/runtime/src/thirdparty/ittnotify/LICENSE.txt https://github.com/intel/llvm/blob/master/third-party/benchmark/LICENSE https://github.com/intel/llvm/blob/master/libcxx/LICENSE.TXT The following people and companies contributed to the LLVM project: https://github.com/intel/llvm/blob/master/compiler-rt/CREDITS.TXT https://github.com/intel/llvm/blob/master/libclc/CREDITS.TXT https://github.com/intel/llvm/blob/master/libcxxabi/CREDITS.TXT https://github.com/intel/llvm/blob/master/polly/CREDITS.txt https://github.com/intel/llvm/blob/master/pstl/CREDITS.txt https://github.com/intel/llvm/blob/master/llvm/CREDITS.TXT https://github.com/intel/llvm/blob/master/openmp/CREDITS.txt https://github.com/intel/llvm/blob/master/libcxx/CREDITS.TXT ============================================================================== Software from third parties included in the LLVM Project: ============================================================================== The LLVM Project contains third party software which is under different license terms. All such code will be identified clearly using at least one of two mechanisms: 1) It will be in a separate directory tree with its own `LICENSE.txt` or `LICENSE` file at the top containing the specific license and restrictions which apply to that software, or 2) It will contain specific license and restriction terms at the top of every file. ============================================================================== Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2003-2020 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. RenderKit-ospray-85af292/third-party-programs-Embree.txt000066400000000000000000003312451464752671100233400ustar00rootroot00000000000000Intel(R) Embree Third Party Programs File This file contains the list of third party software (third party programs) contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the third-party-programs.txt or other similarly-named text file. Third party programs and their corresponding required notices and/or license terms are listed below. 1. Apache License 2.0 ------------------------------------------------------------- 1.1. Intel(R) oneAPI Threading Building Blocks (TBB) https://github.com/oneapi-src/oneTBB Copyright Intel 1.2. Intel(R) Open Image Denoise (OIDN) https://github.com/OpenImageDenoise/oidn Copyright Intel Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 2. Apache License 2.0 with LLVM Exceptions ------------------------------------------------------------- 2.1. oneAPI DPC++ Compiler https://github.com/intel/llvm/ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ---- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. 3. Pixar Modified Apache License 2.0 ------------------------------------------------------------- 3.1 OpenSubdiv https://github.com/PixarAnimationStudios/OpenSubdiv Copyright 2013 Pixar All rights reserved. This product includes software developed at: Pixar (http://www.pixar.com/). Dreamworks Animation (http://www.dreamworksanimation.com/) Autodesk, Inc. (http://www.autodesk.com/). Google, Inc. (http://www.google.com/). DigitalFish (http://digitalfish.com/). This product includes software developed at: Pixar (http://www.pixar.com/). Modified Apache 2.0 License TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor and its affiliates, except as required to comply with Section 4(c) of the License and to reproduce the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 4. zLib License ------------------------------------------------------------- 4.1. GLFW https://github.com/glfw/glfw Copyright (c) 2002-2006 Marcus Geelnard Copyright (c) 2006-2019 Camilla Loewy This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. This notice may not be removed or altered from any source distribution. You can find this license in the file LICENSE.md of the GLFW source tree and in the comment header of each source file. 5. MIT License ------------------------------------------------------------- 5.1. Gruenschloss Halton https://gruenschloss.org/halton/halton.zip Copyright (c) 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org) 5.2. ImGui https://github.com/ocornut/imgui Copyright (c) 2014-2020 Omar Cornut 5.3. PCG Random Number Generation, C++ Edition https://github.com/imneme/pcg-cpp Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors 5.4. SSE2NEON https://github.com/DLTcollab/sse2neon 5.5. stb single-file libraries for C/C++ https://github.com/nothings/stb Copyright (c) 2017 Sean Barrett 5.6. A GPU Optimizer for Blue-Noise Screen-Space Sampler https://github.com/unity-grenoble/sampling_bluenoise_sig21 Copyright (c) 2020 Sylvain Durand The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6. BSD 3-clause License ------------------------------------------------------------- 6.1. OpenEXR https://github.com/AcademySoftwareFoundation/openexr Copyright (c) Contributors to the OpenEXR Project. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 7. BSD 3-clause License + Dependencies ------------------------------------------------------------- 7.1. TinyEXR https://github.com/syoyo/tinyexr Copyright (c) 2014 - 2021, Syoyo Fujita and many contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Syoyo Fujita nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. TinyEXR contains some OpenEXR code, which is licensed under: /////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas // Digital Ltd. LLC // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Industrial Light & Magic nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////// 8. Customized BSD 3-clause License ------------------------------------------------------------- 8.1. Syrah https://github.com/boulos/syrah Copyright (c) 2009, Stanford University, and authors listed below. All rights reserved. Original authors: Solomon Boulos Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Stanford University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 9. Boost Software License - Version 1.0 ------------------------------------------------------------- 9.1. Catch2 https://github.com/catchorg/Catch2 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10. Visual C++ Redistributables for Visual Studio ------------------------------------------------------------- 1. License. This software package from Intel (the “Software Packageâ€) contains code from Microsoft (the “Distributable Codeâ€). You are provided a non-transferable, non-exclusive, non-sublicensable, limited right and license only to use and redistribute the Distributable Code as part of this Software Package. You are not allowed to copy, modify, remove the Distributable Code from the Software Package or redistribute the Distributable Code on a stand-alone basis. 2. Restrictions. The Distributable Code is licensed, not sold. You are only provided the above rights to use the Distributable Code. Intel and Microsoft reserve all other rights. Unless applicable law gives you more rights, you may use the Distributable Code only as expressly permitted in these terms. In using the Distributable Code, you must comply with any technical limitations in the Distributable Code that only allow you to use it in certain ways. You may not: • work around any technical limitations in the Distributable Code; • reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the Distributable Code, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the Distributable Code; • remove, minimize, block or modify any notices of Intel, Microsoft or its suppliers in the Distributable Code; • use the Distributable Code in any way that is against the law; or • share, publish, rent or lease the software, or provide the Distributable Code as a stand-alone offering for others to use. 3. NO WARRANTY. THE DISTRIBUTABLE CODE IS PROVIDED “AS IS†WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. 4. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM INTEL, MICROSOFT OR THEIR SUPPLIERS ONLY DIRECT DAMAGES UP TO $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. This limitation applies to (a) anything related to the Distributable Code; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. It also applies even if Intel or Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages. 5. Export Restrictions. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting. 11. Pixar Modified Apache 2.0 ------------------------------------------------------------- 11.1 Universal Scene Description https://github.com/PixarAnimationStudios/USD Copyright 2016 Pixar All rights reserved. Modified Apache 2.0 License TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor and its affiliates, except as required to comply with Section 4(c) of the License and to reproduce the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ============================================================ RapidJSON ============================================================ Tencent is pleased to support the open source community by making RapidJSON available. Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. A copy of the MIT License is included in this file. Other dependencies and licenses: Open Source Software Licensed Under the BSD License: -------------------------------------------------------------------- The msinttypes r29 Copyright (c) 2006-2013 Alexander Chemeris All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Open Source Software Licensed Under the JSON License: -------------------------------------------------------------------- json.org Copyright (c) 2002 JSON.org All Rights Reserved. JSON_checker Copyright (c) 2002 JSON.org All Rights Reserved. Terms of the JSON License: --------------------------------------------------- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The Software shall be used for Good, not Evil. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Terms of the MIT License: -------------------------------------------------------------------- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ pygilstate_check ============================================================ The MIT License (MIT) Copyright (c) 2014, Pankaj Pandey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ double-conversion ============================================================ Copyright 2006-2011, the V8 project authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================ OpenEXR/IlmBase/Half ============================================================ /////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas // Digital Ltd. LLC // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Industrial Light & Magic nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////// ============================================================ Apple Technical Q&A QA1361 - Detecting the Debugger https://developer.apple.com/library/content/qa/qa1361/_index.html ============================================================ Sample code project: Detecting the Debugger Version: 1.0 Abstract: Shows how to determine if code is being run under the debugger. IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================ LZ4 ============================================================ LZ4 - Fast LZ compression algorithm Copyright (C) 2011-present, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - LZ4 homepage : http://www.lz4.org - LZ4 source repository : https://github.com/lz4/lz4 ============================================================ stb ============================================================ stb_image - v2.19 - public domain image loader - http://nothings.org/stb no warranty implied; use at your own risk stb_image_resize - v0.95 - public domain image resizing by Jorge L Rodriguez (@VinoBS) - 2014 http://github.com/nothings/stb stb_image_write - v1.09 - public domain - http://nothings.org/stb/stb_image_write.h writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 no warranty implied; use at your own risk ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ pugixml ============================================================ MIT License Copyright (c) 2006-2019 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ Vulkan C++ examples and demos (dome light texture filtering) ============================================================ The MIT License (MIT) Copyright (c) 2016 Sascha Willems Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ pbrt (Hammersley Low-Discrepancy Sampling Sequence) ============================================================ Copyright (c) 1998-2015, Matt Pharr, Greg Humphreys, and Wenzel Jakob. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================ Draco ============================================================ USD bundles Draco, which is available under the Apache 2.0 license. For details, see https://github.com/google/draco/blob/master/README.md. ============================================================ Roboto Fonts ============================================================ USD bundles Roboto fonts, which is available under the Apache 2.0 license. For details, see https://fonts.google.com/specimen/Roboto#license ============================================================ Roboto Mono Fonts ============================================================ USD bundles Roboto Mono fonts, which is available under the Apache 2.0 license. For details, see https://fonts.google.com/specimen/Roboto+Mono#license ============================================================ Vulkan Memory Allocator ============================================================ Copyright (c) 2017-2020 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ Spirv Reflect ============================================================ Copyright 2017-2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ============================================================ khrplatform.h ============================================================ Copyright (c) 2008-2018 The Khronos Group Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and/or associated documentation files (the "Materials"), to deal in the Materials without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Materials, and to permit persons to whom the Materials are furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Materials. THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. ============================================================ surfgrad-bump-standalone-demo ============================================================ MIT License Copyright (c) 2020 mmikk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================================ Tessil robin-map ================================================================ MIT License Copyright (c) 2017 Thibaut Goetghebuer-Planchon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11. Intel End User License Agreement for Developer Tools (Version October 2021) ------------------------------------------------------------------------------- 11.1 Intel(R) oneAPI DPC++/C++ Compiler Intel End User License Agreement for Developer Tools (Version October 2021) IMPORTANT NOTICE - PLEASE READ AND AGREE BEFORE DOWNLOADING, INSTALLING, COPYING OR USING This Agreement is between you, or the company or other legal entity that you represent and warrant you have the legal authority to bind, (each, "You" or "Your") and Intel Corporation and its subsidiaries (collectively, "Intel") regarding Your use of the Materials. By downloading, installing, copying or using the Materials, You agree to be bound by the terms of this Agreement. If You do not agree to the terms of this Agreement, or do not have legal authority or required age to agree to them, do not download, install, copy or use the Materials. LICENSE DEFINITIONS. A. "Cloud Provider" means a third party service provider offering a cloud-based platform, infrastructure, application or storage services, such as Microsoft Azure or Amazon Web Services, which You may only utilize to host the Materials subject to the restrictions set forth in Section 2.3 B. B. "Derivative Work" means a derivative work, as defined in 17 U.S.C. § 101, of the Source Code. C. "Executable Code" means computer programming code in binary form suitable for machine execution by a processor without the intervening steps of interpretation or compilation. D. "Materials" mean the software, documentation, the software product serial number, and other collateral, including any updates, made available to You by Intel under this Agreement. Materials include Redistributables, Executable Code, Source Code, Sample Source Code, and Pre-Release Materials, but do not include Third Party Software. E. "Pre-Release Materials" mean the Materials, or portions of the Materials, that are identified (in the product release notes, on Intel's download website for the Materials or elsewhere) or labeled as pre-release, prototype, alpha or beta code and, as such, are deemed to be pre-release code (i) which may not be fully functional or tested and may contain bugs or errors; (ii) which Intel may substantially modify in its development of a production version; or (iii) for which Intel makes no assurances that it will ever develop or make a production version generally available. Pre-Release Materials are subject to the terms of Section 3.2. F. "Reciprocal Open Source Software" means any software that is subject to a license which requires that (i) it must be distributed in source code form; (ii) it must be licensed under the same open source license terms; and (iii) its derivative works must be licensed under the same open source license terms. Examples of this type of license are the GNU General Public License or the Mozilla Public License. G. "Redistributables" mean the files (if any) listed in the "redist.txt," "redist-rt.txt" or similarlynamed text files that may be included in the Materials. Redistributables include Sample Source Code. H. "Sample Source Code" means those portions of the Materials that are Source Code and are identified as sample code. Sample Source Code may not have been tested or validated by Intel and is provided purely as a programming example. I. "Source Code" means the software portion of the Materials provided in human readable format. J. "Third Party Software" mean the files (if any) listed in the "third-party-software.txt" or other similarly-named text file that may be included in the Materials for the applicable software. Third Party Software is subject to the terms of Section 2.2. K. "Your Product" means one or more applications, products or projects developed by or for You using the Materials. 2. LICENSE GRANTS. 2.1 License to the Materials. Subject to the terms and conditions of this Agreement, Intel grants You a non-exclusive, worldwide, non-assignable, non-sublicensable, limited right and license under its copyrights, to: A. reproduce internally a reasonable number of copies of the Materials for Your personal or business use; B. use the Materials solely for Your personal or business use to develop Your Product, in accordance with the documentation included as part of the Materials; C. modify or create Derivative Works only of the Redistributables, or any portions, that are provided to You in Source Code; D. distribute (directly and through Your distributors, resellers, and other channel partners, if applicable), the Redistributables, including any modifications to or Derivative Works of the Redistributables or any portions made pursuant to Section 2.1.C subject to the following conditions: (1) Any distribution of the Redistributables must only be as part of Your Product which must add significant primary functionality different than that of the Redistributables themselves; (2) You must only distribute the Redistributables originally provided to You by Intel only in Executable Code subject to a license agreement that prohibits reverse engineering, decompiling or disassembling the Redistributables; (3) This distribution right includes a limited right to sublicense only the Intel copyrights in the Redistributables and only to the extent necessary to perform, display, and distribute the Redistributables (including Your modifications and Derivative Works of the Redistributables provided in Source Code) solely as incorporated in Your Product; and (4) You: (i) will be solely responsible to Your customers for any update, support obligation or other obligation or liability which may arise from the distribution of Your Product, (ii) will not make any statement that Your Product is "certified" or that its performance is guaranteed by Intel or its suppliers, (iii) will not use Intel's or its suppliers' names or trademarks to market Your Product, (iv) will comply with any additional restrictions which are included in the text files with the Redistributables and in Section 3 below, (v) will indemnify, hold harmless, and defend Intel and its suppliers from and against any claims or lawsuits, costs, damages, and expenses, including attorney's fees, that arise or result from (a) Your modifications or Derivative Works of the Materials or (b) Your distribution of Your Product. 2.2 Third Party Software. Third Party Software, even if included with the distribution of the Materials, may be governed by separate license terms, including without limitation, third party license terms, open source software notices and terms, and/or other Intel software license terms. These separate license terms solely govern Your use of the Third Party Software. 2.3 Third Party Use. A. If You are an entity, Your contractors may use the Materials under the license specified in Section 2, provided: (i) their use of the Materials is solely on behalf of and in support of Your business, (ii) they agree to the terms and conditions of this Agreement, and (iii) You are solely responsible for their use, misuse or disclosure of the Materials. B. You may utilize a Cloud Provider to host the Materials for You, provided: (i) the Cloud Provider may only host the Materials for Your exclusive use and may not use the Materials for any other purpose whatsoever, including the restriction set forth in Section 3.1(xi); (ii) the Cloud Provider's use of the Materials must be solely on behalf of and in support of Your Product, and (iii) You will indemnify, hold harmless, and defend Intel and its suppliers from and against any claims or lawsuits, costs, damages, and expenses, including attorney's fees, that arise or result from Your Cloud Provider's use, misuse or disclosure of the Materials. 3. LICENSE CONDITIONS. 3.1 Restrictions. Except as expressly provided in this Agreement, You may NOT: (i) use, reproduce, disclose, distribute, or publicly display the Materials; (ii) share, publish, rent or lease the Materials to any third party; (iii) assign this Agreement or transfer the Materials; (iv) modify, adapt, or translate the Materials in whole or in part; (v) reverse engineer, decompile, or disassemble the Materials, or otherwise attempt to derive the source code for the software; (vi) work around any technical limitations in the Materials; (vii) distribute, sublicense or transfer any Source Code, modifications or Derivative Works of any Source Code to any third party; (viii) remove, minimize, block or modify any notices of Intel or its suppliers in the Materials; (ix) include the Redistributables in malicious, deceptive, or unlawful programs or products or use the Materials in any way that is against the law; (x) modify, create a Derivative Work, link, or distribute the Materials so that any part of it becomes Reciprocal Open Source Software; (xi) use the Materials directly or indirectly for SaaS services or service bureau purposes (i.e., a service that allows use of or access to the Materials by a third party as part of that service, such as the salesforce.com service business model). 3.2 Pre-Release Materials. If You receive Pre-Release Materials, You may reproduce a reasonable number of copies and use the Pre-Release Materials for evaluation and testing purposes only. You may not (i) modify or incorporate the Pre-Release Materials into Your Product; (ii) continue to use the Pre-Release Materials once a commercial version is released; or (iii) disclose to any third party any benchmarks, performance results, or other information relating to the Pre-Release Materials. Intel may waive these restrictions in writing at its sole discretion; however, if You decide to use the Pre-Release Materials in Your Product (even with Intel's waiver), You acknowledge and agree that You are fully responsible for any and all issues that result from such use. 3.3 Safety-Critical, and Life-Saving Applications; Indemnity. The Materials may provide information relevant to safety-critical applications ("Safety-Critical Applications") to allow compliance with functional safety standards or requirements. You acknowledge and agree that safety is Your responsibility. To the extent You use the Materials to create, or as part of, products used in Safety-Critical Applications, it is Your responsibility to design, manage, and ensure that there are system-level safeguards to anticipate, monitor, and control system failures, and You agree that You are solely responsible for all applicable regulatory standards and safety-related requirements concerning Your use of the Materials in Safety Critical Applications. Should You use the Materials for Safety-Critical Applications or in any type of a system or application in which the failure of the Materials could create a situation where personal injury or death may occur (e.g., medical systems, life-sustaining or life-saving systems) ("Life-Saving Applications"), You agree to indemnify, defend, and hold Intel and its representatives harmless against any claims or lawsuits, costs, damages, and expenses, including reasonable attorney fees, arising in any way out of Your use of the Materials in Safety-Critical Applications or Life-Saving Applications and claims of product liability, personal injury or death associated with those applications; even if such claims allege that Intel was negligent or strictly liable regarding the design or manufacture of the Materials or its failure to warn regarding the Materials. 3.4 Media Format Codecs and Digital Rights Management. You acknowledge and agree that Your use of the Materials or distribution of the Redistributables with Your Product as permitted by this Agreement may require You to procure license(s) from third parties that may hold intellectual property rights applicable to any media decoding, encoding or transcoding technology (e.g., the use of an audio or video codec) and/or digital rights management capabilities of the Materials, if any. Should any such additional licenses be required, You are solely responsible for obtaining any such licenses and agree to obtain any such licenses at Your own expense. 4. DATA COLLECTION AND PRIVACY. 4.1 Data Collection. The Materials may generate and collect anonymous data and/or provisioning data about the Materials and/or the development environment and transmit the data to Intel as a one-time event during installation. Optional data may also be collected by the Materials, however, You will be provided notice of the request to collect optional data and no optional data will be collected without Your consent. All data collection by Intel is performed pursuant to relevant privacy laws, including notice and consent requirements. 4.2 Intel's Privacy Notice. Intel is committed to respecting Your privacy. To learn more about Intel's privacy practices, please visit http://www.intel.com/privacy. 5. OWNERSHIP. Title to the Materials and all copies remain with Intel or its suppliers. The Materials are protected by intellectual property rights, including without limitation, United States copyright laws and international treaty provisions. You will not remove any copyright or other proprietary notices from the Materials. Except as expressly provided herein, no license or right is granted to You directly or by implication, inducement, estoppel or otherwise; specifically, Intel does not grant any express or implied right to You under Intel patents, copyrights, trademarks, or trade secrets. 6. NO WARRANTY AND NO SUPPORT. 6.1 No Warranty. Disclaimer. Intel disclaims all warranties of any kind and the terms and remedies provided in this Agreement are instead of any other warranty or condition, express, implied or statutory, including those regarding merchantability, fitness for any particular purpose, non-infringement or any warranty arising out of any course of dealing, usage of trade, proposal, specification or sample. Intel does not assume (and does not authorize any person to assume on its behalf) any liability. 6.2 No Support; Priority Support. Intel may make changes to the Materials, or to items referenced therein, at any time without notice, but is not obligated to support, update or provide training for the Materials under the terms of this Agreement. Intel offers free community and paid priority support options. More information on these support options can be found at: https://software.intel.com/content/www/us/en/develop/support/priority-support.html. 7. LIMITATION OF LIABILITY. 7.1 Intel will not be liable for any of the following losses or damages (whether such losses or damages were foreseen, foreseeable, known or otherwise): (i) loss of revenue; (ii) loss of actual or anticipated profits; (iii) loss of the use of money; (iv) loss of anticipated savings; (v) loss of business; (vi) loss of opportunity; (vii) loss of goodwill; (viii) loss of use of the Materials; (ix) loss of reputation; (x) loss of, damage to, or corruption of data; or (xi) any indirect, incidental, special or consequential loss of damage however caused (including loss or damage of the type specified in this Section 7). 7.2 Intel's total cumulative liability to You, including for direct damages for claims relating to this Agreement, and whether for breach of contract, negligence, or for any other reason, will not exceed $100. 7.3 You acknowledge that the limitations of liability provided in this Section 7 are an essential part of this Agreement. You agree that the limitations of liability provided in this Agreement with respect to Intel will be conveyed to and made binding upon any customer of Yours that acquires the Redistributables. 8. USER SUBMISSIONS. Should you provide Intel with comments, modifications, corrections, enhancements or other input ("Feedback") related to the Materials, Intel will be free to use, disclose, reproduce, license or otherwise distribute or exploit the Feedback in its sole discretion without any obligations or restrictions of any kind, including without limitation, intellectual property rights or licensing obligations. If You wish to provide Intel with information that You intend to be treated as confidential information, Intel requires that such confidential information be provided pursuant to a non-disclosure agreement ("NDA"); please contact Your Intel representative to ensure the proper NDA is in place. 9. NON-DISCLOSURE. Information provided by Intel to You may include information marked as confidential. You must treat such information as confidential under the terms of the applicable NDA between Intel and You. If You have not entered into an NDA with Intel, You must not disclose, distribute or make use of any information marked as confidential, except as expressly authorized in writing by Intel. Intel retains all rights in and to its confidential information specifications, designs, engineering details, discoveries, inventions, patents, copyrights, trademarks, trade secrets, and other proprietary rights relating to the Materials. Any breach by You of the confidentiality obligations provided for in this Section 9 will cause irreparable injury to Intel for which money damages may be inadequate to compensate Intel for losses arising from such a breach. Intel may obtain equitable relief, including injunctive relief, if You breach or threaten to breach Your confidentiality obligations. 10. TERM AND TERMINATION. This Agreement becomes effective on the date You accept this Agreement and will continue until terminated as provided for in this Agreement. The term for any Pre-Release Materials terminates upon release of a commercial version. This Agreement will terminate if You are in breach of any of its terms and conditions. Upon termination, You will promptly destroy the Materials and all copies. In the event of termination of this Agreement, Your license to any Redistributables distributed by You in accordance with the terms and conditions of this Agreement, prior to the effective date of such termination, will survive any such termination of this Agreement. Sections 1, 2.1.D(4)(v), 2.2, 2.3.A(iii), 2.3.B(iii), 3.3, 5, 6, 7, 8, 9, 10 (with respect to these survival provisions in the last sentence), and 12 will survive expiration or termination of this Agreement. 11. U.S. GOVERNMENT RESTRICTED RIGHTS. The technical data and computer software covered by this license is a "Commercial Item," as such term is defined by the FAR 2.101 (48 C.F.R. 2.101) and is "commercial computer software" and "commercial computer software documentation" as specified under FAR 12.212 (48 C.F.R. 12.212) or DFARS 227.7202 (48 C.F.R. 227.7202), as applicable. This commercial computer software and related documentation is provided to end users for use by and on behalf of the U.S. Government with only those rights as are granted to all other end users pursuant to the terms and conditions of this Agreement. 12. GENERAL PROVISIONS. 12.1 ENTIRE AGREEMENT. This Agreement contains the complete and exclusive agreement and understanding between the parties concerning the subject matter of this Agreement, and supersedes all prior and contemporaneous proposals, agreements, understanding, negotiations, representations, warranties, conditions, and communications, oral or written, between the parties relating to the same subject matter. Each party acknowledges and agrees that in entering into this Agreement it has not relied on, and will not be entitled to rely on, any oral or written representations, warranties, conditions, understanding, or communications between the parties that are not expressly set forth in this Agreement. The express provisions of this Agreement control over any course of performance, course of dealing, or usage of the trade inconsistent with any of the provisions of this Agreement. The provisions of this Agreement will prevail notwithstanding any different, conflicting, or additional provisions that may appear on any purchase order, acknowledgement, invoice, or other writing issued by either party in connection with this Agreement. No modification or amendment to this Agreement will be effective unless in writing and signed by authorized representatives of each party, and must specifically identify this Agreement by its title and version (e.g., "Intel End User License Agreement for Developer Tools (Version October 2021)"); except that Intel may make changes to this Agreement as it distributes new versions of the Materials. When changes are made, Intel will make a new version of the Agreement available on its website. If You received a copy of this Agreement translated into another language, the English language version of this Agreement will prevail in the event of any conflict between versions. 12.2 EXPORT. You acknowledge that the Materials and all related technical information are subject to export controls and you agree to comply with all laws and regulations of the United States and other applicable governments governing export, re-export, import, transfer, distribution, and use of the Materials. In particular, but without limitation, the Materials may not be exported or re-exported (i) into any U.S. embargoed countries or (ii) to any person or entity listed on a denial order published by the U.S. government or any other applicable governments. By using the Materials, You represent and warrant that You are not located in any such country or on any such list. You also agree that You will not use the Materials for, or sell or transfer them to a third party who is known or suspected to be involved in, any purposes prohibited by the U.S. government or other applicable governments, including, without limitation, the development, design, manufacture, or production of nuclear, missile, chemical or biological weapons. 12.3 GOVERNING LAW, JURISDICTION, AND VENUE. All disputes arising out of or related to this Agreement, whether based on contract, tort, or any other legal or equitable theory, will in all respects be governed by, and construed and interpreted under, the laws of the United States of America and the State of Delaware, without reference to conflict of laws principles. The parties agree that the United Nations Convention on Contracts for the International Sale of Goods (1980) is specifically excluded from and will not apply to this Agreement. All disputes arising out of or related to this Agreement, whether based on contract, tort, or any other legal or equitable theory, will be subject to the exclusive jurisdiction of the courts of the State of Delaware or of the Federal courts sitting in that State. Each party submits to the personal jurisdiction of those courts and waives all objections to that jurisdiction and venue for those disputes. 12.4 SEVERABILITY. The parties intend that if a court holds that any provision or part of this Agreement is invalid or unenforceable under applicable law, the court will modify the provision to the minimum extent necessary to make it valid and enforceable, or if it cannot be made valid and enforceable, the parties intend that the court will sever and delete the provision or part from this Agreement. Any change to or deletion of a provision or part of this Agreement under this Section will not affect the validity or enforceability of the remainder of this Agreement, which will continue in full force and effect. 12. Additional Third Party Program Files ------------------------------------------------------------- The following third party programs have their own third party program files. These additional third party program files are as follows: 12.1. Intel(R) oneAPI Threading Building Blocks (TBB) third-party-programs-oneTBB.txt 12.2. Intel(R) Open Image Denoise (OIDN) third-party-programs-OIDN.txt file. 12.3. oneAPI DPC++ Compiler third-party-programs-DPCPP.txt file. 12.4. Intel(R) oneAPI DPC++/C++ Compiler third-party-programs-oneAPI-DPCPP.txt file. RenderKit-ospray-85af292/third-party-programs-ISPC.txt000066400000000000000000002742101464752671100226750ustar00rootroot00000000000000Intel(R) Implicit SPMD Program Compiler (Intel(R) ISPC) Third Party Programs File. This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the “third-party-programs.txt†or other similarly named text file. Third party programs and their corresponding required notices and/or license terms are listed below. -------------------------------------------------------------------------------- 1. LLVM Project. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ---- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. ============================================================================== Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -------------------------------------------------------------------------------- 2. Syrah library. Copyright (c) 2009, Stanford University, and authors listed below. All rights reserved. Original authors: Solomon Boulos Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Stanford University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 3. IEEE 754r Half Precision Floating Point Converter. (c) 2009 by James Tursa, All Rights Reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 4. libncurses libtinfo Copyright 2018-2021,2022 Thomas E. Dickey Copyright 1998-2017,2018 Free Software Foundation, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, distribute with modifications, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization. -------------------------------------------------------------------------------- 5. GNU libstdc++ libgcc GCC is Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Files that have exception clauses are licensed under the terms of the GNU General Public License; either version 3, or (at your option) any later version. On Debian GNU/Linux systems, the complete text of the GNU General Public License is in `/usr/share/common-licenses/GPL', version 3 of this license in `/usr/share/common-licenses/GPL-3'. The following runtime libraries are licensed under the terms of the GNU General Public License (v3 or later) with version 3.1 of the GCC Runtime Library Exception (included in this file): - libgcc (libgcc/, gcc/libgcc2.[ch], gcc/unwind*, gcc/gthr*, gcc/coretypes.h, gcc/crtstuff.c, gcc/defaults.h, gcc/dwarf2.h, gcc/emults.c, gcc/gbl-ctors.h, gcc/gcov-io.h, gcc/libgcov.c, gcc/tsystem.h, gcc/typeclass.h). - libatomic - libdecnumber - libgomp - libitm - libssp - libstdc++-v3 - libobjc - libgfortran - The libgnat-9 Ada support library and libgnatvsn library. - Various config files in gcc/config/ used in runtime libraries. - libvtv The libbacktrace library is licensed under the following terms: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The libsanitizer libraries (libasan, liblsan, libtsan, libubsan) are licensed under the following terms: Copyright (c) 2009-2014 by the LLVM contributors. All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The libffi library is licensed under the following terms: libffi - Copyright (c) 1996-2003 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The documentation is licensed under the GNU Free Documentation License (v1.2). On Debian GNU/Linux systems, the complete text of this license is in `/usr/share/common-licenses/GFDL-1.2'. GCC RUNTIME LIBRARY EXCEPTION Version 3.1, 31 March 2009 Copyright (C) 2009 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception. When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception. 0. Definitions. A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library. "GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF. "GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC. "Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation. The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors. A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process. 1. Grant of Additional Permission. You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules. 2. No Weakening of GCC Copyleft. The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC. libquadmath/*.[hc]: Copyright (C) 2010 Free Software Foundation, Inc. Written by Francois-Xavier Coudert Written by Tobias Burnus This file is part of the libiberty library. Libiberty is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libiberty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. libquadmath/math: atanq.c, expm1q.c, j0q.c, j1q.c, log1pq.c, logq.c: Copyright 2001 by Stephen L. Moshier This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. coshq.c, erfq.c, jnq.c, lgammaq.c, powq.c, roundq.c: Changes for 128-bit __float128 are Copyright (C) 2001 Stephen L. Moshier and are incorporated herein by permission of the author. The author reserves the right to distribute this material elsewhere under different copying permissions. These modifications are distributed here under the following terms: This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. ldexpq.c: * Conversion to long double by Ulrich Drepper, * Cygnus Support, drepper@cygnus.com. cosq_kernel.c, expq.c, sincos_table.c, sincosq.c, sincosq_kernel.c, sinq_kernel.c, truncq.c: Copyright (C) 1997, 1999 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. isinfq.c: * Written by J.T. Conklin . * Change for long double by Jakub Jelinek * Public domain. llroundq.c, lroundq.c, tgammaq.c: Copyright (C) 1997, 1999, 2002, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997 and Jakub Jelinek , 1999. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. log10q.c: Cephes Math Library Release 2.2: January, 1991 Copyright 1984, 1991 by Stephen L. Moshier Adapted for glibc November, 2001 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. remaining files: * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. gcc/go/gofrontend, libgo: Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. D: gdc-9 GNU D Compiler libphobos-9-dev D standard runtime library The D source package is made up of the following components. The D front-end for GCC: - d/* Copyright (C) 2004-2007 David Friedman Modified by Vincenzo Ampolo, Michael Parrot, Iain Buclaw, (C) 2009, 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. On Debian GNU/Linux systems, the complete text of the GNU General Public License is in `/usr/share/common-licenses/GPL', version 2 of this license in `/usr/share/common-licenses/GPL-2'. The DMD Compiler implementation of the D programming language: - d/dmd/* Copyright (c) 1999-2010 by Digital Mars All Rights Reserved written by Walter Bright http://www.digitalmars.com License for redistribution is by either the Artistic License or the GNU General Public License (v1). On Debian GNU/Linux systems, the complete text of the GNU General Public License is in `/usr/share/common-licenses/GPL', the Artistic license in `/usr/share/common-licenses/Artistic'. The Zlib data compression library: - d/phobos/etc/c/zlib/* (C) 1995-2004 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. The Phobos standard runtime library: - d/phobos/* Unless otherwise marked within the file, each file in the source is under the following licenses: Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com Written by Walter Bright This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, in both source and binary form, subject to the following restrictions: o The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. o Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. o This notice may not be removed or altered from any source distribution. By plainly marking modifications, something along the lines of adding to each file that has been changed a "Modified by Foo Bar" line underneath the "Written by" line would be adequate. The libhsail-rt library is licensed under the following terms: Copyright (C) 2015-2017 Free Software Foundation, Inc. Contributed by Pekka Jaaskelainen for General Processor Tech. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. libhsail-rt/rt/fp16.c is licensed under the following terms: Copyright (C) 2008-2017 Free Software Foundation, Inc. Contributed by CodeSourcery. This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . gcc/gm2: Copyright (C) 2007-2019 Free Software Foundation, Inc. Contributed by Gaius Mulley . This file is part of GNU Modula-2. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. gcc/gm2/**/*.texi: Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2012, 2013 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. gcc/gm2/gm2-coroutines: Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. gcc/gm2/ulm-lib-gm2: Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This file was originally part of the University of Ulm library Ulm's Modula-2 Library Copyright (C) 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 by University of Ulm, SAI, D-89069 Ulm, Germany gcc/gm2/ulm-lib-gm2/std/M2RTS.mod: gcc/gm2/ulm-lib-gm2/std/Storage.mod: gcc/gm2/ulm-lib-gm2/std/RTExceptions.mod: Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. gcc/gm2/gm2-libs: Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. ./gm2-libs/cbuiltin.def: ./gm2-libs/MathLib0.def: ./gm2-libs/SYSTEM.def: ./gm2-libs/sckt.def: ./gm2-libs/Indexing.def: ./gm2-libs/Builtins.mod: ./gm2-libs/SFIO.mod: ./gm2-libs/MathLib0.mod: ./gm2-libs/gdbif.mod: ./gm2-libs/M2EXCEPTION.mod: ./gm2-libs/SFIO.def: ./gm2-libs/StringConvert.mod: ./gm2-libs/StringConvert.def: ./gm2-libs/config-host.in: ./gm2-libs/Indexing.mod: ./gm2-libs/errno.def: Copyright (C) 2001-2019 Free Software Foundation, Inc. Contributed by Gaius Mulley . GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ./gm2-libs/M2EXCEPTION.def: Library module defined by the International Standard Information technology - programming languages BS ISO/IEC 10514-1:1996E Part 1: Modula-2, Base Language. Copyright ISO/IEC (International Organization for Standardization and International Electrotechnical Commission) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 gcc/gm2/gm2-libiberty/: Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. gcc/gm2/gm2-libs-iso/: This has a mix of licenses, both LGPL-2.1 and GPL-3.0, plus the apparently unmodified definition modules from ISO/IEC. gcc/gm2/gm2-libs-iso/*.def: Library module defined by the International Standard Information technology - programming languages BS ISO/IEC 10514-1:1996E Part 1: Modula-2, Base Language. Copyright ISO/IEC (International Organization for Standardization and International Electrotechnical Commission) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 gcc/gm2/gm2-libs-iso/*.def: Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. gcc/gm2/gm2-libs-iso/*.def: This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. gcc/gm2/gm2-libs-iso/*.mod: Copyright (C) 2012 Free Software Foundation, Inc. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. gcc/gm2/gm2-libs-iso/*.mod: Copyright (C) 2009, 2010 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. gcc/gm2/gm2-libs-min/*: Copyright (C) 2001-2019 Free Software Foundation, Inc. mix of GPL-3.0 and LGPL-3.0 gcc/gm2/gm2-libs-pim/*: Copyright (C) 2001-2019 Free Software Foundation, Inc. mix of GPL-3.0 and LGPL-2.1/3 gcc/gm2/gm2-libs-ch/*: Copyright (C) 2001-2019 Free Software Foundation, Inc. mix of GPL-3.0 and LGPL-2.1/3 gcc/gm2/examples: Copyright (C) 2005-2015 Free Software Foundation, Inc. Mix of LGPL-2.1 and GPL-3.0. gcc/gm2/images: GPL-3+ gcc/gm2/el/gm2-mode.el: ;; Everyone is granted permission to copy, modify and redistribute ;; GNU Emacs, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is ;; supposed to have been given to you along with GNU Emacs so you ;; can know your rights and responsibilities. It should be in a ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. gcc/gm2/mc-boot/: Copyright (C) 2001-2018 Free Software Foundation, Inc. Contributed by Gaius Mulley . Mix of GPL-3 and LGPL-2.1. gcc/testsuite/gm2/: Copyright (C) 2001-2019 Free Software Foundation, Inc. Mix of GPL-2+ and GPL-3+ libgm2: libgm2/libiso/: Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. libgm2/libpim/: Copyright (C) 2005-2014 Free Software Foundation, Inc. Mix of LGPL-2.1, LGPL-3 and GPL-3. libgm2/liblog/: Copyright (C) 2005-2018 Free Software Foundation, Inc. Mix of LGPL-2.1 and LGPL-3. libgm2/libpth/: Copyright: (C) 1999-2006 Ralf S. Engelschall License: LGPL-2.1+ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. . This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. libgm2/libulm/: Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. libgm2/libcor/: Copyright (C) 2005-2019 Free Software Foundation, Inc. Contributed by Gaius Mulley . GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. libgm2/libmin/: Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. libgm2/p2c/: Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. newlib-X.Y.Z/: Upstream Authors: newlib@sources.redhat.com Jeff Johnston Tom Fitzsimmons The newlib subdirectory is a collection of software from several sources. Each file may have its own copyright/license that is embedded in the source file. This list documents those licenses which are more restrictive than a BSD-like license or require the copyright notice to be duplicated in documentation and/or other materials associated with the distribution. Certain licenses documented here only apply to specific targets. Certain clauses only apply if you are building the code as part of your binary. Note that this list may omit certain licenses that only pertain to the copying/modifying of the individual source code. If you are distributing the source code, then you do not need to worry about these omitted licenses, so long as you do not modify the copyright information already in place. Parts of this work are licensed under the terms of the GNU General Public License. On Debian systems, the complete text of this license can be found in /usr/share/common-licenses/GPL. Parts of this work are licensed under the terms of the GNU Library General Public License. On Debian systems, the complete text of this license be found in /usr/share/common-licenses/LGPL. (1) University of California, Berkeley [1a] Copyright (c) 1990 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms are permitted provided that the above copyright notice and this paragraph are duplicated in all such forms and that any documentation, and other materials related to such distribution and use acknowledge that the software was developed by the University of California, Berkeley. The name of the University may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. [1b] Copyright (c) 1990 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms are permitted provided that the above copyright notice and this paragraph are duplicated in all such forms and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed by the University of California, Berkeley. The name of the University may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. [1c] Copyright (c) 1981, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [1d] Copyright (c) 1988, 1990, 1993 Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [1e] Copyright (c) 1982, 1986, 1989, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. (c) UNIX System Laboratories, Inc. All or some portions of this file are derived from material licensed to the University of California by American Telephone and Telegraph Co. or Unix System Laboratories, Inc. and are reproduced herein with the permission of UNIX System Laboratories, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [1f] Copyright (c) 1987, 1988, 2000 Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms are permitted provided that: (1) source distributions retain this entire copyright notice and comment, and (2) distributions including binaries display the following acknowledgement: ``This product includes software developed by the University of California, Berkeley and its contributors'' in the documentation or other materials provided with the distribution and in all advertising materials mentioning features or use of this software. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ------------------------------------------------------------- Please note that in some of the above alternate licenses, there is a statement regarding that acknowledgement must be made in any advertising materials for products using the code. This restriction no longer applies due to the following license change: ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change In some cases the defunct clause has been removed in modified newlib code and in some cases, the clause has been left as-is. ------------------------------------------------------------- (2) Cygwin (cygwin targets only) Copyright 2001 Red Hat, Inc. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. (3) David M. Gay at AT&T The author of this software is David M. Gay. Copyright (c) 1991 by AT&T. Permission to use, copy, modify, and distribute this software for any purpose without fee is hereby granted, provided that this entire notice is included in all copies of any software which is or includes a copy or modification of this software and in all copies of the supporting documentation for such software. THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. (4) Advanced Micro Devices Copyright 1989, 1990 Advanced Micro Devices, Inc. This software is the property of Advanced Micro Devices, Inc (AMD) which specifically grants the user the right to modify, use and distribute this software provided this notice is not removed or altered. All other rights are reserved by AMD. AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR USE OF THIS SOFTWARE. So that all may benefit from your experience, please report any problems or suggestions about this software to the 29K Technical Support Center at 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or 0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118. Advanced Micro Devices, Inc. 29K Support Products Mail Stop 573 5900 E. Ben White Blvd. Austin, TX 78741 800-292-9263 (5) C.W. Sandmann Copyright (C) 1993 C.W. Sandmann This file may be freely distributed as long as the author's name remains. (6) Eric Backus (C) Copyright 1992 Eric Backus This software may be used freely so long as this copyright notice is left intact. There is no warrantee on this software. (7) Sun Microsystems Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. Developed at SunPro, a Sun Microsystems, Inc. business. Permission to use, copy, modify, and distribute this software is freely granted, provided that this notice is preserved. (8) Hewlett Packard (c) Copyright 1986 HEWLETT-PACKARD COMPANY To anyone who acknowledges that this file is provided "AS IS" without any express or implied warranty: permission to use, copy, modify, and distribute this file for any purpose is hereby granted without fee, provided that the above copyright notice and this notice appears in all copies, and that the name of Hewlett-Packard Company not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. (9) Hans-Peter Nilsson Copyright (C) 2001 Hans-Peter Nilsson Permission to use, copy, modify, and distribute this software is freely granted, provided that the above copyright notice, this notice and the following disclaimer are preserved with no changes. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. (10) Stephane Carrez (m68hc11-elf/m68hc12-elf targets only) Copyright (C) 1999, 2000, 2001, 2002 Stephane Carrez (stcarrez@nerim.fr) The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. (11) Christopher G. Demetriou Copyright (c) 2001 Christopher G. Demetriou All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (12) SuperH, Inc. Copyright 2002 SuperH, Inc. All rights reserved This software is the property of SuperH, Inc (SuperH) which specifically grants the user the right to modify, use and distribute this software provided this notice is not removed or altered. All other rights are reserved by SuperH. SUPERH MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE. IN NO EVENT SHALL SUPERH BE LIABLE FOR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR USE OF THIS SOFTWARE. So that all may benefit from your experience, please report any problems or suggestions about this software to the SuperH Support Center via e-mail at softwaresupport@superh.com . SuperH, Inc. 405 River Oaks Parkway San Jose CA 95134 USA (13) Royal Institute of Technology Copyright (c) 1999 Kungliga Tekniska Hgskolan (Royal Institute of Technology, Stockholm, Sweden). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of KTH nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (14) Alexey Zelkin Copyright (c) 2000, 2001 Alexey Zelkin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (15) Andrey A. Chernov Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (16) FreeBSD Copyright (c) 1997-2002 FreeBSD Project. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (17) S. L. Moshier Author: S. L. Moshier. Copyright (c) 1984,2000 S.L. Moshier Permission to use, copy, modify, and distribute this software for any purpose without fee is hereby granted, provided that this entire notice is included in all copies of any software which is or includes a copy or modification of this software and in all copies of the supporting documentation for such software. THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. (18) Citrus Project Copyright (c)1999 Citrus Project, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (19) Todd C. Miller Copyright (c) 1998 Todd C. Miller All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (20) DJ Delorie (i386) Copyright (C) 1991 DJ Delorie All rights reserved. Redistribution and use in source and binary forms is permitted provided that the above copyright notice and following paragraph are duplicated in all such forms. This file is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. (21) Free Software Foundation LGPL License (*-linux* targets only) Copyright (C) 1990-1999, 2000, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Mark Kettenis , 1997. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA (22) Xavier Leroy LGPL License (i[3456]86-*-linux* targets only) Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. (23) Intel (i960) Copyright (c) 1993 Intel Corporation Intel hereby grants you permission to copy, modify, and distribute this software and its documentation. Intel grants this permission provided that the above copyright notice appears in all copies and that both the copyright notice and this permission notice appear in supporting documentation. In addition, Intel grants this permission provided that you prominently mark as "not part of the original" any modifications made to this software or documentation, and that the name of Intel Corporation not be used in advertising or publicity pertaining to distribution of the software or the documentation without specific, written prior permission. Intel Corporation provides this AS IS, WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Intel makes no guarantee or representations regarding the use of, or the results of the use of, the software and documentation in terms of correctness, accuracy, reliability, currentness, or otherwise; and you rely on the software, documentation and results solely at your own risk. IN NO EVENT SHALL INTEL BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS, LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OF ANY KIND. IN NO EVENT SHALL INTEL'S TOTAL LIABILITY EXCEED THE SUM PAID TO INTEL FOR THE PRODUCT LICENSED HEREUNDER. (24) Hewlett-Packard (hppa targets only) (c) Copyright 1986 HEWLETT-PACKARD COMPANY To anyone who acknowledges that this file is provided "AS IS" without any express or implied warranty: permission to use, copy, modify, and distribute this file for any purpose is hereby granted without fee, provided that the above copyright notice and this notice appears in all copies, and that the name of Hewlett-Packard Company not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. (25) Henry Spencer (only *-linux targets) Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved. This software is not subject to any license of the American Telephone and Telegraph Company or of the Regents of the University of California. Permission is granted to anyone to use this software for any purpose on any computer system, and to alter it and redistribute it, subject to the following restrictions: 1. The author is not responsible for the consequences of use of this software, no matter how awful, even if they arise from flaws in it. 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. Since few users ever read sources, credits must appear in the documentation. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Since few users ever read sources, credits must appear in the documentation. 4. This notice may not be removed or altered. (26) Mike Barcroft Copyright (c) 2001 Mike Barcroft All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (27) Konstantin Chuguev (--enable-newlib-iconv) Copyright (c) 1999, 2000 Konstantin Chuguev. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. iconv (Charset Conversion Library) v2.0 (27) Artem Bityuckiy (--enable-newlib-iconv) Copyright (c) 2003, Artem B. Bityuckiy, SoftMine Corporation. Rights transferred to Franklin Electronic Publishers. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (28) Red Hat Incorporated Unless otherwise stated in each remaining newlib file, the remaining files in the newlib subdirectory default to the following copyright. It should be noted that Red Hat Incorporated now owns copyrights belonging to Cygnus Solutions and Cygnus Support. Copyright (c) 1994, 1997, 2001, 2002, 2003, 2004 Red Hat Incorporated. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. The name of Red Hat Incorporated may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 6. libLLVMGenXIntrinsics MIT License Copyright (c) 2020 Intel Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 7. libLLVMSPIRVLib ============================================================================== LLVM Release License ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. ============================================================================== Copyrights and Licenses for Third Party Software Distributed with LLVM: ============================================================================== The LLVM software contains code written by third parties. Such software will have its own individual LICENSE.TXT file in the directory in which it appears. This file will describe the copyrights, license, and restrictions which apply to that code. The disclaimer of warranty in the University of Illinois Open Source License applies to all code in the LLVM Distribution, and nothing in any of the other licenses gives permission to use the names of the LLVM Team or the University of Illinois to endorse or promote products derived from this Software. The following pieces of software have additional or alternate copyrights, licenses, and/or restrictions: Program Directory ------- --------- Autoconf llvm/autoconf llvm/projects/ModuleMaker/autoconf Google Test llvm/utils/unittest/googletest OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT} ARM contributions llvm/lib/Target/ARM/LICENSE.TXT md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h -------------------------------------------------------------------------------- Other names and brands may be claimed as the property of others. RenderKit-ospray-85af292/third-party-programs-OIDN.txt000066400000000000000000001025331464752671100226660ustar00rootroot00000000000000Intel(R) Open Image Denoise Third Party Programs File This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the "third-party-programs.txt" or other similarly named text file. Third party programs and their corresponding required notices and/or license terms are listed below. -------------------------------------------------------------------------------- 1. Intel(R) oneAPI Deep Neural Network Library (oneDNN) Copyright 2016-2023 Intel Corporation Intel(R) oneAPI Threading Building Blocks (oneTBB) Copyright 2005-2023 Intel Corporation Intel® Embree (snippets) Copyright Intel Corporation Intel® OSPRay (snippets) Copyright Intel Corporation Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- 2. PyTorch From PyTorch: Copyright (c) 2016- Facebook, Inc (Adam Paszke) Copyright (c) 2014- Facebook, Inc (Soumith Chintala) Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) Copyright (c) 2011-2013 NYU (Clement Farabet) Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute (Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz) From Caffe2: Copyright (c) 2016-present, Facebook Inc. All rights reserved. All contributions by Facebook: Copyright (c) 2016 Facebook Inc. All contributions by Google: Copyright (c) 2015 Google Inc. All rights reserved. All contributions by Yangqing Jia: Copyright (c) 2015 Yangqing Jia All rights reserved. All contributions from Caffe: Copyright(c) 2013, 2014, 2015, the respective contributors All rights reserved. All other contributions: Copyright(c) 2015, 2016 the respective contributors All rights reserved. Caffe2 uses a copyright model similar to Caffe: each contributor holds copyright over their contributions to Caffe2. The project versioning records all such contribution and copyright details. If a contributor wants to further mark their specific copyright on a particular contribution, they should indicate their copyright solely in the commit message of the change when it is committed. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories America and IDIAP Research Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 3. pytorch-msssim Copyright (c) 2019 Gongfan Fang ROCmSoftwarePlatform/composable_kernel Copyright (c) 2018- , Advanced Micro Devices, Inc. (Chao Liu, Jing Zhang) Copyright (c) 2019- , Advanced Micro Devices, Inc. (Letao Qin, Qianfeng Zhang, Liang Huang, Shaojie Wang) Copyright (c) 2022- , Advanced Micro Devices, Inc. (Anthony Chang, Chunyu Lai, Illia Silin, Adam Osewski, Poyen Chen, Jehandad Khan) Copyright (c) 2019-2021, Advanced Micro Devices, Inc. (Hanwen Chang) Copyright (c) 2019-2020, Advanced Micro Devices, Inc. (Tejash Shah) Copyright (c) 2020 , Advanced Micro Devices, Inc. (Xiaoyan Zhou) Copyright (c) 2021-2022, Advanced Micro Devices, Inc. (Jianfeng Yan) Copyright (c) 2018-2022, Advanced Micro Devices, Inc. All rights reserved. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 4. Catch2 Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 5. CUTLASS Copyright (c) 2017 - 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-3-Clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 6. oneAPI Data Parallel C++ Compiler Copyright Intel Corporation ============================================================================== The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: ============================================================================== Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ---- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. -------------------------------------------------------------------------------- The following third party programs have their own third party programs. These additional third party program files are as follows: 1. Intel(R) oneAPI Deep Neural Network Library (oneDNN) ./third-party-programs-oneDNN.txt 2. Intel(R) oneAPI Threading Building Blocks (oneTBB) ./third-party-programs-oneTBB.txt 3. oneAPI DPC++ Compiler ./third-party-programs-DPCPP.txt --------------------------------------------------------------------------------RenderKit-ospray-85af292/third-party-programs-OpenVKL.txt000066400000000000000000001062411464752671100234130ustar00rootroot00000000000000Intel(R) Open Volume Kernel Library Third Party Programs File This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the "third-party-programs.txt" or other similarly- named text file. Third party programs and their corresponding required notices and/or license terms are listed below. -------------------------------------------------------------------------------- 1. Boost C++ Libraries Copyright Beman Dawes, David Abrahams, 1998-2005. Copyright Rene Rivera 2004-2005. Catch2 Copyright 2010 Two Blue Cubes Ltd Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 2. IlmBase (part of OpenEXR) Copyright (c) 2006-2019 OpenEXR a Series of LF Projects, LLC. All rights reserved. BSD 3-Clause "New" or "Revised" License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 3. Dear ImGui Copyright (c) 2014-2020 Omar Cornut half Copyright (c) 2012-2021 Christian Rau SSE2NEON The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 4. Embree Copyright 2009 Intel Corporation Google Benchmark Copyright 2014 Google Inc. All rights reserved. OSPRay Copyright 2009 Intel Corporation Threading Building Blocks (oneTBB) Copyright 2005 Intel Corporation Apache License Version 2.0 January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- 5. GLFW Copyright (c) 2002-2006 Marcus Geelnard Copyright (c) 2006-2019 Camilla Löwy zlib Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler zlib License This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- 6. OpenVDB Copyright Contributors to the OpenVDB Project Mozilla Public License Version 2.0 1. Definitions 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means (a) that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or (b) that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: (a) any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or (b) any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and (b) under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: (a) for any code that a Contributor has removed from Covered Software; or (b) for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or (c) under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: (a) such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and (b) You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- 7. C-Blosc Copyright (C) 2009-2018 Francesc Alted Copyright (C) 2019-present Blosc Development team BSD-3-Clause (modified) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Francesc Alted nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- The following third party programs have their own third party programs. These additional third party program files are as follows: 1. Embree: ./third-party-programs-Embree.txt 2. OSPRay: ./third-party-programs.txt 3. Threading Building Blocks (TBB): ./third-party-programs-oneTBB.txt -------------------------------------------------------------------------------- Other names and brands may be claimed as the property of others. RenderKit-ospray-85af292/third-party-programs-oneAPI-DPCPP.txt000066400000000000000000002120101464752671100241040ustar00rootroot00000000000000Intel(R) 2023.0 oneAPI DPC++/C++/Fortran Compiler Third Party Programs File This file is the "third-party-programs.txt" file specified in the associated Intel end user license agreement for the Intel software you are licensing. Third party programs and their corresponding required notices and/or license terms are listed below. ----------------------------------------------------------------- 1. Khronos Group - OpenCL header Copyright (c) 2008-2020 The Khronos Group Inc. Khronos OpenCL ICD Loader Copyright (c) 2020 The Khronos Group Inc. Threading Building Blocks Copyright 2020 Intel Corporation Mentor Graphics Algorithmic C Types Copyright 2008-2016, Mentor Graphics Corporation Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ----------------------------------------------------------------- 2. Khronos Group - SPIRV-LLVM-Translator ============================================================================== LLVM Release License ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. ============================================================================== Copyrights and Licenses for Third Party Software Distributed with LLVM: ============================================================================== The LLVM software contains code written by third parties. Such software will have its own individual LICENSE.TXT file in the directory in which it appears. This file will describe the copyrights, license, and restrictions which apply to that code. The disclaimer of warranty in the University of Illinois Open Source License applies to all code in the LLVM Distribution, and nothing in any of the other licenses gives permission to use the names of the LLVM Team or the University of Illinois to endorse or promote products derived from this Software. The following pieces of software have additional or alternate copyrights, licenses, and/or restrictions: Program Directory ------- --------- Autoconf llvm/autoconf llvm/projects/ModuleMaker/autoconf Google Test llvm/utils/unittest/googletest OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT} ARM contributions llvm/lib/Target/ARM/LICENSE.TXT md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h ----------------------------------------------------------------- 3. llvm-project llvm-project ============================================================================== The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: ============================================================================== Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ---- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. ============================================================================== Software from third parties included in the LLVM Project: ============================================================================== The LLVM Project contains third party software which is under different license terms. All such code will be identified clearly using at least one of two mechanisms: 1) It will be in a separate directory tree with its own `LICENSE.txt` or `LICENSE` file at the top containing the specific license and restrictions which apply to that software, or 2) It will contain specific license and restriction terms at the top of every file. ============================================================================== Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. ----------------------------------------------------------------- 4. fpp - Fortran PreProcessor Copyright (C) 2002-2020 Intel Corporation. All rights reserved. Portions Copyright (C) 1995 by Sun Microsystems, Inc. All rights reserved. Developed at SunSoft, a Sun Microsystems, Inc. business. Permission to use, copy, modify, and distribute this software is freely granted, provided that this notice is preserved. ----------------------------------------------------------------- 5. Intel compute-runtime Copyright 2019 Intel Corporation. Intel vc-intrinsics Copyright 2021 Intel Corporation. libffi Copyright (c) 1996-2021 Anthony Green, Red Hat, Inc and others. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------- 6. protobuf Copyright 2008 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Code generated by the Protocol Buffer compiler is owned by the owner of the input file used when generating it. This code is not standalone and requires a support library to be linked with it. This support library is itself covered by the above license. ----------------------------------------------------------------- 7. MP11 Copyright 2021 Intel Corporation. Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------- 8. Unicode Data Files UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE See Terms of Use for definitions of Unicode Inc.’s Data Files and Software. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. COPYRIGHT AND PERMISSION NOTICE Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. ----------------------------------------------------------------- The following third party programs have their own third party program files. These additional third party program files can be found as follows: 1. Threading Building Blocks: /tbb/licensing/third-party-programs.txt ----------------------------------------------------------------- Intel(R) 2021.8 C/C++/Fortran Compiler Classic Third Party Programs File This file is the "third-party-programs.txt" file specified in the associated Intel end user license agreement for the Intel software you are licensing. Third party programs and their corresponding required notices and/or license terms are listed below. ----------------------------------------------------------------- 1. libdwarf Copyright 2020 Intel Corporatio LIBDWARF Copyright To enable use of the DWARF2 libdwarf interface, the following copyright and notice must be included in this document. Note this notice is for libdwarf only. All other source and documentation are copyright by Intel Corp. LIBDWARF permission notice: Copyright (c) 1994 Silicon Graphics, Inc. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that (i) the above copyright notice and this permission notice appear in all copies of the software and related documentation, and (ii) the name "Silicon Graphics" or any other trademark of Silicon Graphics, Inc. may not be used in any advertising or publicity relating to the software without the specific, prior written permission of Silicon Graphics, Inc. THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ----------------------------------------------------------------- 2. Alladin Enterprises MD5 Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com ----------------------------------------------------------------- 3. ATL Server Library and Tools Microsoft Limited Permissive License (Ms-LPL) Published: October 18, 2005 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 1. Definitions o The terms "reproduce," "reproduction" and "distribution" have the same meaning here as under U.S. copyright law. o "You" means the licensee of the software. o "Licensed patents" means any Microsoft patent claims which read directly on the software as distributed by Microsoft under this license. 2. Grant of Rights a. Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, Microsoft grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce the software, prepare derivative works of the software and distribute the software or any derivative works that you create. b. Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, Microsoft grants you a non-exclusive, worldwide, royalty-free patent license under licensed patents to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the software or derivative works of the software. 3. Conditions and Limitations . No Trademark License- This license does not grant you any rights to use Microsoft's name, logo, or trademarks. a. If you begin patent litigation against Microsoft over patents that you think may apply to the software (including a cross-claim or counterclaim in a lawsuit), your license to the software ends automatically. b. If you distribute copies of the software or derivative works, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. c. If you distribute the software or derivative works in source code form you may do so only under this license (i.e., you must include a complete copy of this license with your distribution), and if you distribute the software or derivative works in compiled or object code form you may only do so under a license that complies with this license. d. The software is licensed "as-is." You bear the risk of using it. Microsoft gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, Microsoft excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement. e. Platform Limitation- The licenses granted in sections 2(A) & 2(B) extend only to the software or derivative works that you create that run on a Microsoft Windows operating system product. ----------------------------------------------------------------- 5. llvm-project llvm-project Copyright 2020 Intel Corporation Intel Open Source Compiler Header Files Copyright 2020 Intel Corporation Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems,and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of,publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and condition for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. ----------------------------------------------------------------- 6. Intel® Threading Building Blocks (Intel® TBB) Copyright Intel Corporation Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------------------- 7. Visual Studio Autogenerated Code Copyright Microsoft Corporation Terms for Microsoft “Distributable Code” provided as part of Microsoft’s Visual Studio Enterprise and Professional software. 1. License. This software package from Intel (the “Software Package”) contains code from Microsoft (the “Distributable Code”). You are provided a non-transferable, non-exclusive, non-sublicensable, limited right and license only to use the Distributable Code as part of this Software Package. You are not allowed to copy, modify, remove the Distributable Code from the Software Package or redistribute the Distributable Code. 2. Restrictions. The Distributable Code is licensed, not sold. You are only provided the above rights to use the Distributable Code. Intel and Microsoft reserve all other rights. Unless applicable law gives you more rights, you may use the Distributable Code only as expressly permitted in these terms. In using the Distributable Code, you must comply with any technical limitations in the Distributable Code that only allow you to use it in certain ways. You may not: • work around any technical limitations in the Distributable Code; • reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the Distributable Code, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the Distributable Code; • remove, minimize, block or modify any notices of Intel, Microsoft or its suppliers in the Distributable Code; • use the Distributable Code in any way that is against the law; or • share, publish, rent or lease the software, or provide the Distributable Code as a stand-alone offering for others to use. 3. NO WARRANTY. THE DISTRIBUTABLE CODE IS PROVIDED “AS IS” WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. 4. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM INTEL, MICROSOFT OR THEIR SUPPLIERS ONLY DIRECT DAMAGES UP TO $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. This limitation applies to (a) anything related to the Distributable Code; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. It also applies even if Intel or Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages. 5. Export Restrictions. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting. ----------------------------------------------------------------- 8. fpp - Fortran PreProcessor Copyright (C) 2002-2018 Intel Corporation. All rights reserved. Portions Copyright (C) 1995 by Sun Microsystems, Inc. All rights reserved. Developed at SunSoft, a Sun Microsystems, Inc. business. Permission to use, copy, modify, and distribute this software is freely granted, provided that this notice is preserved. ----------------------------------------------------------------- 9. Intel Decimal Floating-Point Math Library Copyright (c) 2018, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, his list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------- The following third party programs have their own third party program files. These additional third party program files are as follows: Third-party-program.txt file for Intel(R) TBB is located here: /tbb/licensing/third-party-programs.txt ------------------------------------------------------------- Other names and brands may be claimed as the property of others. RenderKit-ospray-85af292/third-party-programs-oneDNN.txt000066400000000000000000000722011464752671100232540ustar00rootroot00000000000000oneAPI Deep Neural Network Library (oneDNN) Third Party Programs File This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in in the "THIRD-PARTY-PROGRAMS" file. Third party programs and their corresponding required notices and/or license terms are listed below. -------------------------------------------------------------------------------- 1. XByak (src/cpu/xbyak/) Copyright (c) 2007 MITSUNARI Shigeo All rights reserved. 3-Clause BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the copyright owner nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ソースコード形å¼ã‹ãƒã‚¤ãƒŠãƒªå½¢å¼ã‹ã€å¤‰æ›´ã™ã‚‹ã‹ã—ãªã„ã‹ã‚’å•ã‚ãšã€ä»¥ä¸‹ã®æ¡ä»¶ã‚’満㟠ã™å ´åˆã«é™ã‚Šã€å†é ’布ãŠã‚ˆã³ä½¿ç”¨ãŒè¨±å¯ã•れã¾ã™ã€‚ ソースコードをå†é ’布ã™ã‚‹å ´åˆã€ä¸Šè¨˜ã®è‘—ä½œæ¨©è¡¨ç¤ºã€æœ¬æ¡ä»¶ä¸€è¦§ã€ãŠã‚ˆã³ä¸‹è¨˜å…責æ¡é … ã‚’å«ã‚ã‚‹ã“ã¨ã€‚ ãƒã‚¤ãƒŠãƒªå½¢å¼ã§å†é ’布ã™ã‚‹å ´åˆã€é ’布物ã«ä»˜å±žã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆç­‰ã®è³‡æ–™ã«ã€ä¸Šè¨˜ã®è‘—作 æ¨©è¡¨ç¤ºã€æœ¬æ¡ä»¶ä¸€è¦§ã€ãŠã‚ˆã³ä¸‹è¨˜å…責æ¡é …ã‚’å«ã‚ã‚‹ã“ã¨ã€‚ 書é¢ã«ã‚ˆã‚‹ç‰¹åˆ¥ã®è¨±å¯ãªã—ã«ã€æœ¬ã‚½ãƒ•トウェアã‹ã‚‰æ´¾ç”Ÿã—ãŸè£½å“ã®å®£ä¼ã¾ãŸã¯è²©å£²ä¿ƒé€² ã«ã€è‘—作権者ã®åå‰ã¾ãŸã¯ã‚³ãƒ³ãƒˆãƒªãƒ“ューターã®åå‰ã‚’使用ã—ã¦ã¯ãªã‚‰ãªã„。 本ソフトウェアã¯ã€è‘—作権者ãŠã‚ˆã³ã‚³ãƒ³ãƒˆãƒªãƒ“ューターã«ã‚ˆã£ã¦ã€Œç¾çжã®ã¾ã¾ã€æä¾›ã• れã¦ãŠã‚Šã€æ˜Žç¤ºé»™ç¤ºã‚’å•ã‚ãšã€å•†æ¥­çš„ãªä½¿ç”¨å¯èƒ½æ€§ã€ãŠã‚ˆã³ç‰¹å®šã®ç›®çš„ã«å¯¾ã™ã‚‹é©åˆæ€§ ã«é–¢ã™ã‚‹æš—é»™ã®ä¿è¨¼ã‚‚å«ã‚ã€ã¾ãŸãれã«é™å®šã•れãªã„ã€ã„ã‹ãªã‚‹ä¿è¨¼ã‚‚ã‚りã¾ã›ã‚“。 著作権者もコントリビューターもã€äº‹ç”±ã®ã„ã‹ã‚“ã‚’å•ã‚ãšã€ æå®³ç™ºç”Ÿã®åŽŸå› ã„ã‹ã‚“ã‚’ å•ã‚ãšã€ã‹ã¤è²¬ä»»ã®æ ¹æ‹ ãŒå¥‘ç´„ã§ã‚ã‚‹ã‹åŽ³æ ¼è²¬ä»»ã§ã‚ã‚‹ã‹ï¼ˆéŽå¤±ãã®ä»–ã®ï¼‰ä¸æ³•行為㧠ã‚ã‚‹ã‹ã‚’å•ã‚ãšã€ä»®ã«ãã®ã‚ˆã†ãªæå®³ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ã‚’知らã•れã¦ã„ãŸã¨ã—ã¦ã‚‚〠本ソフトウェアã®ä½¿ç”¨ã«ã‚ˆã£ã¦ç™ºç”Ÿã—ãŸï¼ˆä»£æ›¿å“ã¾ãŸã¯ä»£ç”¨ã‚µãƒ¼ãƒ“スã®èª¿é”ã€ä½¿ç”¨ã® 喪失ã€ãƒ‡ãƒ¼ã‚¿ã®å–ªå¤±ã€åˆ©ç›Šã®å–ªå¤±ã€æ¥­å‹™ã®ä¸­æ–­ã‚‚å«ã‚ã€ã¾ãŸãれã«é™å®šã•れãªã„)直接 æå®³ã€é–“接æå®³ã€å¶ç™ºçš„ãªæå®³ã€ç‰¹åˆ¥æå®³ã€æ‡²ç½°çš„æå®³ã€ã¾ãŸã¯çµæžœæå®³ã«ã¤ã„ã¦ã€ 一切責任を負ã‚ãªã„ã‚‚ã®ã¨ã—ã¾ã™ã€‚ -------------------------------------------------------------------------------- 2. Googletest (tests/gtests/gtest/) Copyright 2005, Google Inc. Copyright 2006, Google Inc. Copyright 2007, Google Inc. Copyright 2008, Google Inc. Copyright 2015, Google Inc. All rights reserved. 3-Clause BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 3. Instrumentation and Tracing Technology API (src/common/ittnotify/) Copyright (c) 2011, Intel Corporation. All rights reserved. Copyright (c) 2005-2014 Intel Corporation. All rights reserved. 3-Clause BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 4. CMake (cmake/FindOpenCL.cmake, cmake/FindBLAS.cmake, cmake/FindACL.cmake) CMake - Cross Platform Makefile Generator Copyright 2000-2020 Kitware, Inc. and Contributors All rights reserved. 3-Clause BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Kitware, Inc. nor the names of Contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ The following individuals and institutions are among the Contributors: * Aaron C. Meadows * Adriaan de Groot * Aleksey Avdeev * Alexander Neundorf * Alexander Smorkalov * Alexey Sokolov * Alex Merry * Alex Turbov * Andreas Pakulat * Andreas Schneider * André Rigland Brodtkorb * Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf * Benjamin Eikel * Bjoern Ricks * Brad Hards * Christopher Harvey * Christoph Grüninger * Clement Creusot * Daniel Blezek * Daniel Pfeifer * Enrico Scholz * Eran Ifrah * Esben Mose Hansen, Ange Optimization ApS * Geoffrey Viola * Google Inc * Gregor Jasny * Helio Chissini de Castro * Ilya Lavrenov * Insight Software Consortium * Jan Woetzel * Julien Schueller * Kelly Thompson * Konstantin Podsvirov * Laurent Montel * Mario Bensi * Martin Gräßlin * Mathieu Malaterre * Matthaeus G. Chajdas * Matthias Kretz * Matthias Maennich * Michael Hirsch, Ph.D. * Michael Stürmer * Miguel A. Figueroa-Villanueva * Mike Jackson * Mike McQuaid * Nicolas Bock * Nicolas Despres * Nikita Krupen'ko * NVIDIA Corporation * OpenGamma Ltd. * Patrick Stotko * Per Øyvind Karlsen * Peter Collingbourne * Petr Gotthard * Philip Lowman * Philippe Proulx * Raffi Enficiaud, Max Planck Society * Raumfeld * Roger Leigh * Rolf Eike Beer * Roman Donchenko * Roman Kharitonov * Ruslan Baratov * Sebastian Holtermann * Stephen Kelly * Sylvain Joubert * The Qt Company Ltd. * Thomas Sondergaard * Tobias Hunger * Todd Gamblin * Tristan Carel * University of Dundee * Vadim Zhukov * Will Dicharry See version control history for details of individual contributions. The above copyright and license notice applies to distributions of CMake in source and binary form. Third-party software packages supplied with CMake under compatible licenses provide their own copyright notices documented in corresponding subdirectories or source files. ------------------------------------------------------------------------------ CMake was initially developed by Kitware with the following sponsorship: * National Library of Medicine at the National Institutes of Health as part of the Insight Segmentation and Registration Toolkit (ITK). * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel Visualization Initiative. * National Alliance for Medical Image Computing (NAMIC) is funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. * Kitware, Inc. -------------------------------------------------------------------------------- 5. Xbyak_aarch64 (src/cpu/aarch64/xbyak_aarch64/) Copyright 2019-2020 FUJITSU LIMITED Apache License, Version 2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- 6. Boost C++ Libraries (src/common/primitive_hashing.hpp) Copyright 2005-2014 Daniel James. Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 7. Intel(R) Graphics Compute Runtime for oneAPI Level Zero and OpenCL(TM) Driver (src/gpu/jit/ngen/npack/{elf_structs,hash}.hpp) Copyright (c) 2018 Intel Corporation Intel(R) Graphics Compiler (src/gpu/jit/ngen/npack/neo_structs.hpp) Copyright (c) 2019 Intel Corporation oneAPI Level Zero (src/sycl/level_zero) Copyright (C) 2019-2021 Intel Corporation Doxyrest toolkit (doc/doxyrest/*) Copyright (c) 2016, Tibbo Technology Inc Copyright (c) 2016, Vladimir Gladkov Copyright (c) 2016, Doxyrest maintainers MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8. Sphinx (doc/sphinx/conf/py) Copyright (c) 2007-2021 by the Sphinx team (see AUTHORS file). All rights reserved. 2-Clause BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 9. Intel(R) Metrics Discovery Application Programming Interface (src/gpu/ocl/mdapi/metrics_discovery_api.h) MIT License Copyright (c) 2019, Intel Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. RenderKit-ospray-85af292/third-party-programs-oneTBB.txt000066400000000000000000001336031464752671100232500ustar00rootroot00000000000000oneAPI Threading Building Blocks (oneTBB) Third Party Programs File This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the "third-party-programs.txt" or other similarlynamed text file. The third party programs and their corresponding required notices and/or license terms are listed below. _______________________________________________________________________________________________________ 1. Intel(R) Instrumentation and Tracing Technology (ITT) Copyright (c) 2022 Intel Corporation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _______________________________________________________________________________________________________ 2. ActiveState Thread pool with same API as (multi) processing.Pool (Python recipe): Copyright (c) 2008,2016 david decotigny (this file) Copyright (c) 2006-2008, R Oudkerk (multiprocessing.Pool) Portable Hardware Locality (hwloc) Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation. All rights reserved. Copyright (c) 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation. All rights reserved. Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart. All rights reserved. Copyright (c) 2004-2005 The Regents of the University of California. All rights reserved. Copyright (c) 2009 CNRS Copyright (c) 2009-2016 Inria. All rights reserved. Copyright (c) 2009-2015 Université Bordeaux Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. Copyright (c) 2009-2012 Oracle and/or its affiliates. All rights reserved. Copyright (c) 2010 IBM Copyright (c) 2010 Jirka Hladky Copyright (c) 2012 Aleksej Saushev, The NetBSD Foundation Copyright (c) 2012 Blue Brain Project, EPFL. All rights reserved. Copyright (c) 2013-2014 University of Wisconsin-La Crosse. All rights reserved. Copyright (c) 2015 Research Organization for Information Science and Technology (RIST). All rights reserved. Copyright (c) 2015-2016 Intel, Inc. All rights reserved. BSD 3-clause "New" or "Revised" License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _______________________________________________________________________________________________________ 3. gperftools: Copyright (c) 2011, Google Inc. Tachyon: Copyright (c) 1994-2008 John E. Stone. All rights reserved. BSD 3-Clause "New" or "Revised" License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _______________________________________________________________________________________________________ 4. Mateusz Kwiatkowski Workaround for bug 62258 in libstdc++ GPL 3.0 with GCC Runtime Library Exception 3.1 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (c) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . GCC RUNTIME LIBRARY EXCEPTION Version 3.1, 31 March 2009 Copyright (c) 2009 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception. When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception. 0. Definitions. A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library. "GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF. "GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC. "Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation. The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors. A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process. 1. Grant of Additional Permission. You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules. 2. No Weakening of GCC Copyleft. The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC. _______________________________________________________________________________________________________ 5. Doctest Copyright (c) 2016-2021 Viktor Kirilov The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. _______________________________________________________________________________________________________ *Other names and brands may be claimed as the property of others. RenderKit-ospray-85af292/third-party-programs.txt000066400000000000000000001640011464752671100221350ustar00rootroot00000000000000Intel(R) OSPRay Third Party Programs File This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the "third-party-programs.txt" or other similarly named text file. Third party programs and their corresponding required notices and/or license terms are listed below. -------------------------------------------------------------------------------- 1. Intel(R) Embree Copyright 2009 Intel Corporation Google Benchmark Copyright 2014 Google Inc. All rights reserved. Intel(R) Open Image Denoise Copyright 2009 Intel Corporation Intel(R) Open VKL Copyright 2019 Intel Corporation Intel(R) oneAPI Threading Building Blocks (oneTBB) Copyright 2005 Intel Corporation Intel(R) Implicit SPMD Program Compiler (ISPC) Copyright 2011 Intel Corporation Apache License Version 2.0 January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. -------------------------------------------------------------------------------- 2. Dear ImGui Copyright 2014-2020 Omar Cornut Twinklebear pico-bench Copyright 2015 Will Usher Gruenschloss Halton Copyright 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org) Imneme pcg-cpp Copyright 2014-2017 Melissa O'Neill and PCG Project contributors glm (OpenGL Mathematics) Copyright 2005 - G-Truc Creation SSE2NEON The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- 3. GLFW Copyright 2002-2006 Marcus Geelnard Copyright 2006-2019 Camilla Löwy zlib Copyright 1995-2017 Jean-loup Gailly and Mark Adler enkiTS Copyright (c) 2013 Doug Binks zlib License This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- 4. Google Test Copyright 2008, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 5. Skylight model Copyright 2012-2013, Lukas Hosek and Alexander Wilkie This source is published under the following 3-clause BSD license. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * None of the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- 6. Visual C++ Redistributables for Visual Studio 1. License. This software package from Intel (the Software Package) contains code from Microsoft (the Distributable Code). You are provided a non-transferable, non-exclusive, non-sublicensable, limited right and license only to use the Distributable Code as part of this Software Package. You are not allowed to copy, modify, remove the Distributable Code from the Software Package or redistribute the Distributable Code. 2. Restrictions. The Distributable Code is licensed, not sold. You are only provided the above rights to use the Distributable Code. Intel and Microsoft reserve all other rights. Unless applicable law gives you more rights, you may use the Distributable Code only as expressly permitted in these terms. In using the Distributable Code, you must comply with any technical limitations in the Distributable Code that only allow you to use it in certain ways. You may not: work around any technical limitations in the Distributable Code; reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the Distributable Code, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the Distributable Code; remove, minimize, block or modify any notices of Intel, Microsoft or its suppliers in the Distributable Code; use the Distributable Code in any way that is against the law; or share, publish, rent or lease the software, or provide the Distributable Code as a stand-alone offering for others to use. 3. NO WARRANTY. THE DISTRIBUTABLE CODE IS PROVIDED AS IS WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. 4. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM INTEL, MICROSOFT OR THEIR SUPPLIERS ONLY DIRECT DAMAGES UP TO $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. This limitation applies to (a) anything related to the Distributable Code; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. It also applies even if Intel or Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages. 5. Export Restrictions. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting. -------------------------------------------------------------------------------- 7. Google Snappy Copyright 2011, Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. === Some of the benchmark data in testdata/ is licensed differently: - fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and is licensed under the Creative Commons Attribution 3.0 license (CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/ for more information. - kppkn.gtb is taken from the Gaviota chess tablebase set, and is licensed under the MIT License. See https://sites.google.com/site/gaviotachessengine/Home/endgame-tablebases-1 for more information. - paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper "Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA Replication Timing in _Drosophila_" by Federico Comoglio and Renato Paro, which is licensed under the CC-BY license. See http://www.ploscompbiol.org/static/license for more ifnormation. - alice29.txt, asyoulik.txt, plrabn12.txt and lcet10.txt are from Project Gutenberg. The first three have expired copyrights and are in the public domain; the latter does not have expired copyright, but is still in the public domain according to the license information (http://www.gutenberg.org/ebooks/53). -------------------------------------------------------------------------------- 8. oneAPI DPC++ Compiler https://github.com/intel/llvm/ Apache License 2.0 with LLVM Exceptions Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ---- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. -------------------------------------------------------------------------------- 9. Intel(R) oneAPI DPC++/C++ Compiler Intel End User License Agreement for Developer Tools (Version October 2021) IMPORTANT NOTICE - PLEASE READ AND AGREE BEFORE DOWNLOADING, INSTALLING, COPYING OR USING This Agreement is between you, or the company or other legal entity that you represent and warrant you have the legal authority to bind, (each, "You" or "Your") and Intel Corporation and its subsidiaries (collectively, "Intel") regarding Your use of the Materials. By downloading, installing, copying or using the Materials, You agree to be bound by the terms of this Agreement. If You do not agree to the terms of this Agreement, or do not have legal authority or required age to agree to them, do not download, install, copy or use the Materials. LICENSE DEFINITIONS. A. "Cloud Provider" means a third party service provider offering a cloud-based platform, infrastructure, application or storage services, such as Microsoft Azure or Amazon Web Services, which You may only utilize to host the Materials subject to the restrictions set forth in Section 2.3 B. B. "Derivative Work" means a derivative work, as defined in 17 U.S.C. § 101, of the Source Code. C. "Executable Code" means computer programming code in binary form suitable for machine execution by a processor without the intervening steps of interpretation or compilation. D. "Materials" mean the software, documentation, the software product serial number, and other collateral, including any updates, made available to You by Intel under this Agreement. Materials include Redistributables, Executable Code, Source Code, Sample Source Code, and Pre-Release Materials, but do not include Third Party Software. E. "Pre-Release Materials" mean the Materials, or portions of the Materials, that are identified (in the product release notes, on Intel's download website for the Materials or elsewhere) or labeled as pre-release, prototype, alpha or beta code and, as such, are deemed to be pre-release code (i) which may not be fully functional or tested and may contain bugs or errors; (ii) which Intel may substantially modify in its development of a production version; or (iii) for which Intel makes no assurances that it will ever develop or make a production version generally available. Pre-Release Materials are subject to the terms of Section 3.2. F. "Reciprocal Open Source Software" means any software that is subject to a license which requires that (i) it must be distributed in source code form; (ii) it must be licensed under the same open source license terms; and (iii) its derivative works must be licensed under the same open source license terms. Examples of this type of license are the GNU General Public License or the Mozilla Public License. G. "Redistributables" mean the files (if any) listed in the "redist.txt," "redist-rt.txt" or similarlynamed text files that may be included in the Materials. Redistributables include Sample Source Code. H. "Sample Source Code" means those portions of the Materials that are Source Code and are identified as sample code. Sample Source Code may not have been tested or validated by Intel and is provided purely as a programming example. I. "Source Code" means the software portion of the Materials provided in human readable format. J. "Third Party Software" mean the files (if any) listed in the "third-party-software.txt" or other similarly-named text file that may be included in the Materials for the applicable software. Third Party Software is subject to the terms of Section 2.2. K. "Your Product" means one or more applications, products or projects developed by or for You using the Materials. 2. LICENSE GRANTS. 2.1 License to the Materials. Subject to the terms and conditions of this Agreement, Intel grants You a non-exclusive, worldwide, non-assignable, non-sublicensable, limited right and license under its copyrights, to: A. reproduce internally a reasonable number of copies of the Materials for Your personal or business use; B. use the Materials solely for Your personal or business use to develop Your Product, in accordance with the documentation included as part of the Materials; C. modify or create Derivative Works only of the Redistributables, or any portions, that are provided to You in Source Code; D. distribute (directly and through Your distributors, resellers, and other channel partners, if applicable), the Redistributables, including any modifications to or Derivative Works of the Redistributables or any portions made pursuant to Section 2.1.C subject to the following conditions: (1) Any distribution of the Redistributables must only be as part of Your Product which must add significant primary functionality different than that of the Redistributables themselves; (2) You must only distribute the Redistributables originally provided to You by Intel only in Executable Code subject to a license agreement that prohibits reverse engineering, decompiling or disassembling the Redistributables; (3) This distribution right includes a limited right to sublicense only the Intel copyrights in the Redistributables and only to the extent necessary to perform, display, and distribute the Redistributables (including Your modifications and Derivative Works of the Redistributables provided in Source Code) solely as incorporated in Your Product; and (4) You: (i) will be solely responsible to Your customers for any update, support obligation or other obligation or liability which may arise from the distribution of Your Product, (ii) will not make any statement that Your Product is "certified" or that its performance is guaranteed by Intel or its suppliers, (iii) will not use Intel's or its suppliers' names or trademarks to market Your Product, (iv) will comply with any additional restrictions which are included in the text files with the Redistributables and in Section 3 below, (v) will indemnify, hold harmless, and defend Intel and its suppliers from and against any claims or lawsuits, costs, damages, and expenses, including attorney's fees, that arise or result from (a) Your modifications or Derivative Works of the Materials or (b) Your distribution of Your Product. 2.2 Third Party Software. Third Party Software, even if included with the distribution of the Materials, may be governed by separate license terms, including without limitation, third party license terms, open source software notices and terms, and/or other Intel software license terms. These separate license terms solely govern Your use of the Third Party Software. 2.3 Third Party Use. A. If You are an entity, Your contractors may use the Materials under the license specified in Section 2, provided: (i) their use of the Materials is solely on behalf of and in support of Your business, (ii) they agree to the terms and conditions of this Agreement, and (iii) You are solely responsible for their use, misuse or disclosure of the Materials. B. You may utilize a Cloud Provider to host the Materials for You, provided: (i) the Cloud Provider may only host the Materials for Your exclusive use and may not use the Materials for any other purpose whatsoever, including the restriction set forth in Section 3.1(xi); (ii) the Cloud Provider's use of the Materials must be solely on behalf of and in support of Your Product, and (iii) You will indemnify, hold harmless, and defend Intel and its suppliers from and against any claims or lawsuits, costs, damages, and expenses, including attorney's fees, that arise or result from Your Cloud Provider's use, misuse or disclosure of the Materials. 3. LICENSE CONDITIONS. 3.1 Restrictions. Except as expressly provided in this Agreement, You may NOT: (i) use, reproduce, disclose, distribute, or publicly display the Materials; (ii) share, publish, rent or lease the Materials to any third party; (iii) assign this Agreement or transfer the Materials; (iv) modify, adapt, or translate the Materials in whole or in part; (v) reverse engineer, decompile, or disassemble the Materials, or otherwise attempt to derive the source code for the software; (vi) work around any technical limitations in the Materials; (vii) distribute, sublicense or transfer any Source Code, modifications or Derivative Works of any Source Code to any third party; (viii) remove, minimize, block or modify any notices of Intel or its suppliers in the Materials; (ix) include the Redistributables in malicious, deceptive, or unlawful programs or products or use the Materials in any way that is against the law; (x) modify, create a Derivative Work, link, or distribute the Materials so that any part of it becomes Reciprocal Open Source Software; (xi) use the Materials directly or indirectly for SaaS services or service bureau purposes (i.e., a service that allows use of or access to the Materials by a third party as part of that service, such as the salesforce.com service business model). 3.2 Pre-Release Materials. If You receive Pre-Release Materials, You may reproduce a reasonable number of copies and use the Pre-Release Materials for evaluation and testing purposes only. You may not (i) modify or incorporate the Pre-Release Materials into Your Product; (ii) continue to use the Pre-Release Materials once a commercial version is released; or (iii) disclose to any third party any benchmarks, performance results, or other information relating to the Pre-Release Materials. Intel may waive these restrictions in writing at its sole discretion; however, if You decide to use the Pre-Release Materials in Your Product (even with Intel's waiver), You acknowledge and agree that You are fully responsible for any and all issues that result from such use. 3.3 Safety-Critical, and Life-Saving Applications; Indemnity. The Materials may provide information relevant to safety-critical applications ("Safety-Critical Applications") to allow compliance with functional safety standards or requirements. You acknowledge and agree that safety is Your responsibility. To the extent You use the Materials to create, or as part of, products used in Safety-Critical Applications, it is Your responsibility to design, manage, and ensure that there are system-level safeguards to anticipate, monitor, and control system failures, and You agree that You are solely responsible for all applicable regulatory standards and safety-related requirements concerning Your use of the Materials in Safety Critical Applications. Should You use the Materials for Safety-Critical Applications or in any type of a system or application in which the failure of the Materials could create a situation where personal injury or death may occur (e.g., medical systems, life-sustaining or life-saving systems) ("Life-Saving Applications"), You agree to indemnify, defend, and hold Intel and its representatives harmless against any claims or lawsuits, costs, damages, and expenses, including reasonable attorney fees, arising in any way out of Your use of the Materials in Safety-Critical Applications or Life-Saving Applications and claims of product liability, personal injury or death associated with those applications; even if such claims allege that Intel was negligent or strictly liable regarding the design or manufacture of the Materials or its failure to warn regarding the Materials. 3.4 Media Format Codecs and Digital Rights Management. You acknowledge and agree that Your use of the Materials or distribution of the Redistributables with Your Product as permitted by this Agreement may require You to procure license(s) from third parties that may hold intellectual property rights applicable to any media decoding, encoding or transcoding technology (e.g., the use of an audio or video codec) and/or digital rights management capabilities of the Materials, if any. Should any such additional licenses be required, You are solely responsible for obtaining any such licenses and agree to obtain any such licenses at Your own expense. 4. DATA COLLECTION AND PRIVACY. 4.1 Data Collection. The Materials may generate and collect anonymous data and/or provisioning data about the Materials and/or the development environment and transmit the data to Intel as a one-time event during installation. Optional data may also be collected by the Materials, however, You will be provided notice of the request to collect optional data and no optional data will be collected without Your consent. All data collection by Intel is performed pursuant to relevant privacy laws, including notice and consent requirements. 4.2 Intel's Privacy Notice. Intel is committed to respecting Your privacy. To learn more about Intel's privacy practices, please visit http://www.intel.com/privacy. 5. OWNERSHIP. Title to the Materials and all copies remain with Intel or its suppliers. The Materials are protected by intellectual property rights, including without limitation, United States copyright laws and international treaty provisions. You will not remove any copyright or other proprietary notices from the Materials. Except as expressly provided herein, no license or right is granted to You directly or by implication, inducement, estoppel or otherwise; specifically, Intel does not grant any express or implied right to You under Intel patents, copyrights, trademarks, or trade secrets. 6. NO WARRANTY AND NO SUPPORT. 6.1 No Warranty. Disclaimer. Intel disclaims all warranties of any kind and the terms and remedies provided in this Agreement are instead of any other warranty or condition, express, implied or statutory, including those regarding merchantability, fitness for any particular purpose, non-infringement or any warranty arising out of any course of dealing, usage of trade, proposal, specification or sample. Intel does not assume (and does not authorize any person to assume on its behalf) any liability. 6.2 No Support; Priority Support. Intel may make changes to the Materials, or to items referenced therein, at any time without notice, but is not obligated to support, update or provide training for the Materials under the terms of this Agreement. Intel offers free community and paid priority support options. More information on these support options can be found at: https://software.intel.com/content/www/us/en/develop/support/priority-support.html. 7. LIMITATION OF LIABILITY. 7.1 Intel will not be liable for any of the following losses or damages (whether such losses or damages were foreseen, foreseeable, known or otherwise): (i) loss of revenue; (ii) loss of actual or anticipated profits; (iii) loss of the use of money; (iv) loss of anticipated savings; (v) loss of business; (vi) loss of opportunity; (vii) loss of goodwill; (viii) loss of use of the Materials; (ix) loss of reputation; (x) loss of, damage to, or corruption of data; or (xi) any indirect, incidental, special or consequential loss of damage however caused (including loss or damage of the type specified in this Section 7). 7.2 Intel's total cumulative liability to You, including for direct damages for claims relating to this Agreement, and whether for breach of contract, negligence, or for any other reason, will not exceed $100. 7.3 You acknowledge that the limitations of liability provided in this Section 7 are an essential part of this Agreement. You agree that the limitations of liability provided in this Agreement with respect to Intel will be conveyed to and made binding upon any customer of Yours that acquires the Redistributables. 8. USER SUBMISSIONS. Should you provide Intel with comments, modifications, corrections, enhancements or other input ("Feedback") related to the Materials, Intel will be free to use, disclose, reproduce, license or otherwise distribute or exploit the Feedback in its sole discretion without any obligations or restrictions of any kind, including without limitation, intellectual property rights or licensing obligations. If You wish to provide Intel with information that You intend to be treated as confidential information, Intel requires that such confidential information be provided pursuant to a non-disclosure agreement ("NDA"); please contact Your Intel representative to ensure the proper NDA is in place. 9. NON-DISCLOSURE. Information provided by Intel to You may include information marked as confidential. You must treat such information as confidential under the terms of the applicable NDA between Intel and You. If You have not entered into an NDA with Intel, You must not disclose, distribute or make use of any information marked as confidential, except as expressly authorized in writing by Intel. Intel retains all rights in and to its confidential information specifications, designs, engineering details, discoveries, inventions, patents, copyrights, trademarks, trade secrets, and other proprietary rights relating to the Materials. Any breach by You of the confidentiality obligations provided for in this Section 9 will cause irreparable injury to Intel for which money damages may be inadequate to compensate Intel for losses arising from such a breach. Intel may obtain equitable relief, including injunctive relief, if You breach or threaten to breach Your confidentiality obligations. 10. TERM AND TERMINATION. This Agreement becomes effective on the date You accept this Agreement and will continue until terminated as provided for in this Agreement. The term for any Pre-Release Materials terminates upon release of a commercial version. This Agreement will terminate if You are in breach of any of its terms and conditions. Upon termination, You will promptly destroy the Materials and all copies. In the event of termination of this Agreement, Your license to any Redistributables distributed by You in accordance with the terms and conditions of this Agreement, prior to the effective date of such termination, will survive any such termination of this Agreement. Sections 1, 2.1.D(4)(v), 2.2, 2.3.A(iii), 2.3.B(iii), 3.3, 5, 6, 7, 8, 9, 10 (with respect to these survival provisions in the last sentence), and 12 will survive expiration or termination of this Agreement. 11. U.S. GOVERNMENT RESTRICTED RIGHTS. The technical data and computer software covered by this license is a "Commercial Item," as such term is defined by the FAR 2.101 (48 C.F.R. 2.101) and is "commercial computer software" and "commercial computer software documentation" as specified under FAR 12.212 (48 C.F.R. 12.212) or DFARS 227.7202 (48 C.F.R. 227.7202), as applicable. This commercial computer software and related documentation is provided to end users for use by and on behalf of the U.S. Government with only those rights as are granted to all other end users pursuant to the terms and conditions of this Agreement. 12. GENERAL PROVISIONS. 12.1 ENTIRE AGREEMENT. This Agreement contains the complete and exclusive agreement and understanding between the parties concerning the subject matter of this Agreement, and supersedes all prior and contemporaneous proposals, agreements, understanding, negotiations, representations, warranties, conditions, and communications, oral or written, between the parties relating to the same subject matter. Each party acknowledges and agrees that in entering into this Agreement it has not relied on, and will not be entitled to rely on, any oral or written representations, warranties, conditions, understanding, or communications between the parties that are not expressly set forth in this Agreement. The express provisions of this Agreement control over any course of performance, course of dealing, or usage of the trade inconsistent with any of the provisions of this Agreement. The provisions of this Agreement will prevail notwithstanding any different, conflicting, or additional provisions that may appear on any purchase order, acknowledgement, invoice, or other writing issued by either party in connection with this Agreement. No modification or amendment to this Agreement will be effective unless in writing and signed by authorized representatives of each party, and must specifically identify this Agreement by its title and version (e.g., "Intel End User License Agreement for Developer Tools (Version October 2021)"); except that Intel may make changes to this Agreement as it distributes new versions of the Materials. When changes are made, Intel will make a new version of the Agreement available on its website. If You received a copy of this Agreement translated into another language, the English language version of this Agreement will prevail in the event of any conflict between versions. 12.2 EXPORT. You acknowledge that the Materials and all related technical information are subject to export controls and you agree to comply with all laws and regulations of the United States and other applicable governments governing export, re-export, import, transfer, distribution, and use of the Materials. In particular, but without limitation, the Materials may not be exported or re-exported (i) into any U.S. embargoed countries or (ii) to any person or entity listed on a denial order published by the U.S. government or any other applicable governments. By using the Materials, You represent and warrant that You are not located in any such country or on any such list. You also agree that You will not use the Materials for, or sell or transfer them to a third party who is known or suspected to be involved in, any purposes prohibited by the U.S. government or other applicable governments, including, without limitation, the development, design, manufacture, or production of nuclear, missile, chemical or biological weapons. 12.3 GOVERNING LAW, JURISDICTION, AND VENUE. All disputes arising out of or related to this Agreement, whether based on contract, tort, or any other legal or equitable theory, will in all respects be governed by, and construed and interpreted under, the laws of the United States of America and the State of Delaware, without reference to conflict of laws principles. The parties agree that the United Nations Convention on Contracts for the International Sale of Goods (1980) is specifically excluded from and will not apply to this Agreement. All disputes arising out of or related to this Agreement, whether based on contract, tort, or any other legal or equitable theory, will be subject to the exclusive jurisdiction of the courts of the State of Delaware or of the Federal courts sitting in that State. Each party submits to the personal jurisdiction of those courts and waives all objections to that jurisdiction and venue for those disputes. 12.4 SEVERABILITY. The parties intend that if a court holds that any provision or part of this Agreement is invalid or unenforceable under applicable law, the court will modify the provision to the minimum extent necessary to make it valid and enforceable, or if it cannot be made valid and enforceable, the parties intend that the court will sever and delete the provision or part from this Agreement. Any change to or deletion of a provision or part of this Agreement under this Section will not affect the validity or enforceability of the remainder of this Agreement, which will continue in full force and effect. -------------------------------------------------------------------------------- The following third party programs have their own third party programs. These additional third party program files are as follows: 1. Embree: ./third-party-programs-Embree.txt 2. Open Image Denoise: ./third-party-programs-OIDN.txt 3. Open VKL: ./third-party-programs-OpenVKL.txt 4. oneAPI Threading Building Blocks: ./third-party-programs-oneTBB.txt 5. Implicit SPMD Program Compiler: ./third-party-programs-ISPC.txt 6. oneAPI DPC++ Compiler: ./third-party-programs-DPCPP.txt 7. Intel(R) oneAPI DPC++/C++ Compiler: ./third-party-programs-oneAPI-DPCPP.txt -------------------------------------------------------------------------------- Other names and brands may be claimed as the property of others.