diff --git a/RenderingToolkit/GettingStarted/02_embree_gsg/CMakeLists.txt b/RenderingToolkit/GettingStarted/02_embree_gsg/CMakeLists.txt new file mode 100644 index 0000000000..3a00202fa6 --- /dev/null +++ b/RenderingToolkit/GettingStarted/02_embree_gsg/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.16) +project(EMBREE_GSG LANGUAGES CXX) + +set(ONEAPI_ROOT "") +if(DEFINED ENV{ONEAPI_ROOT}) + set(ONEAPI_ROOT "$ENV{ONEAPI_ROOT}") + message(STATUS "ONEAPI_ROOT FROM ENVIRONMENT: ${ONEAPI_ROOT}") +else() + if(WIN32) + set(ONEAPI_ROOT "C:/Program Files (x86)/Intel/oneAPI") + else() + set(ONEAPI_ROOT /opt/intel/oneapi) + endif() + message(STATUS "ONEAPI_ROOT DEFAULT: ${ONEAPI_ROOT}") +endif(DEFINED ENV{ONEAPI_ROOT}) + +find_package(embree 3.0 REQUIRED PATHS ${ONEAPI_ROOT}) + +if(MSVC) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif(MSVC) + +include_directories(${EMBREE_INCLUDE_DIR} ${RKCOMMON_INCLUDE_DIRS}) +link_directories(${EMBREE_ROOT}/lib ${ONEAPI_ROOT}/rkcommon/latest/lib) + +add_executable(minimal src/minimal.cpp) +target_link_libraries(minimal PRIVATE embree rkcommon) + +install(TARGETS minimal + DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/RenderingToolkit/GettingStarted/02_embree_gsg/LICENSE.txt b/RenderingToolkit/GettingStarted/02_embree_gsg/LICENSE.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/RenderingToolkit/GettingStarted/02_embree_gsg/LICENSE.txt @@ -0,0 +1,202 @@ + + 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. diff --git a/RenderingToolkit/GettingStarted/02_embree_gsg/README.md b/RenderingToolkit/GettingStarted/02_embree_gsg/README.md new file mode 100644 index 0000000000..c443d6c4e3 --- /dev/null +++ b/RenderingToolkit/GettingStarted/02_embree_gsg/README.md @@ -0,0 +1,86 @@ +# Getting Started Sample for Intel oneAPI Rendering Toolkit: Intel Embree + +Embree is a collection of high-performance ray tracing kernels. Improve performance of photo-realistic rendering applications by using performance optimized ray-tracing kernels. + +| Minimum Requirements | Description +|:--- |:--- +| OS | Linux* Ubuntu* 18.04, CentOS 8 (or compatible); Windows 10; MacOS 10.15+ +| Hardware | Intel 64 Penryn or newer with SSE4.1 extensions; ARM64 with NEON extensions +| Compiler Toolchain | Windows* OS: MSVS 2019 with Windows* SDK and CMake*; Other platforms: C++11 compiler, a C99 compiler (ex: gcc/c++/clang), and CMake* +| Libraries | Install Intel oneAPI Rendering Toolkit including Embree + +| Optimized Requirements | Description +| :--- | :--- +| Hardware | Intel 64 Skylake or newer with AVX512 extentions, ARM64 with NEON extensions + +| Objective | Description +|:--- |:--- +| What you will learn | How to build and run a basic sample program using the Embree API from the Render Kit. +| Time to complete | 5 minutes + +## Purpose + +This sample program, `minimal`, performs two ray to triangle intersect tests with the Embree API. One test is successful, while the other test is a miss. Output is written to the console (stdout). + +## Key Implementation Details + +This source code is constructed to build with a C++ or a C compiler. + +## License + +This code sample is licensed under the Apache 2.0 license. See +[LICENSE.txt](LICENSE.txt) for details. + +Third party program Licenses can be found here: [third-party-programs.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/third-party-programs.txt) + +## Build and Run + +### Windows OS: + +Run a new **x64 Native Tools Command Prompt for MSVS 2019** + +``` +call \setvars.bat +cd \RenderingToolkit\02_embree_gsg +mkdir build +cd build +cmake .. +cmake --build . --config Release +cd Release +minimal.exe +``` + +Review the terminal output (stdout) + + +### Linux OS: + +Start a new Terminal session +``` +source /setvars.sh +cd /RenderingToolkit/02_embree_gsg +mkdir build +cd build +cmake .. +cmake --build . +./minimal +``` + +Review the terminal output (stdout) + + +### MacOS: + +Start a new Terminal session + +``` +source /setvars.sh +cd /RenderingToolkit/02_embree_gsg +mkdir build +cd build +cmake .. +cmake --build . +./minimal +``` + +Review the terminal output (stdout) diff --git a/RenderingToolkit/GettingStarted/02_embree_gsg/sample.json b/RenderingToolkit/GettingStarted/02_embree_gsg/sample.json new file mode 100644 index 0000000000..a34ddadf95 --- /dev/null +++ b/RenderingToolkit/GettingStarted/02_embree_gsg/sample.json @@ -0,0 +1,54 @@ +{ + "guid": "87FA013D-0B19-45AE-BCD5-43412BE0A99F", + "name": "Intel Embree Getting Started", + "categories": ["Toolkit/oneAPI Libraries/Embree"], + "description": "This introductory hello rendering toolkit sample illustrates how to cast a ray into a scene with Intel Embree", + "builder": ["cli"], + "languages": [{"cpp":{}}], + "dependencies": ["tbb","rkcommon"], + "os":["linux", "windows", "darwin"], + "targetDevice": ["CPU"], + "ciTests": { + "linux": [ + { + "id": "Intel_Embree_minimal_lin", + "steps": [ + "mkdir build", + "cd build", + "cmake ..", + "cmake --build . ", + "./minimal" + ] + } + ], + "windows":[ + { + "env": ["call \"C:\\Program Files (x86)\\Intel\\oneAPI\\setvars.bat\""], + "id": "Intel_Embree_minimal_win", + "steps":[ + "mkdir build", + "cd build", + "cmake -G\"Visual Studio 16 2019\" -A x64 -DCMAKE_PREFIX_PATH=\"C:/Program Files (x86)/Intel/oneAPI\" ..", + "cmake --build . --config Release", + "cd Release", + ".\\minimal.exe" + ] + + } + ], + "darwin": [ + { + "id": "Intel_Embree_minimal_mac", + "steps": [ + "mkdir build", + "cd build", + "cmake ..", + "cmake --build . ", + "export DYLD_LIBRARY_PATH=${LIBRARY_PATH} && ./minimal" + ] + } + ] + + + } +} diff --git a/RenderingToolkit/GettingStarted/02_embree_gsg/src/minimal.cpp b/RenderingToolkit/GettingStarted/02_embree_gsg/src/minimal.cpp new file mode 100644 index 0000000000..8982b93bd1 --- /dev/null +++ b/RenderingToolkit/GettingStarted/02_embree_gsg/src/minimal.cpp @@ -0,0 +1,242 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +#include + +#if defined(_WIN32) +#include +#include +#endif + +/* + * A minimal tutorial. + * + * It demonstrates how to intersect a ray with a single triangle. It is + * meant to get you started as quickly as possible, and does not output + * an image. + * + * For more complex examples, see the other tutorials. + * + * Compile this file using + * + * gcc -std=c99 \ + * -I///include \ + * -o minimal \ + * minimal.c \ + * -L///lib \ + * -lembree3 + * + * You should be able to compile this using a C or C++ compiler. + */ + +/* + * This is only required to make the tutorial compile even when + * a custom namespace is set. + */ +#if defined(RTC_NAMESPACE_USE) +RTC_NAMESPACE_USE +#endif + +/* + * We will register this error handler with the device in initializeDevice(), + * so that we are automatically informed on errors. + * This is extremely helpful for finding bugs in your code, prevents you + * from having to add explicit error checking to each Embree API call. + */ +void errorFunction(void* userPtr, enum RTCError error, const char* str) { + printf("error %d: %s\n", error, str); +} + +/* + * Embree has a notion of devices, which are entities that can run + * raytracing kernels. + * We initialize our device here, and then register the error handler so that + * we don't miss any errors. + * + * rtcNewDevice() takes a configuration string as an argument. See the API docs + * for more information. + * + * Note that RTCDevice is reference-counted. + */ +RTCDevice initializeDevice() { + RTCDevice device = rtcNewDevice(NULL); + + if (!device) + printf("error %d: cannot create device\n", rtcGetDeviceError(NULL)); + + rtcSetDeviceErrorFunction(device, errorFunction, NULL); + return device; +} + +/* + * Create a scene, which is a collection of geometry objects. Scenes are + * what the intersect / occluded functions work on. You can think of a + * scene as an acceleration structure, e.g. a bounding-volume hierarchy. + * + * Scenes, like devices, are reference-counted. + */ +RTCScene initializeScene(RTCDevice device) { + RTCScene scene = rtcNewScene(device); + + /* + * Create a triangle mesh geometry, and initialize a single triangle. + * You can look up geometry types in the API documentation to + * find out which type expects which buffers. + * + * We create buffers directly on the device, but you can also use + * shared buffers. For shared buffers, special care must be taken + * to ensure proper alignment and padding. This is described in + * more detail in the API documentation. + */ + RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE); + float* vertices = (float*)rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, 3 * sizeof(float), 3); + + unsigned* indices = (unsigned*)rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 3 * sizeof(unsigned), + 1); + + if (vertices && indices) { + vertices[0] = 0.f; + vertices[1] = 0.f; + vertices[2] = 0.f; + vertices[3] = 1.f; + vertices[4] = 0.f; + vertices[5] = 0.f; + vertices[6] = 0.f; + vertices[7] = 1.f; + vertices[8] = 0.f; + + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + } + + /* + * You must commit geometry objects when you are done setting them up, + * or you will not get any intersections. + */ + rtcCommitGeometry(geom); + + /* + * In rtcAttachGeometry(...), the scene takes ownership of the geom + * by increasing its reference count. This means that we don't have + * to hold on to the geom handle, and may release it. The geom object + * will be released automatically when the scene is destroyed. + * + * rtcAttachGeometry() returns a geometry ID. We could use this to + * identify intersected objects later on. + */ + rtcAttachGeometry(scene, geom); + rtcReleaseGeometry(geom); + + /* + * Like geometry objects, scenes must be committed. This lets + * Embree know that it may start building an acceleration structure. + */ + rtcCommitScene(scene); + + return scene; +} + +/* + * Cast a single ray with origin (ox, oy, oz) and direction + * (dx, dy, dz). + */ +void castRay(RTCScene scene, float ox, float oy, float oz, float dx, float dy, + float dz) { + /* + * The intersect context can be used to set intersection + * filters or flags, and it also contains the instance ID stack + * used in multi-level instancing. + */ + struct RTCIntersectContext context; + rtcInitIntersectContext(&context); + + /* + * The ray hit structure holds both the ray and the hit. + * The user must initialize it properly -- see API documentation + * for rtcIntersect1() for details. + */ + struct RTCRayHit rayhit; + rayhit.ray.org_x = ox; + rayhit.ray.org_y = oy; + rayhit.ray.org_z = oz; + rayhit.ray.dir_x = dx; + rayhit.ray.dir_y = dy; + rayhit.ray.dir_z = dz; + rayhit.ray.tnear = 0; + rayhit.ray.tfar = std::numeric_limits::infinity(); + rayhit.ray.mask = -1; + rayhit.ray.flags = 0; + rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID; + rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; + + /* + * There are multiple variants of rtcIntersect. This one + * intersects a single ray with the scene. + */ + rtcIntersect1(scene, &context, &rayhit); + + printf("%f, %f, %f: ", ox, oy, oz); + if (rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID) { + /* Note how geomID and primID identify the geometry we just hit. + * We could use them here to interpolate geometry information, + * compute shading, etc. + * Since there is only a single triangle in this scene, we will + * get geomID=0 / primID=0 for all hits. + * There is also instID, used for instancing. See + * the instancing tutorials for more information */ + printf("Found intersection on geometry %d, primitive %d at tfar=%f\n", + rayhit.hit.geomID, rayhit.hit.primID, rayhit.ray.tfar); + } else + printf("Did not find any intersection.\n"); +} + +void waitForKeyPressedUnderWindows() { +#if defined(_WIN32) + HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (!GetConsoleScreenBufferInfo(hStdOutput, &csbi)) { + printf("GetConsoleScreenBufferInfo failed: %d\n", GetLastError()); + return; + } + + /* do not pause when running on a shell */ + if (csbi.dwCursorPosition.X != 0 || csbi.dwCursorPosition.Y != 0) return; + + /* only pause if running in separate console window. */ + printf("\n\tPress any key to exit...\n"); + int ch = getch(); +#endif +} + +/* -------------------------------------------------------------------------- */ + +int main() { + /* Initialization. All of this may fail, but we will be notified by + * our errorFunction. */ + RTCDevice device = initializeDevice(); + RTCScene scene = initializeScene(device); + + /* This will hit the triangle at t=1. */ + castRay(scene, 0, 0, -1, 0, 0, 1); + + /* This will not hit anything. */ + castRay(scene, 1, 1, -1, 0, 0, 1); + + /* Though not strictly necessary in this example, you should + * always make sure to release resources allocated through Embree. */ + rtcReleaseScene(scene); + rtcReleaseDevice(device); + + /* wait for user input under Windows when opened in separate window */ + waitForKeyPressedUnderWindows(); + + return 0; +}