1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 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 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 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 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413
|
% Embree: High Performance Ray Tracing Kernels 3.13.5
% Intel Corporation
Embree Overview
===============
Intel® Embree is a collection of high-performance ray tracing kernels,
developed at Intel. The target users of Intel® Embree are graphics application
engineers who want to improve the performance of their
photo-realistic rendering application by leveraging Embree's
performance-optimized ray tracing kernels. The kernels are optimized
for the latest Intel® processors with support for SSE, AVX, AVX2, and
AVX-512 instructions. Intel® Embree supports runtime code selection to choose
the traversal and build algorithms that best matches the instruction
set of your CPU. We recommend using Intel® Embree through its API to get the
highest benefit from future improvements. Intel® Embree is released as Open
Source under the
[Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0).
Intel® Embree supports applications written with the Intel® Implicit SPMD
Program Compiler (Intel® ISPC, <https://ispc.github.io/>) by also providing an Intel® ISPC
interface to the core ray tracing algorithms. This makes it possible
to write a renderer in Intel® ISPC that automatically vectorizes and
leverages SSE, AVX, AVX2, and AVX-512 instructions. Intel® ISPC also supports
runtime code selection, thus Intel® ISPC will select the best code path for
your application.
Intel® Embree contains algorithms optimized for incoherent workloads (e.g.
Monte Carlo ray tracing algorithms) and coherent workloads
(e.g. primary visibility and hard shadow rays).
The single-ray traversal kernels of Intel® Embree provide high performance
for incoherent workloads and are very easy to integrate into existing
rendering applications. Using the stream kernels, even higher
performance for incoherent rays is possible, but integration might
require significant code changes to the application to use the stream
paradigm. In general for coherent workloads, the stream mode with
coherent flag set gives the best performance.
Intel® Embree also supports dynamic scenes by implementing high-performance
two-level spatial index structure construction algorithms.
In addition to the ray tracing kernels, Intel® Embree provides some
[Embree Tutorials] to demonstrate how to use the
[Embree API].
Supported Platforms
-------------------
Embree supports Windows (32-bit and 64-bit), Linux (64-bit), and macOS
(64-bit) both x86 and Apple M1 based. The code compiles with the Intel®
Compiler, GCC, Clang, and the Microsoft Compiler.
Using the Intel® Compiler improves performance by approximately
10%. Performance also varies across different operating
systems, with Linux typically performing best as it supports
transparently transitioning to 2MB pages.
Embree is optimized for Intel CPUs supporting SSE, AVX, AVX2, and
AVX-512 instructions. Embree requires at least an x86 CPU with support for
SSE2 or an Apple M1 CPU.
Embree Support and Contact
--------------------------
If you encounter bugs please report them via [Embree's GitHub Issue
Tracker](https://github.com/embree/embree/issues).
For questions and feature requests please write us at
<embree_support@intel.com>.
To receive notifications of updates and new features of Embree please
subscribe to the [Embree mailing
list](https://groups.google.com/d/forum/embree/).
Installation of Embree
======================
Windows ZIP File
-----------------
Embree linked against Visual Studio 2015 are provided as a ZIP file
[embree-3.13.5.x64.vc14.windows.zip](https://github.com/embree/embree/releases/download/v3.13.5/embree-3.13.5.x64.vc14.windows.zip). After
unpacking this ZIP file, you should set the path to the `lib` folder
manually to your `PATH` environment variable for applications to find
Embree.
Linux tar.gz Files
------------------
The Linux version of Embree is also delivered as a `tar.gz` file:
[embree-3.13.5.x86_64.linux.tar.gz](https://github.com/embree/embree/releases/download/v3.13.5/embree-3.13.5.x86_64.linux.tar.gz). Unpack
this file using `tar` and source the provided `embree-vars.sh` (if you
are using the bash shell) or `embree-vars.csh` (if you are using the C
shell) to set up the environment properly:
tar xzf embree-3.13.5.x86_64.linux.tar.gz
source embree-3.13.5.x86_64.linux/embree-vars.sh
We recommend adding a relative `RPATH` to your application that points
to the location where Embree (and TBB) can be found, e.g. `$ORIGIN/../lib`.
macOS ZIP file
-----------------
The macOS version of Embree is also delivered as a ZIP file:
[embree-3.13.5.x86_64.macosx.zip](https://github.com/embree/embree/releases/download/v3.13.5/embree-3.13.5.x86_64.macosx.zip). Unpack
this file using `tar` and source the provided `embree-vars.sh` (if you
are using the bash shell) or `embree-vars.csh` (if you are using the C
shell) to set up the environment properly:
unzip embree-3.13.5.x64.macosx.zip
source embree-3.13.5.x64.macosx/embree-vars.sh
If you want to ship Embree with your application, please use the Embree
library of the provided ZIP file. The library name of that Embree
library is of the form `@rpath/libembree.3.dylib`
(and similar also for the included TBB library). This ensures that you
can add a relative `RPATH` to your application that points to the location
where Embree (and TBB) can be found, e.g. `@loader_path/../lib`.
Compiling Embree
================
We recommend to use CMake to build Embree. Do not enable fast-math
optimizations; these might break Embree.
Linux and macOS
---------------
To compile Embree you need a modern C++ compiler that supports
C++11. Embree is tested with the following compilers:
Linux
- Intel® oneAPI DPC++/C++ Compiler 2022.0.0
- Intel® Compiler 2020 Update 1
- Intel® Compiler 2019 Update 4
- Intel® Compiler 2017 Update 1
- Intel® Compiler 2016 Update 3
- Intel® Compiler 2015 Update 3
- Clang 5.0.0
- Clang 4.0.0
- GCC 10.0.1 (Fedora 32) AVX512 support
- GCC 8.3.1 (Fedora 28) AVX512 support
- GCC 7.3.1 (Fedora 27) AVX2 support
- GCC 7.3.1 (Fedora 26) AVX2 support
- GCC 6.4.1 (Fedora 25) AVX2 support
macOS x86
- Intel® Compiler 2020 Update 1
- Intel® Compiler 2019 Update 4
- Apple LLVM 10.0.1 (macOS 10.14.6)
macOS M1
- Apple Clang 12.0.0
Embree supports using the Intel® Threading Building Blocks (TBB) as the
tasking system. For performance and flexibility reasons we recommend
to use Embree with the Intel® Threading Building Blocks (TBB) and best
also use TBB inside your application. Optionally you can disable TBB
in Embree through the `EMBREE_TASKING_SYSTEM` CMake variable.
Embree supports the Intel® Implicit SPMD Program Compiler (Intel® ISPC), which allows
straightforward parallelization of an entire renderer. If you do not
want to use Intel® ISPC then you can disable `EMBREE_ISPC_SUPPORT` in
CMake. Otherwise, download and install the Intel® ISPC binaries (we have
tested Intel® ISPC version 1.9.1) from
[ispc.github.io](https://ispc.github.io/downloads.html). After
installation, put the path to `ispc` permanently into your `PATH`
environment variable or you need to correctly set the
`EMBREE_ISPC_EXECUTABLE` variable during CMake configuration.
You additionally have to install CMake 3.1.0 or higher and the developer
version of GLUT.
Under macOS, all these dependencies can be installed
using [MacPorts](http://www.macports.org/):
sudo port install cmake tbb-devel glfw-devel
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
sudo yum install tbb-devel
sudo yum install glfw-devel
Type the following to install the dependencies using `apt-get`:
sudo apt-get install cmake-curses-gui
sudo apt-get install libtbb-dev
sudo apt-get install libglfw3-dev
Finally you can compile Embree using CMake. Create a build directory
inside the Embree root directory and execute `ccmake ..` inside this
build directory.
mkdir build
cd build
ccmake ..
Per default CMake will use the compilers specified with the `CC` and
`CXX` environment variables. Should you want to use a different
compiler, run `cmake` first and set the `CMAKE_CXX_COMPILER` and
`CMAKE_C_COMPILER` variables to the desired compiler. For example, to
use the Intel® Compiler instead of the default GCC on most Linux machines
(`g++` and `gcc`), execute
cmake -DCMAKE_CXX_COMPILER=icpc -DCMAKE_C_COMPILER=icc ..
Similarly, to use Clang set the variables to `clang++` and `clang`,
respectively. Note that the compiler variables cannot be changed anymore
after the first run of `cmake` or `ccmake`.
Running `ccmake` will open a dialog where you can perform various
configurations as described below in [CMake Configuration]. After having
configured Embree, press `c` (for configure) and `g` (for generate) to
generate a Makefile and leave the configuration. The code can be
compiled by executing make.
make
The executables will be generated inside the build folder. We recommend
to finally install the Embree library and header files on your
system. Therefore set the `CMAKE_INSTALL_PREFIX` to `/usr` in cmake
and type:
sudo make install
If you keep the default `CMAKE_INSTALL_PREFIX` of `/usr/local` then
you have to make sure the path `/usr/local/lib` is in your
`LD_LIBRARY_PATH`.
You can also uninstall Embree again by executing:
sudo make uninstall
If you cannot install Embree on your system (e.g. when you don't have
administrator rights) you need to add embree_root_directory/build to
your `LD_LIBRARY_PATH`.
Windows
-------
Embree is tested using the following compilers under Windows:
- Visual Studio 2019
- Visual Studio 2017
- Visual Studio 2015 (Update 1)
- Intel® oneAPI DPC++/C++ Compiler 2022.0.0
- Intel® Compiler 2019 Update 6
- Intel® Compiler 2017 Update 8
- LLVM Clang 9.0.0
To compile Embree for AVX-512 you have to use the Intel® Compiler.
Embree supports using the Intel® Threading Building Blocks (TBB) as the
tasking system. For performance and flexibility reasons we recommend
to use Embree with the Intel® Threading Building Blocks (TBB) and best
also use TBB inside your application. Optionally you can disable TBB
in Embree through the `EMBREE_TASKING_SYSTEM` CMake variable.
Embree will either find the Intel® Threading Building Blocks (TBB)
installation that comes with the Intel® Compiler, or you can install the
binary distribution of TBB directly from
[https://github.com/oneapi-src/oneTBB/releases](https://github.com/oneapi-src/oneTBB/releases)
into a folder named `tbb` into your Embree root directory. You also have
to make sure that the libraries `tbb.dll` and `tbb_malloc.dll` can be
found when executing your Embree applications, e.g. by putting the path
to these libraries into your `PATH` environment variable.
Embree supports the Intel® Implicit SPMD Program Compiler (Intel® ISPC), which allows
straightforward parallelization of an entire renderer. When installing
Intel® ISPC, make sure to download an Intel® ISPC version from
[ispc.github.io](https://ispc.github.io/downloads.html) that is
compatible with your Visual Studio version. After installation, put
the path to `ispc.exe` permanently into your `PATH` environment
variable or you need to correctly set the `EMBREE_ISPC_EXECUTABLE` variable
during CMake configuration. If you do not want to use Intel® ISPC then you
can disable `EMBREE_ISPC_SUPPORT` in CMake.
We have tested Embree with the following Intel® ISPC versions:
- Intel® ISPC 1.14.1
- Intel® ISPC 1.13.0
- Intel® ISPC 1.12.0
- Intel® ISPC 1.9.2
You additionally have to install [CMake](http://www.cmake.org/download/)
(version 2.8.11 or higher). Note that you need a native Windows CMake
installation, because CMake under Cygwin cannot generate solution files
for Visual Studio.
### Using the IDE
Run `cmake-gui`, browse to the Embree sources, set the build directory
and click Configure. Now you can select the Generator, e.g. "Visual
Studio 12 2013" for a 32-bit build or "Visual Studio 12 2013 Win64"
for a 64-bit build.
To use a different compiler than the Microsoft Visual C++ compiler, you
additionally need to specify the proper compiler toolset through the
option "Optional toolset to use (-T parameter)". E.g. to use Clang for
compilation set the toolset to "LLVM_v142", to use the Intel®
Compiler 2017 for compilation set the toolset to "Intel C++
Compiler 17.0".
Do not change the toolset manually in a solution file (neither through
the project properties dialog, nor through the "Use Intel Compiler"
project context menu), because then some compiler specific command line
options cannot be set by CMake.
Most configuration parameters described in the [CMake Configuration]
can be set under Windows as well. Finally, click "Generate" to create
the Visual Studio solution files.
The following CMake options are only available under Windows:
+ `CMAKE_CONFIGURATION_TYPE`: List of generated
configurations. Default value is Debug;Release;RelWithDebInfo.
+ `USE_STATIC_RUNTIME`: Use the static version of the C/C++ runtime
library. This option is turned OFF by default.
Use the generated Visual Studio solution file `embree2.sln` to compile
the project. To build Embree with support for the AVX2 instruction set
you need at least Visual Studio 2013 (Update 4).
We recommend enabling syntax highlighting for the `.ispc` source and
`.isph` header files. To do so open Visual Studio, go to Tools ⇒
Options ⇒ Text Editor ⇒ File Extension and add the `isph` and `ispc`
extensions for the "Microsoft Visual C++" editor.
### Using the Command Line
Embree can also be configured and built without the IDE using the Visual
Studio command prompt:
cd path\to\embree
mkdir build
cd build
cmake -G "Visual Studio 12 2013 Win64" ..
cmake --build . --config Release
To use the Intel® Compiler, set the proper toolset, e.g. for Intel
Compiler 17.0:
cmake -G "Visual Studio 12 2013 Win64" -T "Intel C++ Compiler 17.0" ..
cmake --build . --config Release
You can also build only some projects with the `--target` switch.
Additional parameters after "`--`" will be passed to `msbuild`. For
example, to build the Embree library in parallel use
cmake --build . --config Release --target embree -- /m
CMake Configuration
-------------------
The default CMake configuration in the configuration dialog should be
appropriate for most usages. The following list describes all
parameters that can be configured in CMake:
+ `CMAKE_BUILD_TYPE`: Can be used to switch between Debug mode
(Debug), Release mode (Release) (default), and Release mode with
enabled assertions and debug symbols (RelWithDebInfo).
+ `EMBREE_STACK_PROTECTOR`: Enables protection of return address
from buffer overwrites. This option is OFF by default.
+ `EMBREE_ISPC_SUPPORT`: Enables Intel® ISPC support of Embree. This option
is ON by default.
+ `EMBREE_STATIC_LIB`: Builds Embree as a static library (OFF by
default). Further multiple static libraries are generated for the
different ISAs selected (e.g. `embree3.a`, `embree3_sse42.a`,
`embree3_avx.a`, `embree3_avx2.a`, `embree3_avx512.a`). You have
to link these libraries in exactly this order of increasing ISA.
+ `EMBREE_API_NAMESPACE`: Specifies a namespace name to put all Embree
API symbols inside. By default no namespace is used and plain C symbols
exported.
+ `EMBREE_LIBRARY_NAME`: Specifies the name of the Embree library file
created. By default the name embree3 is used.
+ `EMBREE_IGNORE_CMAKE_CXX_FLAGS`: When enabled, Embree ignores
default CMAKE_CXX_FLAGS. This option is turned ON by default.
+ `EMBREE_TUTORIALS`: Enables build of Embree tutorials (default ON).
+ `EMBREE_BACKFACE_CULLING`: Enables backface culling, i.e. only
surfaces facing a ray can be hit. This option is turned OFF by
default.
+ `EMBREE_COMPACT_POLYS`: Enables compact tris/quads, i.e. only
geomIDs and primIDs are stored inside the leaf nodes.
+ `EMBREE_FILTER_FUNCTION`: Enables the intersection filter function
feature (ON by default).
+ `EMBREE_RAY_MASK`: Enables the ray masking feature (OFF by default).
+ `EMBREE_RAY_PACKETS`: Enables ray packet traversal kernels. This
feature is turned ON by default. When turned on packet traversal is
used internally and packets passed to rtcIntersect4/8/16 are kept
intact in callbacks (when the ISA of appropriate width is enabled).
+ `EMBREE_IGNORE_INVALID_RAYS`: Makes code robust against the risk of
full-tree traversals caused by invalid rays (e.g. rays containing
INF/NaN as origins). This option is turned OFF by default.
+ `EMBREE_TASKING_SYSTEM`: Chooses between Intel® Threading TBB
Building Blocks (TBB), Parallel Patterns Library (PPL) (Windows
only), or an internal tasking system (INTERNAL). By default TBB is
used.
+ `EMBREE_TBB_ROOT`: If Intel® Threading Building Blocks (TBB)
is used as a tasking system, search the library in this directory
tree.
+ `EMBREE_TBB_COMPONENT`: The component/library name of Intel® Threading
Building Blocks (TBB). Embree searches for this library name (default: tbb)
when TBB is used as tasking system.
+ `EMBREE_TBB_POSTFIX`: If Intel® Threading Building Blocks (TBB)
is used as a tasking system, link to tbb<EMBREE_TBB_POSTFIX>.(so,dll,lib).
Defaults to the empty string.
+ `EMBREE_TBB_DEBUG_ROOT`: If Intel® Threading Building Blocks (TBB)
is used as a tasking system, search the library in this directory
tree in Debug mode. Defaults to `EMBREE_TBB_ROOT`.
+ `EMBREE_TBB_DEBUG_POSTFIX`: If Intel® Threading Building Blocks (TBB)
is used as a tasking system, link to tbb<EMBREE_TBB_DEBUG_POSTFIX>.(so,dll,lib)
in Debug mode. Defaults to "_debug".
+ `EMBREE_MAX_ISA`: Select highest supported ISA (SSE2, SSE4.2, AVX,
AVX2, AVX512, or NONE). When set to NONE the
EMBREE_ISA_* variables can be used to enable ISAs individually. By
default the option is set to AVX2.
+ `EMBREE_ISA_SSE2`: Enables SSE2 when EMBREE_MAX_ISA is set to
NONE. By default this option is turned OFF.
+ `EMBREE_ISA_SSE42`: Enables SSE4.2 when EMBREE_MAX_ISA is set to
NONE. By default this option is turned OFF.
+ `EMBREE_ISA_AVX`: Enables AVX when EMBREE_MAX_ISA is set to NONE. By
default this option is turned OFF.
+ `EMBREE_ISA_AVX2`: Enables AVX2 when EMBREE_MAX_ISA is set to
NONE. By default this option is turned OFF.
+ `EMBREE_ISA_AVX512`: Enables AVX-512 for Skylake when
EMBREE_MAX_ISA is set to NONE. By default this option is turned OFF.
+ `EMBREE_GEOMETRY_TRIANGLE`: Enables support for trianglegeometries
(ON by default).
+ `EMBREE_GEOMETRY_QUAD`: Enables support for quad geometries (ON by
default).
+ `EMBREE_GEOMETRY_CURVE`: Enables support for curve geometries (ON by
default).
+ `EMBREE_GEOMETRY_SUBDIVISION`: Enables support for subdivision
geometries (ON by default).
+ `EMBREE_GEOMETRY_INSTANCE`: Enables support for instances (ON by
default).
+ `EMBREE_GEOMETRY_USER`: Enables support for user defined geometries
(ON by default).
+ `EMBREE_GEOMETRY_POINT`: Enables support for point geometries
(ON by default).
+ `EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR`: Specifies a
factor that controls the self intersection avoidance feature for flat
curves. Flat curve intersections which are closer than
curve_radius*`EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR` to
the ray origin are ignored. A value of 0.0f disables self
intersection avoidance while 2.0f is the default value.
+ `EMBREE_DISC_POINT_SELF_INTERSECTION_AVOIDANCE`: Enables self
intersection avoidance for RTC_GEOMETRY_TYPE_DISC_POINT geometry
type (ON by default). When enabled intersections are skipped if the ray
origin lies inside the sphere defined by the point primitive.
+ `EMBREE_MIN_WIDTH`: Enabled the min-width feature, which allows
increasing the radius of curves and points to match some amount of
pixels. See [rtcSetGeometryMaxRadiusScale] for more details.
+ `EMBREE_MAX_INSTANCE_LEVEL_COUNT`: Specifies the maximum number of nested
instance levels. Should be greater than 0; the default value is 1.
Instances nested any deeper than this value will silently disappear in
release mode, and cause assertions in debug mode.
Using Embree
=============
The most convenient way of using Embree is through CMake. Just let
CMake find Embree using the `FIND_PACKAGE` function inside your
`CMakeLists.txt` file:
FIND_PACKAGE(embree 3.0 REQUIRED)
To cmake to properly find Embree you need to set the `embree_DIR`
variable to the folder you extracted Embree to.
The `FIND_PACKAGE` function will create an embree target that
you can add to your target link libraries:
TARGET_LINK_LIBRARIES(application embree)
Now please have a look at the [Embree Tutorials] source code and the
[Embree API] section to get started.
Embree API
==========
The Embree API is a low-level C99 ray tracing API which can be used to
construct 3D scenes and perform ray queries of different types inside
these scenes. All API calls carry the prefix `rtc` (or `RTC` for types)
which stands for **r**ay **t**racing **c**ore.
The API also exists in an Intel® Implicit SPMD Program Compiler (Intel®
ISPC) version, which is almost identical but contains additional
functions that operate on ray packets with a size of the native SIMD
width used by Intel® ISPC. For simplicity this document refers to the
C99 version of the API functions. For changes when upgrading from the
Embree 2 to the current Embree 3 API see Section [Upgrading from
Embree 2 to Embree 3].
The API supports scenes consisting of different geometry types such as
triangle meshes, quad meshes (triangle pairs), grid meshes, flat
curves, round curves, oriented curves, subdivision meshes, instances,
and user-defined geometries. See Section [Scene Object](#scene-object)
for more information.
Finding the closest hit of a ray segment with the scene
(`rtcIntersect`-type functions), and determining whether any hit
between a ray segment and the scene exists (`rtcOccluded`-type
functions) are both supported. The API supports queries for single
rays, ray packets, and ray streams. See Section [Ray
Queries](#ray-queries) for more information.
The API is designed in an object-oriented manner, e.g. it contains
device objects (`RTCDevice` type), scene objects (`RTCScene` type),
geometry objects (`RTCGeometry` type), buffer objects (`RTCBuffer`
type), and BVH objects (`RTCBVH` type). All objects are reference
counted, and handles can be released by calling the appropriate release
function (e.g. `rtcReleaseDevice`) or retained by incrementing the
reference count (e.g. `rtcRetainDevice`). In general, API calls that
access the same object are not thread-safe, unless specified
differently. However, attaching geometries to the same scene and
performing ray queries in a scene is thread-safe.
Device Object
-------------
Embree supports a device concept, which allows different components of
the application to use the Embree API without interfering with each
other. An application typically first creates a device using the
[rtcNewDevice] function. This device can then be used to construct
further objects, such as scenes and geometries. Before the application
exits, it should release all devices by invoking [rtcReleaseDevice].
An application typically creates only a single device. If required
differently, it should only use a small number of devices at any given
time.
Each user thread has its own error flag per device. If an error occurs
when invoking an API function, this flag is set to an error code (if it
isn't already set by a previous error). See Section
[rtcGetDeviceError] for information on how to read the error code and
Section [rtcSetDeviceErrorFunction] on how to register a callback
that is invoked for each error encountered. It is recommended to always
set a error callback function, to detect all errors.
Scene Object
------------
A scene is a container for a set of geometries, and contains a spatial
acceleration structure which can be used to perform different types of
ray queries.
A scene is created using the `rtcNewScene` function call, and released
using the `rtcReleaseScene` function call. To populate a scene with
geometries use the `rtcAttachGeometry` call, and to detach them use the
`rtcDetachGeometry` call. Once all scene geometries are attached, an
`rtcCommitScene` call (or `rtcJoinCommitScene` call) will finish the
scene description and trigger building of internal data structures.
After the scene got committed, it is safe to perform ray queries (see
Section [Ray Queries](#ray-queries)) or to query the scene bounding box
(see [rtcGetSceneBounds] and [rtcGetSceneLinearBounds]).
If scene geometries get modified or attached or detached, the
`rtcCommitScene` call must be invoked before performing any further ray
queries for the scene; otherwise the effect of the ray query is
undefined. The modification of a geometry, committing the scene, and
tracing of rays must always happen sequentially, and never at the same
time. Any API call that sets a property of the scene or geometries
contained in the scene count as scene modification, e.g. including
setting of intersection filter functions.
Scene flags can be used to configure a scene to use less memory
(`RTC_SCENE_FLAG_COMPACT`), use more robust traversal algorithms
(`RTC_SCENE_FLAG_ROBUST`), and to optimize for dynamic content. See
Section [rtcSetSceneFlags] for more details.
A build quality can be specified for a scene to balance between
acceleration structure build performance and ray query performance. See
Section [rtcSetSceneBuildQuality] for more details on build quality.
Geometry Object
---------------
A new geometry is created using the `rtcNewGeometry` function.
Depending on the geometry type, different buffers must be bound (e.g.
using `rtcSetSharedGeometryBuffer`) to set up the geometry data. In
most cases, binding of a vertex and index buffer is required. The
number of primitives and vertices of that geometry is typically
inferred from the size of these bound buffers.
Changes to the geometry always must be committed using the
`rtcCommitGeometry` call before using the geometry. After committing, a
geometry is not included in any scene. A geometry can be added to a
scene by using the `rtcAttachGeometry` function (to automatically
assign a geometry ID) or using the `rtcAttachGeometryById` function (to
specify the geometry ID manually). A geometry can get attached to
multiple scenes.
All geometry types support multi-segment motion blur with an arbitrary
number of equidistant time steps (in the range of 2 to 129) inside a
user specified time range. Each geometry can have a different number of
time steps and a different time range. The motion blur geometry is
defined by linearly interpolating the geometries of neighboring time
steps. To construct a motion blur geometry, first the number of time
steps of the geometry must be specified using the
`rtcSetGeometryTimeStepCount` function, and then a vertex buffer for
each time step must be bound, e.g. using the
`rtcSetSharedGeometryBuffer` function. Optionally, a time range
defining the start (and end time) of the first (and last) time step can
be set using the `rtcSetGeometryTimeRange` function. This feature will
also allow geometries to appear and disappear during the camera shutter
time if the time range is a sub range of [0,1].
The API supports per-geometry filter callback functions (see
`rtcSetGeometryIntersectFilterFunction` and
`rtcSetGeometryOccludedFilterFunction`) that are invoked for each
intersection found during the `rtcIntersect`-type or `rtcOccluded`-type
calls. The former ones are called geometry intersection filter
functions, the latter ones geometry occlusion filter functions. These
filter functions are designed to be used to ignore intersections
outside of a user-defined silhouette of a primitive, e.g. to model tree
leaves using transparency textures.
Ray Queries
-----------
The API supports finding the closest hit of a ray segment with the
scene (`rtcIntersect`-type functions), and determining whether any hit
between a ray segment and the scene exists (`rtcOccluded`-type
functions).
Supported are single ray queries (`rtcIntersect1` and `rtcOccluded1`)
as well as ray packet queries for ray packets of size 4
(`rtcIntersect4` and `rtcOccluded4`), ray packets of size 8
(`rtcIntersect8` and `rtcOccluded8`), and ray packets of size 16
(`rtcIntersect16` and `rtcOccluded16`).
Ray streams in a variety of layouts are supported as well, such as
streams of single rays (`rtcIntersect1M` and `rtcOccluded1M`), streams
of pointers to single rays (`rtcIntersect1p` and `rtcOccluded1p`),
streams of ray packets (`rtcIntersectNM` and `rtcOccludedNM`), and
large packet-like streams in structure of pointer layout
(`rtcIntersectNp` and `rtcOccludedNp`).
See Sections [rtcIntersect1] and [rtcOccluded1] for a detailed
description of how to set up and trace a ray.
See tutorial [Triangle Geometry] for a complete example of how to
trace single rays and ray packets. Also have a look at the tutorial
[Stream Viewer] for an example of how to trace ray streams.
Point Queries
-------------
The API supports traversal of the BVH using a point query object that
specifies a location and a query radius. For all primitives
intersecting the according domain, a user defined callback function is
called which allows queries such as finding the closest point on the
surface geometries of the scene (see Tutorial [Closest Point]) or
nearest neighbour queries (see Tutorial [Voronoi]).
See Section [rtcPointQuery] for a detailed description of how to set
up point queries.
Collision Detection
-------------------
The Embree API also supports collision detection queries between two
scenes consisting only of user geometries. Embree only performs
broadphase collision detection, the narrow phase detection can be
performed through a callback function.
See Section [rtcCollide] for a detailed description of how to set up
collision detection.
Seen tutorial [Collision Detection](#collision-detection) for a
complete example of collision detection being used on a simple cloth
solver.
Miscellaneous
-------------
A context filter function, which can be set per ray query is supported
(see `rtcInitIntersectContext`). This filter function is designed to
change the semantics of the ray query, e.g. to accumulate opacity for
transparent shadows, count the number of surfaces along a ray, collect
all hits along a ray, etc.
The internal algorithms to build a BVH are exposed through the `RTCBVH`
object and `rtcBuildBVH` call. This call makes it possible to build a
BVH in a user-specified format over user-specified primitives. See the
documentation of the `rtcBuildBVH` call for more details.
For getting the most performance out of Embree, see the Section
[Performance Recommendations].
Upgrading from Embree 2 to Embree 3
===================================
We decided to introduce an improved API in Embree 3 that is not
backward compatible with the Embree 2 API. This step was required to
remove various deprecated API functions that accumulated over time,
improve extensibility of the API, fix suboptimal design decisions, fix
design mistakes (such as incompatible single ray and ray packet
layouts), clean up inconsistent naming, and increase flexibility.
To make porting to the new API easy, we provide a conversion script
that can do most of the work, and will annotate the code with remaining
changes required. The script can be invoked the following way for CPP
files:
./scripts/cpp-patch.py --patch embree2_to_embree3.patch
--in infile.cpp --out outfile.cpp
When invoked for Intel® ISPC files, add the `--ispc` option:
./scripts/cpp-patch.py --ispc --patch embree2_to_embree3.patch
--in infile.ispc --out outfile.ispc
Apply the script to each source file of your project that contains
Embree API calls or types. The input file and output file can also be
identical to perform the patch in-place. Please always backup your
original code before running the script, and inspect the code changes
done by the script using diff (e.g. `git diff`), to make sure no
undesired code locations got changed. Grep the code for comments
containing `EMBREE_FIXME` and perform the action described in the
comment.
The following changes need to be performed when switching from Embree 2
to Embree 3. Most of these changes are automatically done by the script
if not described differently.
We strongly recommend to set an error callback function (see
`rtcSetDeviceErrorFunction`) when porting to Embree 3 to detect all
runtime errors early.
Device
------
- `rtcInit` and `rtcExit` got removed. Please use the device concept
using the `rtcNewDevice` and `rtcReleaseDevice` functions instead.
- Functions that conceptually should operate on a device but did not
get a device argument got removed. The upgrade script replaces
these functions by the proper functions that operate on a device,
however, manually propagating the device handle to these function
calls might still be required.
Scene
-----
- The API no longer distinguishes between a static and a dynamic
scene. Some users had issues as they wanted to do minor
modifications to static scenes, but maintain high traversal
performance.
The new approach gives more flexibility, as each scene is
changeable, and build quality settings can be changed on a commit
basis to balance between build performance and render performance.
- The `rtcCommitThread` function got removed; use
`rtcJoinCommitScene` instead.
- The scene now supports different build quality settings. Please use
those instead of the previous way of `RTC_SCENE_STATIC`,
`RTC_SCENE_DYNAMIC`, and `RTC_SCENE_HIGH_QUALITY` flags.
Geometry
--------
- There is now only one `rtcNewGeometry` function to create
geometries which gets passed an enum to specify the type of
geometry to create. The number of vertices and primitives of the
geometries is inferred from the size of data buffers.
- We introduced an object type `RTCGeometry` for all geometries.
Previously a geometry was not a standalone object and could only
exist inside a scene. The new approach comes with more flexibility
and more readable code.
Operations like `rtcInterpolate` can now be performed on the
geometry object directly without the need of a scene. Further, an
application can choose to create its geometries independent of a
scene, e.g. each time a geometry node is added to its scene graph.
This modification changed many API functions to get passed one
`RTCGeometry` object instead of a `RTCScene` and `geomID`. The
script does all required changed automatically. However, in some
cases the script may introduce `rtcGetGeometry(scene, geomID)`
calls to retrieve the geometry handle. Best store the geometry
handle inside your scene representation (and release it in the
destructor) and access the handle directly instead of calling
`rtcGetGeometry`.
- Geometries are not included inside a scene anymore but can be
attached to a multiple scenes using the `rtcAttachGeomety` or
`rtcAttachGeometryByID` functions.
- As geometries are separate objects, commit semantics got introduced
for them too. Thus geometries must be committed through the
`rtcCommitGeometry` call before getting used. This allows for
earlier error checking and pre-calculating internal data per
geometry object.
Such commit points were previously not required in the Embree 2
API. The upgrade script attempts to insert the commits
automatically, but cannot do so properly under all circumstances.
Thus please check if every `rtcCommitGeometry` call inserted by the
script is properly placed, and if a `rtcCommitGeometry` call is
placed after a sequence of changes to a geometry.
- Only the latest version of the previous displacement function call
(`RTCDisplacementFunc2`) is now supported, and the callback is
passed as a structure containing all arguments.
- The deprecated `RTCBoundaryMode` type and `rtcSetBoundaryMode`
function got removed and replaced by `RTCSubdivisionMode` enum and
the `rtcSetGeometrySubdivisionMode` function. The script does this
replacement automatically.
- Ribbon curves and lines now avoid self-intersections automatically
The application can be simplified by removing special code paths
that previously did the self-intersection handling.
- The previous Embree 2 way of instancing was suboptimal as it
required user geometries to update the `instID` field of the ray
differently when used inside an instanced scene or inside a
top-level scene. The user geometry intersection code now just has
to copy the `context.instID` field into the `ray.instID` field to
function properly under all circumstances.
- The internal instancing code will update the `context.instID` field
properly when entering or leaving an instance. When instancing is
implemented manually through user geometries, the code must be
modified to set the `context.instID` field properly and no longer
pass `instID` through the ray. This change must done manually and
cannot be performed by the script.
- We flipped the direction of the geometry normal to the widely used
convention that a shape with counter-clockwise layout of vertices
has the normal pointing upwards (right-hand rule). Most modeling
tools follow that convention.
The conversion script does not perform this change, thus if
required adjust your code to flip `Ng` for triangle, quad, and
subdivision surfaces.
Buffers
-------
- With Embree 3 we are introducing explicit `RTCBuffer` objects.
However, you can still use the short way of sharing buffers with
Embree through the `rtcSetSharedGeometryBuffer` call.
- The `rtcMapBuffer` and `rtcUnmapBuffer` API calls were removed, and
we added the `rtcGetBufferData` call instead.
Previously the `rtcMapBuffer` call had the semantics of creating an
internal buffer when no buffer was shared for the corresponding
buffer slot. These invocations of `rtcMapBuffer` must be replaced
by an explicit creation of an internally managed buffer using the
`rtcNewGeometryBuffer` function.
The upgrade script cannot always detect if the `rtcMapBuffer` call
would create an internal buffer or just map the buffer pointer.
Thus check whether the `rtcNewGeometryBuffer` and
`rtcGetBufferData` calls are correct after the conversion.
- The `rtcUpdateGeometryBuffer` function now must be called for every
buffer that got modified by the application. Note that the
conversion script cannot automatically detect each location where a
buffer update is now required.
- The buffer type no longer encodes the time step or user vertex
buffer index. Now `RTC_VERTEX_BUFFER_TYPE` and additional `slot`
specifies the vertex buffer for a specific time step, and
`RTC_USER_VERTEX_BUFFER_TYPE` and additional `slot` specifies a
vertex attribute.
Miscellaneous {#miscellaneous}
-------------
- The header files for Embree 3 are now inside the `embree3` folder
(instead of `embree2` folder) and `libembree.so` is now called
`libembree3.so` to be able to install multiple Embree versions side
by side. We made the headers C99 compliant.
- All API objects are now reference counted with release functions to
decrement and retain functions to increment the reference count (if
required).
- Most callback functions no longer get different arguments as input,
but a pointer to a structure containing all arguments. This results
in more readable code, faster callback invocation (as some
arguments do not change between invocations) and is extensible, as
new members to the structure can be later added in a backward
compatible way (if required).
The conversion script can convert the definition and declaration of
the old callback functions in most cases. Before running the
script, make sure that you never type-cast a callback function when
assigning it (as this has the danger of assigning a callback
function with a wrong type if the conversion did not detect some
callbacks as such). If the script does not detect a callback
function, make sure the argument types match exactly the types in
the header (e.g. write `const int` instead of `int const` or
convert the callback manually).
- An intersection context is now required for each ray query
invocation. The context should be initialized using the
`rtcInitIntersectContext` function.
- The `rtcIntersect`-type functions get as input an `RTCRayHit` type,
which is similar to before, but has the ray and hit parts split
into two sub-structures.
The `rtcOccluded`-type functions get as input an `RTCRay` type,
which does not contain hit data anymore. When an occlusion is
found, the `tfar` element of the ray is set to `-inf`.
Required code changes cannot be done by the upgrade script and need
to be done manually.
- The ray layout for single rays and packets of rays had certain
incompatibilities (alignment of `org` and `dir` for single rays
caused gaps in the single ray layout that were not in the ray
packet layout). This issue never showed up because single rays and
ray packets were separate in the system initially. This layout
issue is now fixed, and a single ray has the same layout as a ray
packet of size 1.
- Previously Embree supported placing additional data at the end of
the ray structure, and accessing that data inside user geometry
callbacks and filter callback functions.
With Embree 3 this is no longer supported, and the ray passed to a
callback function may be copied to a different memory location. To
attach additional data to your ray, simply extend the intersection
context with a pointer to that data.
This change cannot be done by the script. Further, code will still
work if you extend the ray as the implementation did not change
yet.
- The ray structure now contains an additional `id` and `flags`
field. The `id` can be used to store the index of the ray with
respect to a ray packet or ray stream. The `flags` is reserved for
future use, and currently must be set to 0.
- All previous intersection filter callback variants have been
removed, except for the `RTCFilterFuncN` which gets a varying size
ray packet as input. The semantics of this filter function type
have changed from copying the hit on acceptance to clearing the
ray's valid argument in case of non-acceptance. This way, chaining
multiple filters is more efficient.
We kept the guarantee that for `rtcIntersect1/4/8/16` and
`rtcOccluded1/4/8/16` calls the packet size and ray order will not
change from the initial size and ordering when entering a filter
callback.
- We no longer export Intel® ISPC-specific symbols. This has the
advantage that certain linking issues went away, e.g. it is now
possible to link an Intel® ISPC application compiled for any
combination of ISAs, and link this to an Embree library compiled
with a different set of ISAs. Previously the ISAs of the
application had to be a subset of the ISAs of Embree, and when the
user enabled exactly one ISA, they had to do this in Embree and the
application.
- We no longer export the Intel® ISPC tasking system, which means
that the application has the responsibility to implement the Intel®
ISPC tasking system itself. Intel® ISPC comes with example code on
how to do this. This change is not performed by the script and must
be done manually.
- Fixed many naming inconsistencies, and changed names of further API
functions. All these renamings are properly done by the script and
need no further attention.
Embree API Reference
====================
rtcNewDevice
------------
#### NAME
rtcNewDevice - creates a new device
#### SYNOPSIS
#include <embree3/rtcore.h>
RTCDevice rtcNewDevice(const char* config);
#### DESCRIPTION
This function creates a new device and returns a handle to this device.
The device object is reference counted with an initial reference count
of 1. The handle can be released using the `rtcReleaseDevice` API call.
The device object acts as a class factory for all other object types.
All objects created from the device (like scenes, geometries, etc.)
hold a reference to the device, thus the device will not be destroyed
unless these objects are destroyed first.
Objects are only compatible if they belong to the same device, e.g it
is not allowed to create a geometry in one device and attach it to a
scene created with a different device.
A configuration string (`config` argument) can be passed to the device
construction. This configuration string can be `NULL` to use the
default configuration.
The following configuration is supported:
- `threads=[int]`: Specifies a number of build threads to use. A
value of 0 enables all detected hardware threads. By default all
hardware threads are used.
- `user_threads=[int]`: Sets the number of user threads that can be
used to join and participate in a scene commit using
`rtcJoinCommitScene`. The tasking system will only use
threads-user\_threads many worker threads, thus if the app wants to
solely use its threads to commit scenes, just set threads equal to
user\_threads. This option only has effect with the Intel(R)
Threading Building Blocks (TBB) tasking system.
- `set_affinity=[0/1]`: When enabled, build threads are affinitized
to hardware threads. This option is disabled by default on standard
CPUs, and enabled by default on Xeon Phi Processors.
- `start_threads=[0/1]`: When enabled, the build threads are started
upfront. This can be useful for benchmarking to exclude thread
creation time. This option is disabled by default.
- `isa=[sse2,sse4.2,avx,avx2,avx512]`: Use specified ISA. By default
the ISA is selected automatically.
- `max_isa=[sse2,sse4.2,avx,avx2,avx512]`: Configures the automated
ISA selection to use maximally the specified ISA.
- `hugepages=[0/1]`: Enables or disables usage of huge pages. Under
Linux huge pages are used by default but under Windows and macOS
they are disabled by default.
- `enable_selockmemoryprivilege=[0/1]`: When set to 1, this enables
the `SeLockMemoryPrivilege` privilege with is required to use huge
pages on Windows. This option has an effect only under Windows and
is ignored on other platforms. See Section [Huge Page Support]
for more details.
- `verbose=[0,1,2,3]`: Sets the verbosity of the output. When set to
0, no output is printed by Embree, when set to a higher level more
output is printed. By default Embree does not print anything on the
console.
- `frequency_level=[simd128,simd256,simd512]`: Specifies the
frequency level the application want to run on, which can be
either:
a) simd128 to run at highest frequency
b) simd256 to run at AVX2-heavy frequency level
c) simd512 to run at heavy AVX512 frequency level. When some
frequency level is specified, Embree will avoid doing
optimizations that may reduce the frequency level below the
level specified. E.g. if your app does not use AVX instructions
setting "frequency\_level=simd128" will cause some CPUs to run
at highest frequency, which may result in higher application
performance if you do much shading. If you application heavily
uses AVX code, you should best set the frequency level to
simd256. Per default Embree tries to avoid reducing the
frequency of the CPU by setting the simd256 level only when the
CPU has no significant down clocking.
Different configuration options should be separated by commas, e.g.:
rtcNewDevice("threads=1,isa=avx");
#### EXIT STATUS
On success returns a handle of the created device. On failure returns
`NULL` as device and sets a per-thread error code that can be queried
using `rtcGetDeviceError(NULL)`.
#### SEE ALSO
[rtcRetainDevice], [rtcReleaseDevice]
rtcRetainDevice
---------------
#### NAME {#name}
rtcRetainDevice - increments the device reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcRetainDevice(RTCDevice device);
#### DESCRIPTION {#description}
Device objects are reference counted. The `rtcRetainDevice` function
increments the reference count of the passed device object (`device`
argument). This function together with `rtcReleaseDevice` allows to use
the internal reference counting in a C++ wrapper class to manage the
ownership of the object.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewDevice], [rtcReleaseDevice]
rtcReleaseDevice
----------------
#### NAME {#name}
rtcReleaseDevice - decrements the device reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcReleaseDevice(RTCDevice device);
#### DESCRIPTION {#description}
Device objects are reference counted. The `rtcReleaseDevice` function
decrements the reference count of the passed device object (`device`
argument). When the reference count falls to 0, the device gets
destroyed.
All objects created from the device (like scenes, geometries, etc.)
hold a reference to the device, thus the device will not get destroyed
unless these objects are destroyed first.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewDevice], [rtcRetainDevice]
rtcGetDeviceProperty
--------------------
#### NAME {#name}
rtcGetDeviceProperty - queries properties of the device
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
ssize_t rtcGetDeviceProperty(
RTCDevice device,
enum RTCDeviceProperty prop
);
#### DESCRIPTION {#description}
The `rtcGetDeviceProperty` function can be used to query properties
(`prop` argument) of a device object (`device` argument). The returned
property is an integer of type `ssize_t`.
Possible properties to query are:
- `RTC_DEVICE_PROPERTY_VERSION`: Queries the combined version number
(MAJOR.MINOR.PATCH) with two decimal digits per component. E.g. for
Embree 2.8.3 the integer 208003 is returned.
- `RTC_DEVICE_PROPERTY_VERSION_MAJOR`: Queries the major version
number of Embree.
- `RTC_DEVICE_PROPERTY_VERSION_MINOR`: Queries the minor version
number of Embree.
- `RTC_DEVICE_PROPERTY_VERSION_PATCH`: Queries the patch version
number of Embree.
- `RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED`: Queries whether the
`rtcIntersect4` and `rtcOccluded4` functions preserve packet size
and ray order when invoking callback functions. This is only the
case if Embree is compiled with `EMBREE_RAY_PACKETS` and `SSE2` (or
`SSE4.2`) enabled, and if the machine it is running on supports
`SSE2` (or `SSE4.2`).
- `RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED`: Queries whether the
`rtcIntersect8` and `rtcOccluded8` functions preserve packet size
and ray order when invoking callback functions. This is only the
case if Embree is compiled with `EMBREE_RAY_PACKETS` and `AVX` (or
`AVX2`) enabled, and if the machine it is running on supports `AVX`
(or `AVX2`).
- `RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED`: Queries whether the
`rtcIntersect16` and `rtcOccluded16` functions preserve packet size
and ray order when invoking callback functions. This is only the
case if Embree is compiled with `EMBREE_RAY_PACKETS` and `AVX512`
enabled, and if the machine it is running on supports `AVX512`.
- `RTC_DEVICE_PROPERTY_RAY_STREAM_SUPPORTED`: Queries whether
`rtcIntersect1M`, `rtcIntersect1Mp`, `rtcIntersectNM`,
`rtcIntersectNp`, `rtcOccluded1M`, `rtcOccluded1Mp`,
`rtcOccludedNM`, and `rtcOccludedNp` are supported. This is only
the case if Embree is compiled with `EMBREE_RAY_PACKETS` enabled.
- `RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED`: Queries whether ray masks
are supported. This is only the case if Embree is compiled with
`EMBREE_RAY_MASK` enabled.
- `RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED`: Queries whether
back face culling is enabled. This is only the case if Embree is
compiled with `EMBREE_BACKFACE_CULLING` enabled.
- `RTC_DEVICE_PROPERTY_COMPACT_POLYS_ENABLED`: Queries whether
compact polys is enabled. This is only the case if Embree is
compiled with `EMBREE_COMPACT_POLYS` enabled.
- `RTC_DEVICE_PROPERTY_FILTER_FUNCTION_SUPPORTED`: Queries whether
filter functions are supported, which is the case if Embree is
compiled with `EMBREE_FILTER_FUNCTION` enabled.
- `RTC_DEVICE_PROPERTY_IGNORE_INVALID_RAYS_ENABLED`: Queries whether
invalid rays are ignored, which is the case if Embree is compiled
with `EMBREE_IGNORE_INVALID_RAYS` enabled.
- `RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED`: Queries whether
triangles are supported, which is the case if Embree is compiled
with `EMBREE_GEOMETRY_TRIANGLE` enabled.
- `RTC_DEVICE_PROPERTY_QUAD_GEOMETRY_SUPPORTED`: Queries whether
quads are supported, which is the case if Embree is compiled with
`EMBREE_GEOMETRY_QUAD` enabled.
- `RTC_DEVICE_PROPERTY_SUBDIVISION_GEOMETRY_SUPPORTED`: Queries
whether subdivision meshes are supported, which is the case if
Embree is compiled with `EMBREE_GEOMETRY_SUBDIVISION` enabled.
- `RTC_DEVICE_PROPERTY_CURVE_GEOMETRY_SUPPORTED`: Queries whether
curves are supported, which is the case if Embree is compiled with
`EMBREE_GEOMETRY_CURVE` enabled.
- `RTC_DEVICE_PROPERTY_POINT_GEOMETRY_SUPPORTED`: Queries whether
points are supported, which is the case if Embree is compiled with
`EMBREE_GEOMETRY_POINT` enabled.
- `RTC_DEVICE_PROPERTY_USER_GEOMETRY_SUPPORTED`: Queries whether user
geometries are supported, which is the case if Embree is compiled
with `EMBREE_GEOMETRY_USER` enabled.
- `RTC_DEVICE_PROPERTY_TASKING_SYSTEM`: Queries the tasking system
Embree is compiled with. Possible return values are:
0. internal tasking system
1. Intel Threading Building Blocks (TBB)
2. Parallel Patterns Library (PPL)
- `RTC_DEVICE_PROPERTY_JOIN_COMMIT_SUPPORTED`: Queries whether
`rtcJoinCommitScene` is supported. This is not the case when Embree
is compiled with PPL or older versions of TBB.
- `RTC_DEVICE_PROPERTY_PARALLEL_COMMIT_SUPPORTED`: Queries whether
`rtcCommitScene` can get invoked from multiple TBB worker threads
concurrently. This feature is only supported starting with TBB 2019
Update 9.
#### EXIT STATUS {#exit-status}
On success returns the value of the queried property. For properties
returning a boolean value, the return value 0 denotes `false` and 1
denotes `true`.
On failure zero is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
rtcGetDeviceError
-----------------
#### NAME {#name}
rtcGetDeviceError - returns the error code of the device
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCError rtcGetDeviceError(RTCDevice device);
#### DESCRIPTION {#description}
Each thread has its own error code per device. If an error occurs when
calling an API function, this error code is set to the occurred error
if it stores no previous error. The `rtcGetDeviceError` function reads
and returns the currently stored error and clears the error code. This
assures that the returned error code is always the first error occurred
since the last invocation of `rtcGetDeviceError`.
Possible error codes returned by `rtcGetDeviceError` are:
- `RTC_ERROR_NONE`: No error occurred.
- `RTC_ERROR_UNKNOWN`: An unknown error has occurred.
- `RTC_ERROR_INVALID_ARGUMENT`: An invalid argument was specified.
- `RTC_ERROR_INVALID_OPERATION`: The operation is not allowed for the
specified object.
- `RTC_ERROR_OUT_OF_MEMORY`: There is not enough memory left to
complete the operation.
- `RTC_ERROR_UNSUPPORTED_CPU`: The CPU is not supported as it does
not support the lowest ISA Embree is compiled for.
- `RTC_ERROR_CANCELLED`: The operation got canceled by a memory
monitor callback or progress monitor callback function.
When the device construction fails, `rtcNewDevice` returns `NULL` as
device. To detect the error code of a such a failed device
construction, pass `NULL` as device to the `rtcGetDeviceError`
function. For all other invocations of `rtcGetDeviceError`, a proper
device pointer must be specified.
#### EXIT STATUS {#exit-status}
Returns the error code for the device.
#### SEE ALSO {#see-also}
[rtcSetDeviceErrorFunction]
rtcSetDeviceErrorFunction
-------------------------
#### NAME {#name}
rtcSetDeviceErrorFunction - sets an error callback function for the device
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
typedef void (*RTCErrorFunction)(
void* userPtr,
RTCError code,
const char* str
);
void rtcSetDeviceErrorFunction(
RTCDevice device,
RTCErrorFunction error,
void* userPtr
);
#### DESCRIPTION {#description}
Using the `rtcSetDeviceErrorFunction` call, it is possible to set a
callback function (`error` argument) with payload (`userPtr` argument),
which is called whenever an error occurs for the specified device
(`device` argument).
Only a single callback function can be registered per device, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
When the registered callback function is invoked, it gets passed the
user-defined payload (`userPtr` argument as specified at registration
time), the error code (`code` argument) of the occurred error, as well
as a string (`str` argument) that further describes the error.
The error code is also set if an error callback function is registered.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetDeviceError]
rtcSetDeviceMemoryMonitorFunction
---------------------------------
#### NAME {#name}
rtcSetDeviceMemoryMonitorFunction - registers a callback function
to track memory consumption
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
typedef bool (*RTCMemoryMonitorFunction)(
void* userPtr,
ssize_t bytes,
bool post
);
void rtcSetDeviceMemoryMonitorFunction(
RTCDevice device,
RTCMemoryMonitorFunction memoryMonitor,
void* userPtr
);
#### DESCRIPTION {#description}
Using the `rtcSetDeviceMemoryMonitorFunction` call, it is possible to
register a callback function (`memoryMonitor` argument) with payload
(`userPtr` argument) for a device (`device` argument), which is called
whenever internal memory is allocated or deallocated by objects of that
device. Using this memory monitor callback mechanism, the application
can track the memory consumption of an Embree device, and optionally
terminate API calls that consume too much memory.
Only a single callback function can be registered per device, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
Once registered, the Embree device will invoke the memory monitor
callback function before or after it allocates or frees important
memory blocks. The callback function gets passed the payload as
specified at registration time (`userPtr` argument), the number of
bytes allocated or deallocated (`bytes` argument), and whether the
callback is invoked after the allocation or deallocation took place
(`post` argument). The callback function might get called from multiple
threads concurrently.
The application can track the current memory usage of the Embree device
by atomically accumulating the `bytes` input parameter provided to the
callback function. This parameter will be \>0 for allocations and \<0
for deallocations.
Embree will continue its operation normally when returning `true` from
the callback function. If `false` is returned, Embree will cancel the
current operation with the `RTC_ERROR_OUT_OF_MEMORY` error code.
Issuing multiple cancel requests from different threads is allowed.
Canceling will only happen when the callback was called for allocations
(bytes \> 0), otherwise the cancel request will be ignored.
If a callback to cancel was invoked before the allocation happens
(`post == false`), then the `bytes` parameter should not be
accumulated, as the allocation will never happen. If the callback to
cancel was invoked after the allocation happened (`post == true`), then
the `bytes` parameter should be accumulated, as the allocation properly
happened and a deallocation will later free that data block.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewDevice]
rtcNewScene
-----------
#### NAME {#name}
rtcNewScene - creates a new scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCScene rtcNewScene(RTCDevice device);
#### DESCRIPTION {#description}
This function creates a new scene bound to the specified device
(`device` argument), and returns a handle to this scene. The scene
object is reference counted with an initial reference count of 1. The
scene handle can be released using the `rtcReleaseScene` API call.
#### EXIT STATUS {#exit-status}
On success a scene handle is returned. On failure `NULL` is returned
and an error code is set that can be queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcRetainScene], [rtcReleaseScene]
rtcGetSceneDevice
-----------------
#### NAME {#name}
rtcGetSceneDevice - returns the device the scene got created in
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCDevice rtcGetSceneDevice(RTCScene scene);
#### DESCRIPTION {#description}
This function returns the device object the scene got created in. The
returned handle own one additional reference to the device object, thus
you should need to call `rtcReleaseDevice` when the returned handle is
no longer required.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcReleaseDevice]
rtcRetainScene
--------------
#### NAME {#name}
rtcRetainScene - increments the scene reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcRetainScene(RTCScene scene);
#### DESCRIPTION {#description}
Scene objects are reference counted. The `rtcRetainScene` function
increments the reference count of the passed scene object (`scene`
argument). This function together with `rtcReleaseScene` allows to use
the internal reference counting in a C++ wrapper class to handle the
ownership of the object.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewScene], [rtcReleaseScene]
rtcReleaseScene
---------------
#### NAME {#name}
rtcReleaseScene - decrements the scene reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcReleaseScene(RTCScene scene);
#### DESCRIPTION {#description}
Scene objects are reference counted. The `rtcReleaseScene` function
decrements the reference count of the passed scene object (`scene`
argument). When the reference count falls to 0, the scene gets
destroyed.
The scene holds a reference to all attached geometries, thus if the
scene gets destroyed, all geometries get detached and their reference
count decremented.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewScene], [rtcRetainScene]
rtcAttachGeometry
-----------------
#### NAME {#name}
rtcAttachGeometry - attaches a geometry to the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
unsigned int rtcAttachGeometry(
RTCScene scene,
RTCGeometry geometry
);
#### DESCRIPTION {#description}
The `rtcAttachGeometry` function attaches a geometry (`geometry`
argument) to a scene (`scene` argument) and assigns a geometry ID to
that geometry. All geometries attached to a scene are defined to be
included inside the scene. A geometry can get attached to multiple
scenes. The geometry ID is unique for the scene, and is used to
identify the geometry when hit by a ray during ray queries.
This function is thread-safe, thus multiple threads can attach
geometries to a scene in parallel.
The geometry IDs are assigned sequentially, starting from 0, as long as
no geometry got detached. If geometries got detached, the
implementation will reuse IDs in an implementation dependent way.
Consequently sequential assignment is no longer guaranteed, but a
compact range of IDs.
These rules allow the application to manage a dynamic array to
efficiently map from geometry IDs to its own geometry representation.
Alternatively, the application can also use per-geometry user data to
map to its geometry representation. See `rtcSetGeometryUserData` and
`rtcGetGeometryUserData` for more information.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryUserData], [rtcGetGeometryUserData]
rtcAttachGeometryByID
---------------------
#### NAME {#name}
rtcAttachGeometryByID - attaches a geometry to the scene
using a specified geometry ID
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcAttachGeometryByID(
RTCScene scene,
RTCGeometry geometry,
unsigned int geomID
);
#### DESCRIPTION {#description}
The `rtcAttachGeometryByID` function attaches a geometry (`geometry`
argument) to a scene (`scene` argument) and assigns a user provided
geometry ID (`geomID` argument) to that geometry. All geometries
attached to a scene are defined to be included inside the scene. A
geometry can get attached to multiple scenes. The passed user-defined
geometry ID is used to identify the geometry when hit by a ray during
ray queries. Using this function, it is possible to share the same IDs
to refer to geometries inside the application and Embree.
This function is thread-safe, thus multiple threads can attach
geometries to a scene in parallel.
The user-provided geometry ID must be unused in the scene, otherwise
the creation of the geometry will fail. Further, the user-provided
geometry IDs should be compact, as Embree internally creates a vector
which size is equal to the largest geometry ID used. Creating very
large geometry IDs for small scenes would thus cause a memory
consumption and performance overhead.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcAttachGeometry]
rtcDetachGeometry
-----------------
#### NAME {#name}
rtcDetachGeometry - detaches a geometry from the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcDetachGeometry(RTCScene scene, unsigned int geomID);
#### DESCRIPTION {#description}
This function detaches a geometry identified by its geometry ID
(`geomID` argument) from a scene (`scene` argument). When detached, the
geometry is no longer contained in the scene.
This function is thread-safe, thus multiple threads can detach
geometries from a scene at the same time.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcAttachGeometry], [rtcAttachGeometryByID]
rtcGetGeometry
--------------
#### NAME {#name}
rtcGetGeometry - returns the geometry bound to
the specified geometry ID
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry rtcGetGeometry(RTCScene scene, unsigned int geomID);
#### DESCRIPTION {#description}
The `rtcGetGeometry` function returns the geometry that is bound to the
specified geometry ID (`geomID` argument) for the specified scene
(`scene` argument). This function just looks up the handle and does
*not* increment the reference count. If you want to get ownership of
the handle, you need to additionally call `rtcRetainGeometry`.
This function is not thread safe and thus can be used during rendering.
However, it is generally recommended to store the geometry handle
inside the application's geometry representation and look up the
geometry handle from that representation directly.
If you need a thread safe version of this function please use
[rtcGetGeometryThreadSafe].
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcAttachGeometry], [rtcAttachGeometryByID],
[rtcGetGeometryThreadSafe]
rtcGetGeometryThreadSafe
------------------------
#### NAME {#name}
rtcGetGeometryThreadSafe - returns the geometry bound to
the specified geometry ID
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry rtcGetGeometryThreadSafe(RTCScene scene, unsigned int geomID);
#### DESCRIPTION {#description}
The `rtcGetGeometryThreadSafe` function returns the geometry that is
bound to the specified geometry ID (`geomID` argument) for the
specified scene (`scene` argument). This function just looks up the
handle and does *not* increment the reference count. If you want to get
ownership of the handle, you need to additionally call
`rtcRetainGeometry`.
This function is thread safe and should NOT get used during rendering.
If you need a fast non-thread safe version during rendering please use
the [rtcGetGeometry] function.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcAttachGeometry], [rtcAttachGeometryByID], [rtcGetGeometry]
rtcCommitScene
--------------
#### NAME {#name}
rtcCommitScene - commits scene changes
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcCommitScene(RTCScene scene);
#### DESCRIPTION {#description}
The `rtcCommitScene` function commits all changes for the specified
scene (`scene` argument). This internally triggers building of a
spatial acceleration structure for the scene using all available worker
threads. Ray queries can be performed only after committing all scene
changes.
If the application uses TBB 2019 Update 9 or later for parallelization
of rendering, lazy scene construction during rendering is supported by
`rtcCommitScene`. Therefore `rtcCommitScene` can get called from
multiple TBB worker threads concurrently for the same scene. The
`rtcCommitScene` function will then internally isolate the scene
construction using a tbb::isolated\_task\_group. The alternative
approach of using `rtcJoinCommitScene` which uses an tbb:task\_arena
internally, is not recommended due to it's high runtime overhead.
If scene geometries get modified or attached or detached, the
`rtcCommitScene` call must be invoked before performing any further ray
queries for the scene; otherwise the effect of the ray query is
undefined. The modification of a geometry, committing the scene, and
tracing of rays must always happen sequentially, and never at the same
time. Any API call that sets a property of the scene or geometries
contained in the scene count as scene modification, e.g. including
setting of intersection filter functions.
The kind of acceleration structure built can be influenced using scene
flags (see `rtcSetSceneFlags`), and the quality can be specified using
the `rtcSetSceneBuildQuality` function.
Embree silently ignores primitives during spatial acceleration
structure construction that would cause numerical issues,
e.g. primitives containing NaNs, INFs, or values greater than 1.844E18f
(as no reasonable calculations can be performed with such values
without causing overflows).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcJoinCommitScene]
rtcJoinCommitScene
------------------
#### NAME {#name}
rtcJoinCommitScene - commits the scene from multiple threads
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcJoinCommitScene(RTCScene scene);
#### DESCRIPTION {#description}
The `rtcJoinCommitScene` function commits all changes for the specified
scene (`scene` argument). The scene commit internally triggers building
of a spatial acceleration structure for the scene. Ray queries can be
performed after scene changes got properly committed.
The `rtcJoinCommitScene` function can get called from multiple user
threads which will all cooperate in the build operation. All threads
calling into this function will return from `rtcJoinCommitScene` after
the scene commit is finished. All threads must consistently call
`rtcJoinCommitScene` and not `rtcCommitScene`.
In contrast to the `rtcCommitScene` function, the `rtcJoinCommitScene`
function can be called from multiple user threads, while the
`rtcCommitScene` can only get called from multiple TBB worker threads
when used concurrently. For optimal performance we strongly recommend
using TBB inside the application together with the `rtcCommitScene`
function and to avoid using the `rtcJoinCommitScene` function.
The `rtcJoinCommitScene` feature allows a flexible way to lazily create
hierarchies during rendering. A thread reaching a not-yet-constructed
sub-scene of a two-level scene can generate the sub-scene geometry and
call `rtcJoinCommitScene` on that just generated scene. During
construction, further threads reaching the not-yet-built scene can join
the build operation by also invoking `rtcJoinCommitScene`. A thread
that calls `rtcJoinCommitScene` after the build finishes will directly
return from the `rtcJoinCommitScene` call.
Multiple scene commit operations on different scenes can be running at
the same time, hence it is possible to commit many small scenes in
parallel, distributing the commits to many threads.
When using Embree with the Intel® Threading Building Blocks (which is
the default), threads that call `rtcJoinCommitScene` will join the
build operation, but other TBB worker threads might also participate in
the build. To avoid thread oversubscription, we recommend using TBB
also inside the application. Further, the join mode only works properly
starting with TBB v4.4 Update 1. For earlier TBB versions, threads that
call `rtcJoinCommitScene` to join a running build will just trigger the
build and wait for the build to finish. Further, old TBB versions with
`TBB_INTERFACE_VERSION_MAJOR < 8` do not support `rtcJoinCommitScene`,
and invoking this function will result in an error.
When using Embree with the internal tasking system, only threads that
call `rtcJoinCommitScene` will perform the build operation, and no
additional worker threads will be scheduled.
When using Embree with the Parallel Patterns Library (PPL),
`rtcJoinCommitScene` is not supported and calling that function will
result in an error.
To detect whether `rtcJoinCommitScene` is supported, use the
`rtcGetDeviceProperty` function.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcCommitScene], [rtcGetDeviceProperty]
rtcSetSceneProgressMonitorFunction
----------------------------------
#### NAME {#name}
rtcSetSceneProgressMonitorFunction - registers a callback
to track build progress
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
typedef bool (*RTCProgressMonitorFunction)(
void* ptr,
double n
);
void rtcSetSceneProgressMonitorFunction(
RTCScene scene,
RTCProgressMonitorFunction progress,
void* userPtr
);
#### DESCRIPTION {#description}
Embree supports a progress monitor callback mechanism that can be used
to report progress of hierarchy build operations and to cancel build
operations.
The `rtcSetSceneProgressMonitorFunction` registers a progress monitor
callback function (`progress` argument) with payload (`userPtr`
argument) for the specified scene (`scene` argument).
Only a single callback function can be registered per scene, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
Once registered, Embree will invoke the callback function multiple
times during hierarchy build operations of the scene, by passing the
payload as set at registration time (`userPtr` argument), and a double
in the range $[0, 1]$ which estimates the progress of the operation
(`n` argument). The callback function might be called from multiple
threads concurrently.
When returning `true` from the callback function, Embree will continue
the build operation normally. When returning `false`, Embree will
cancel the build operation with the `RTC_ERROR_CANCELLED` error code.
Issuing multiple cancel requests for the same build operation is
allowed.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewScene]
rtcSetSceneBuildQuality
-----------------------
#### NAME {#name}
rtcSetSceneBuildQuality - sets the build quality for
the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetSceneBuildQuality(
RTCScene scene,
enum RTCBuildQuality quality
);
#### DESCRIPTION {#description}
The `rtcSetSceneBuildQuality` function sets the build quality
(`quality` argument) for the specified scene (`scene` argument).
Possible values for the build quality are:
- `RTC_BUILD_QUALITY_LOW`: Create lower quality data structures,
e.g. for dynamic scenes. A two-level spatial index structure is
built when enabling this mode, which supports fast partial scene
updates, and allows for setting a per-geometry build quality
through the `rtcSetGeometryBuildQuality` function.
- `RTC_BUILD_QUALITY_MEDIUM`: Default build quality for most usages.
Gives a good compromise between build and render performance.
- `RTC_BUILD_QUALITY_HIGH`: Create higher quality data structures for
final-frame rendering. For certain geometry types this enables a
spatial split BVH.
Selecting a higher build quality results in better rendering
performance but slower scene commit times. The default build quality
for a scene is `RTC_BUILD_QUALITY_MEDIUM`.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryBuildQuality]
rtcSetSceneFlags
----------------
#### NAME {#name}
rtcSetSceneFlags - sets the flags for the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetSceneFlags(RTCScene scene, enum RTCSceneFlags flags);
#### DESCRIPTION {#description}
The `rtcSetSceneFlags` function sets the scene flags (`flags` argument)
for the specified scene (`scene` argument). Possible scene flags are:
- `RTC_SCENE_FLAG_NONE`: No flags set.
- `RTC_SCENE_FLAG_DYNAMIC`: Provides better build performance for
dynamic scenes (but also higher memory consumption).
- `RTC_SCENE_FLAG_COMPACT`: Uses compact acceleration structures and
avoids algorithms that consume much memory.
- `RTC_SCENE_FLAG_ROBUST`: Uses acceleration structures that allow
for robust traversal, and avoids optimizations that reduce
arithmetic accuracy. This mode is typically used for avoiding
artifacts caused by rays shooting through edges of neighboring
primitives.
- `RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION`: Enables support for a
filter function inside the intersection context for this scene. See
Section [rtcInitIntersectContext] for more details.
Multiple flags can be enabled using an `or` operation,
e.g. `RTC_SCENE_FLAG_COMPACT | RTC_SCENE_FLAG_ROBUST`.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetSceneFlags]
rtcGetSceneFlags
----------------
#### NAME {#name}
rtcGetSceneFlags - returns the flags of the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
enum RTCSceneFlags rtcGetSceneFlags(RTCScene scene);
#### DESCRIPTION {#description}
Queries the flags of a scene. This function can be useful when setting
individual flags, e.g. to just set the robust mode without changing
other flags the following way:
RTCSceneFlags flags = rtcGetSceneFlags(scene);
rtcSetSceneFlags(scene, RTC_SCENE_FLAG_ROBUST | flags);
#### EXIT STATUS {#exit-status}
On failure `RTC_SCENE_FLAG_NONE` is returned and an error code is set
that can be queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetSceneFlags]
rtcGetSceneBounds
-----------------
#### NAME {#name}
rtcGetSceneBounds - returns the axis-aligned bounding box of the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCORE_ALIGN(16) RTCBounds
{
float lower_x, lower_y, lower_z, align0;
float upper_x, upper_y, upper_z, align1;
};
void rtcGetSceneBounds(
RTCScene scene,
struct RTCBounds* bounds_o
);
#### DESCRIPTION {#description}
The `rtcGetSceneBounds` function queries the axis-aligned bounding box
of the specified scene (`scene` argument) and stores that bounding box
to the provided destination pointer (`bounds_o` argument). The stored
bounding box consists of lower and upper bounds for the x, y, and z
dimensions as specified by the `RTCBounds` structure.
The provided destination pointer must be aligned to 16 bytes. The
function may be invoked only after committing the scene; otherwise the
result is undefined.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetSceneLinearBounds], [rtcCommitScene], [rtcJoinCommitScene]
rtcGetSceneLinearBounds
-----------------------
#### NAME {#name}
rtcGetSceneLinearBounds - returns the linear bounds of the scene
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCORE_ALIGN(16) RTCLinearBounds
{
RTCBounds bounds0;
RTCBounds bounds1;
};
void rtcGetSceneLinearBounds(
RTCScene scene,
struct RTCLinearBounds* bounds_o
);
#### DESCRIPTION {#description}
The `rtcGetSceneLinearBounds` function queries the linear bounds of the
specified scene (`scene` argument) and stores them to the provided
destination pointer (`bounds_o` argument). The stored linear bounds
consist of bounding boxes for time 0 (`bounds0` member) and time 1
(`bounds1` member) as specified by the `RTCLinearBounds` structure.
Linearly interpolating these bounds to a specific time `t` yields
bounds for the geometry at that time.
The provided destination pointer must be aligned to 16 bytes. The
function may be called only after committing the scene, otherwise the
result is undefined.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetSceneBounds], [rtcCommitScene], [rtcJoinCommitScene]
rtcNewGeometry
--------------
#### NAME {#name}
rtcNewGeometry - creates a new geometry object
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
enum RTCGeometryType
{
RTC_GEOMETRY_TYPE_TRIANGLE,
RTC_GEOMETRY_TYPE_QUAD,
RTC_GEOMETRY_TYPE_SUBDIVISION,
RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE,
RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,
RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE,
RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE,
RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE,
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE,
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE,
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE,
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE,
RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE,
RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE,
RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE,
RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE,
RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE,
RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE,
RTC_GEOMETRY_TYPE_GRID,
RTC_GEOMETRY_TYPE_SPHERE_POINT,
RTC_GEOMETRY_TYPE_DISC_POINT,
RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT,
RTC_GEOMETRY_TYPE_USER,
RTC_GEOMETRY_TYPE_INSTANCE
};
RTCGeometry rtcNewGeometry(
RTCDevice device,
enum RTCGeometryType type
);
#### DESCRIPTION {#description}
Geometries are objects that represent an array of primitives of the
same type. The `rtcNewGeometry` function creates a new geometry of
specified type (`type` argument) bound to the specified device
(`device` argument) and returns a handle to this geometry. The geometry
object is reference counted with an initial reference count of 1. The
geometry handle can be released using the `rtcReleaseGeometry` API
call.
Supported geometry types are triangle meshes
(`RTC_GEOMETRY_TYPE_TRIANGLE` type), quad meshes (triangle pairs)
(`RTC_GEOMETRY_TYPE_QUAD` type), Catmull-Clark subdivision surfaces
(`RTC_GEOMETRY_TYPE_SUBDIVISION` type), curve geometries with different
bases (`RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE`,\
`RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE`,\
`RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE`,
`RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE` types) grid meshes
(`RTC_GEOMETRY_TYPE_GRID`), point geometries
(`RTC_GEOMETRY_TYPE_SPHERE_POINT`, `RTC_GEOMETRY_TYPE_DISC_POINT`,
`RTC_TYPE_ORIENTED_DISC_POINT`), user-defined geometries
(`RTC_GEOMETRY_TYPE_USER`), and instances
(`RTC_GEOMETRY_TYPE_INSTANCE`).
The types `RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE`, and
`RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE` will treat the curve as a
sweep surface of a varying-radius circle swept tangentially along the
curve. The types `RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE`, and
`RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE` use ray-facing ribbons as a
faster-to-intersect approximation.
After construction, geometries are enabled by default and not attached
to any scene. Geometries can be disabled (`rtcDisableGeometry` call),
and enabled again (`rtcEnableGeometry` call). A geometry can be
attached to multiple scenes using the `rtcAttachGeometry` call (or
`rtcAttachGeometryByID` call), and detached using the
`rtcDetachGeometry` call. During attachment, a geometry ID is assigned
to the geometry (or assigned by the user when using the
`rtcAttachGeometryByID` call), which uniquely identifies the geometry
inside that scene. This identifier is returned when primitives of the
geometry are hit in later ray queries for the scene.
Geometries can also be modified, including their vertex and index
buffers. After modifying a buffer, `rtcUpdateGeometryBuffer` must be
called to notify that the buffer got modified.
The application can use the `rtcSetGeometryUserData` function to set a
user data pointer to its own geometry representation, and later read
out this pointer using the `rtcGetGeometryUserData` function.
After setting up the geometry or modifying it, `rtcCommitGeometry` must
be called to finish the geometry setup. After committing the geometry,
vertex data interpolation can be performed using the `rtcInterpolate`
and `rtcInterpolateN` functions.
A build quality can be specified for a geometry using the
`rtcSetGeometryBuildQuality` function, to balance between acceleration
structure build performance and ray query performance. The build
quality per geometry will be used if a two-level acceleration structure
is built internally, which is the case if the `RTC_BUILD_QUALITY_LOW`
is set as the scene build quality. See Section
[rtcSetSceneBuildQuality] for more details.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcEnableGeometry], [rtcDisableGeometry], [rtcAttachGeometry],
[rtcAttachGeometryByID], [rtcUpdateGeometryBuffer],
[rtcSetGeometryUserData], [rtcGetGeometryUserData],
[rtcCommitGeometry], [rtcInterpolate], [rtcInterpolateN],
[rtcSetGeometryBuildQuality], [rtcSetSceneBuildQuality],
[RTC\_GEOMETRY\_TYPE\_TRIANGLE], [RTC\_GEOMETRY\_TYPE\_QUAD],
[RTC\_GEOMETRY\_TYPE\_SUBDIVISION], [RTC\_GEOMETRY\_TYPE\_CURVE],
[RTC\_GEOMETRY\_TYPE\_GRID], [RTC\_GEOMETRY\_TYPE\_POINT],
[RTC\_GEOMETRY\_TYPE\_USER], [RTC\_GEOMETRY\_TYPE\_INSTANCE]
RTC\_GEOMETRY\_TYPE\_TRIANGLE
-----------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_TRIANGLE - triangle geometry type
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry geometry =
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);
#### DESCRIPTION {#description}
Triangle meshes are created by passing `RTC_GEOMETRY_TYPE_TRIANGLE` to
the `rtcNewGeometry` function call. The triangle indices can be
specified by setting an index buffer (`RTC_BUFFER_TYPE_INDEX` type) and
the triangle vertices by setting a vertex buffer
(`RTC_BUFFER_TYPE_VERTEX` type). See `rtcSetGeometryBuffer` and
`rtcSetSharedGeometryBuffer` for more details on how to set buffers.
The index buffer must contain an array of three 32-bit indices per
triangle (`RTC_FORMAT_UINT3` format) and the number of primitives is
inferred from the size of that buffer. The vertex buffer must contain
an array of single precision `x`, `y`, `z` floating point coordinates
(`RTC_FORMAT_FLOAT3` format), and the number of vertices are inferred
from the size of that buffer. The vertex buffer can be at most 16 GB
large.
The parametrization of a triangle uses the first vertex `p0` as base
point, the vector `p1 - p0` as u-direction and the vector `p2 - p0` as
v-direction. Thus vertex attributes `t0,t1,t2` can be linearly
interpolated over the triangle the following way:
t_uv = (1-u-v)*t0 + u*t1 + v*t2
= t0 + u*(t1-t0) + v*(t2-t0)
A triangle whose vertices are laid out counter-clockwise has its
geometry normal pointing upwards outside the front face, like
illustrated in the following picture:
![][imgTriangleUV]
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` call. Then a vertex
buffer for each time step can be set using different buffer slots, and
all these buffers have to have the same stride and size.
Also see tutorial [Triangle Geometry] for an example of how to create
triangle meshes.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that be get
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry]
RTC\_GEOMETRY\_TYPE\_QUAD
-------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_QUAD - quad geometry type
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry geometry =
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_QUAD);
#### DESCRIPTION {#description}
Quad meshes are created by passing `RTC_GEOMETRY_TYPE_QUAD` to the
`rtcNewGeometry` function call. The quad indices can be specified by
setting an index buffer (`RTC_BUFFER_TYPE_INDEX` type) and the quad
vertices by setting a vertex buffer (`RTC_BUFFER_TYPE_VERTEX` type).
See `rtcSetGeometryBuffer` and `rtcSetSharedGeometryBuffer` for more
details on how to set buffers. The index buffer contains an array of
four 32-bit indices per quad (`RTC_FORMAT_UINT4` format), and the
number of primitives is inferred from the size of that buffer. The
vertex buffer contains an array of single precision `x`, `y`, `z`
floating point coordinates (`RTC_FORMAT_FLOAT3` format), and the number
of vertices is inferred from the size of that buffer. The vertex buffer
can be at most 16 GB large.
A quad is internally handled as a pair of two triangles `v0,v1,v3` and
`v2,v3,v1`, with the `u'`/`v'` coordinates of the second triangle
corrected by `u = 1-u'` and `v = 1-v'` to produce a quad
parametrization where `u` and `v` are in the range 0 to 1. Thus the
parametrization of a quad uses the first vertex `p0` as base point, and
the vector `p1 - p0` as `u`-direction, and `p3 - p0` as v-direction.
Thus vertex attributes `t0,t1,t2,t3` can be bilinearly interpolated
over the quadrilateral the following way:
t_uv = (1-v)((1-u)*t0 + u*t1) + v*((1-u)*t3 + u*t2)
Mixed triangle/quad meshes are supported by encoding a triangle as a
quad, which can be achieved by replicating the last triangle vertex
(`v0,v1,v2` -\> `v0,v1,v2,v2`). This way the second triangle is a line
(which can never get hit), and the parametrization of the first
triangle is compatible with the standard triangle parametrization.
A quad whose vertices are laid out counter-clockwise has its geometry
normal pointing upwards outside the front face, like illustrated in the
following picture.
![][imgQuadUV]
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` call. Then a vertex
buffer for each time step can be set using different buffer slots, and
all these buffers must have the same stride and size.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry]
RTC\_GEOMETRY\_TYPE\_GRID
-------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_GRID - grid geometry type
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry geometry =
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_GRID);
#### DESCRIPTION {#description}
Grid meshes are created by passing `RTC_GEOMETRY_TYPE_GRID` to the
`rtcNewGeometry` function call, and contain an array of grid
primitives. This array of grids can be specified by setting up a grid
buffer (with `RTC_BUFFER_TYPE_GRID` type and `RTC_FORMAT_GRID` format)
and the grid mesh vertices by setting a vertex buffer
(`RTC_BUFFER_TYPE_VERTEX` type). See `rtcSetGeometryBuffer` and
`rtcSetSharedGeometryBuffer` for more details on how to set buffers.
The number of grid primitives in the grid mesh is inferred from the
size of the grid buffer.
The vertex buffer contains an array of single precision `x`, `y`, `z`
floating point coordinates (`RTC_FORMAT_FLOAT3` format), and the number
of vertices is inferred from the size of that buffer.
Each grid in the grid buffer is of the type `RTCGrid`:
struct RTCGrid
{
unsigned int startVertexID;
unsigned int stride;
unsigned short width,height;
};
The `RTCGrid` structure describes a 2D grid of vertices (with respect
to the vertex buffer of the grid mesh). The `width` and `height`
members specify the number of vertices in u and v direction,
e.g. setting both `width` and `height` to 3 sets up a 3×3 vertex grid.
The maximum allowed `width` and `height` is 32767. The `startVertexID`
specifies the ID of the top-left vertex in the vertex grid, while the
`stride` parameter specifies a stride (in number of vertices) used to
step to the next row.
A vertex grid of dimensions `width` and `height` is treated as a
`(width-1)` x `(height-1)` grid of `quads` (triangle-pairs), with the
same shared edge handling as for regular quad meshes. However, the
`u`/`v` coordinates have the uniform range `[0..1]` for an entire
vertex grid. The `u` direction follows the `width` of the grid while
the `v` direction the `height`.
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` call. Then a vertex
buffer for each time step can be set using different buffer slots, and
all these buffers must have the same stride and size.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry]
RTC\_GEOMETRY\_TYPE\_SUBDIVISION
--------------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_SUBDIVISION - subdivision geometry type
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry geometry =
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_SUBDIVISION);
#### DESCRIPTION {#description}
Catmull-Clark subdivision meshes are supported, including support for
edge creases, vertex creases, holes, non-manifold geometry, and
face-varying interpolation. The number of vertices per face can be in
the range of 3 to 15 vertices (triangles, quadrilateral, pentagons,
etc).
Subdivision meshes are created by passing
`RTC_GEOMETRY_TYPE_SUBDIVISION` to the `rtcNewGeometry` function.
Various buffers need to be set by the application to set up the
subdivision mesh. See `rtcSetGeometryBuffer` and
`rtcSetSharedGeometryBuffer` for more details on how to set buffers.
The face buffer (`RTC_BUFFER_TYPE_FACE` type and `RTC_FORMAT_UINT`
format) contains the number of edges/indices of each face (3 to 15),
and the number of faces is inferred from the size of this buffer. The
index buffer (`RTC_BUFFER_TYPE_INDEX` type) contains multiple (3 to 15)
32-bit vertex indices (`RTC_FORMAT_UINT` format) for each face, and the
number of edges is inferred from the size of this buffer. The vertex
buffer (`RTC_BUFFER_TYPE_VERTEX` type) stores an array of single
precision `x`, `y`, `z` floating point coordinates (`RTC_FORMAT_FLOAT3`
format), and the number of vertices is inferred from the size of this
buffer.
Optionally, the application may set additional index buffers using
different buffer slots if multiple topologies are required for
face-varying interpolation. The standard vertex buffers
(`RTC_BUFFER_TYPE_VERTEX`) are always bound to the geometry topology
(topology 0) thus use `RTC_BUFFER_TYPE_INDEX` with buffer slot 0. User
vertex data interpolation may use different topologies as described
later.
Optionally, the application can set up the hole buffer
(`RTC_BUFFER_TYPE_HOLE`) which contains an array of 32-bit indices
(`RTC_FORMAT_UINT` format) of faces that should be considered
non-existing in all topologies. The number of holes is inferred from
the size of this buffer.
Optionally, the application can fill the level buffer
(`RTC_BUFFER_TYPE_LEVEL`) with a tessellation rate for each of the
edges of each face. This buffer must have the same size as the index
buffer. The tessellation level is a positive floating point value
(`RTC_FORMAT_FLOAT` format) that specifies how many quads along the
edge should be generated during tessellation. If no level buffer is
specified, a level of 1 is used. The maximally supported edge level is
4096, and larger levels are clamped to that value. Note that edges may
be shared between (typically 2) faces. To guarantee a watertight
tessellation, the level of these shared edges should be identical. A
uniform tessellation rate for an entire subdivision mesh can be set by
using the `rtcSetGeometryTessellationRate` function. The existence of a
level buffer has precedence over the uniform tessellation rate.
Optionally, the application can fill the sparse edge crease buffers to
make edges appear sharper. The edge crease index buffer
(`RTC_BUFFER_TYPE_EDGE_CREASE_INDEX`) contains an array of pairs of
32-bit vertex indices (`RTC_FORMAT_UINT2` format) that specify
unoriented edges in the geometry topology. The edge crease weight
buffer (`RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT`) stores for each of these
crease edges a positive floating point weight (`RTC_FORMAT_FLOAT`
format). The number of edge creases is inferred from the size of these
buffers, which has to be identical. The larger a weight, the sharper
the edge. Specifying a weight of infinity is supported and marks an
edge as infinitely sharp. Storing an edge multiple times with the same
crease weight is allowed, but has lower performance. Storing an edge
multiple times with different crease weights results in undefined
behavior. For a stored edge (i,j), the reverse direction edges (j,i) do
not have to be stored, as both are considered the same unoriented edge.
Edge crease features are shared between all topologies.
Optionally, the application can fill the sparse vertex crease buffers
to make vertices appear sharper. The vertex crease index buffer
(`RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX`), contains an array of 32-bit
vertex indices (`RTC_FORMAT_UINT` format) to specify a set of vertices
from the geometry topology. The vertex crease weight buffer
(`RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT`) specifies for each of these
vertices a positive floating point weight (`RTC_FORMAT_FLOAT` format).
The number of vertex creases is inferred from the size of these
buffers, and has to be identical. The larger a weight, the sharper the
vertex. Specifying a weight of infinity is supported and makes the
vertex infinitely sharp. Storing a vertex multiple times with the same
crease weight is allowed, but has lower performance. Storing a vertex
multiple times with different crease weights results in undefined
behavior. Vertex crease features are shared between all topologies.
Subdivision modes can be used to force linear interpolation for parts
of the subdivision mesh; see `rtcSetGeometrySubdivisionMode` for more
details.
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` call. Then a vertex
buffer for each time step can be set using different buffer slots, and
all these buffers have to have the same stride and size.
Also see tutorial [Subdivision Geometry] for an example of how to
create subdivision surfaces.
#### Parametrization
The parametrization for subdivision faces is different for
quadrilaterals and non-quadrilateral faces.
The parametrization of a quadrilateral face uses the first vertex `p0`
as base point, and the vector `p1 - p0` as u-direction and `p3 - p0` as
v-direction.
The parametrization for all other face types (with number of vertices
not equal 4), have a special parametrization where the subpatch ID `n`
(of the `n`-th quadrilateral that would be obtained by a single
subdivision step) and the local hit location inside this quadrilateral
are encoded in the UV coordinates. The following code extracts the
sub-patch ID `i` and local UVs of this subpatch:
unsigned int l = floorf(0.5f*U);
unsigned int h = floorf(0.5f*V);
unsigned int i = 4*h+l;
float u = 2.0f*fracf(0.5f*U)-0.5f;
float v = 2.0f*fracf(0.5f*V)-0.5f;
This encoding allows local subpatch UVs to be in the range `[-0.5,1.5[`
thus negative subpatch UVs can be passed to `rtcInterpolate` to sample
subpatches slightly out of bounds. This can be useful to calculate
derivatives using finite differences if required. The encoding further
has the property that one can just move the value `u` (or `v`) on a
subpatch by adding `du` (or `dv`) to the special UV encoding as long as
it does not fall out of the `[-0.5,1.5[` range.
To smoothly interpolate vertex attributes over the subdivision surface
we recommend using the `rtcInterpolate` function, which will apply the
standard subdivision rules for interpolation and automatically takes
care of the special UV encoding for non-quadrilaterals.
#### Face-Varying Data
Face-varying interpolation is supported through multiple topologies per
subdivision mesh and binding such topologies to vertex attribute
buffers to interpolate. This way, texture coordinates may use a
different topology with additional boundaries to construct separate UV
regions inside one subdivision mesh.
Each such topology `i` has a separate index buffer (specified using
`RTC_BUFFER_TYPE_INDEX` with buffer slot `i`) and separate subdivision
mode that can be set using `rtcSetGeometrySubdivisionMode`. A vertex
attribute buffer `RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE` bound to a buffer
slot `j` can be assigned to use a topology for interpolation using the
`rtcSetGeometryVertexAttributeTopology` call.
The face buffer (`RTC_BUFFER_TYPE_FACE` type) is shared between all
topologies, which means that the `n`-th primitive always has the same
number of vertices (e.g. being a triangle or a quad) for each topology.
However, the indices of the topologies themselves may be different.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry]
RTC\_GEOMETRY\_TYPE\_CURVE
--------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE -
flat curve geometry with linear basis
RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE -
flat curve geometry with cubic Bézier basis
RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE -
flat curve geometry with cubic B-spline basis
RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE -
flat curve geometry with cubic Hermite basis
RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE -
flat curve geometry with Catmull-Rom basis
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE -
flat normal oriented curve geometry with cubic Bézier basis
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE -
flat normal oriented curve geometry with cubic B-spline basis
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE -
flat normal oriented curve geometry with cubic Hermite basis
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE -
flat normal oriented curve geometry with Catmull-Rom basis
RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE -
capped cone curve geometry with linear basis - discontinuous at edge boundaries
RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE -
capped cone curve geometry with linear basis and spherical ending
RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE -
swept surface curve geometry with cubic Bézier basis
RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE -
swept surface curve geometry with cubic B-spline basis
RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE -
swept surface curve geometry with cubic Hermite basis
RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE -
swept surface curve geometry with Catmull-Rom basis
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE);
#### DESCRIPTION {#description}
Curves with per vertex radii are supported with linear, cubic Bézier,
cubic B-spline, and cubic Hermite bases. Such curve geometries are
created by passing `RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE`,
`RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_BSPLINE_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_HERMITE_CURVE`,
`RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_CATMULL_ROM_CURVE`,
`RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE`,
`RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE`, or
`RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE` to the `rtcNewGeometry`
function. The curve indices can be specified through an index buffer
(`RTC_BUFFER_TYPE_INDEX`) and the curve vertices through a vertex
buffer (`RTC_BUFFER_TYPE_VERTEX`). For the Hermite basis a tangent
buffer (`RTC_BUFFER_TYPE_TANGENT`), normal oriented curves a normal
buffer (`RTC_BUFFER_TYPE_NORMAL`), and for normal oriented Hermite
curves a normal derivative buffer (`RTC_BUFFER_TYPE_NORMAL_DERIVATIVE`)
has to get specified additionally. See `rtcSetGeometryBuffer` and
`rtcSetSharedGeometryBuffer` for more details on how to set buffers.
The index buffer contains an array of 32-bit indices (`RTC_FORMAT_UINT`
format), each pointing to the first control vertex in the vertex
buffer, but also to the first tangent in the tangent buffer, and first
normal in the normal buffer if these buffers are present.
The vertex buffer stores each control vertex in the form of a single
precision position and radius stored in (`x`, `y`, `z`, `r`) order in
memory (`RTC_FORMAT_FLOAT4` format). The number of vertices is inferred
from the size of this buffer. The radii may be smaller than zero but
the interpolated radii should always be greater or equal to zero.
Similarly, the tangent buffer stores the derivative of each control
vertex (`x`, `y`, `z`, `r` order and `RTC_FORMAT_FLOAT4` format) and
the normal buffer stores a single precision normal per control vertex
(`x`, `y`, `z` order and `RTC_FORMAT_FLOAT3` format).
##### Linear Basis
For the linear basis 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. When
constructing hair strands in this basis, the end-point can be shared
with the start of the next line segment.
For the linear basis the user optionally can provide a flags buffer of
type `RTC_BUFFER_TYPE_FLAGS` which contains bytes that encode if the
left neighbor segment (`RTC_CURVE_FLAG_NEIGHBOR_LEFT` flag) and/or
right neighbor segment (`RTC_CURVE_FLAG_NEIGHBOR_RIGHT` flags) exist
(see [RTCCurveFlags]). If this buffer is not set, than the left/right
neighbor bits are automatically calculated base on the index buffer
(left segment exists if segment(id-1)+1 == segment(id) and right
segment exists if segment(id+1)-1 == segment(id)).
A left neighbor segment is assumed to end at the start vertex of the
current segment, and to start at the previous vertex in the vertex
buffer. Similarly, the right neighbor segment is assumed to start at
the end vertex of the current segment, and to end at the next vertex in
the vertex buffer.
Only when the left and right bits are properly specified the current
segment can properly attach to the left and/or right neighbor,
otherwise the touching area may not get rendered properly.
##### Bézier Basis
For the cubic Bézier basis the indices point to the first of 4
consecutive control points in the vertex buffer. These control points
use the cubic Bézier basis, where 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.
##### B-spline Basis
For the cubic B-spline basis the indices point to the first of 4
consecutive control points in the vertex buffer. These control points
make up a cardinal cubic B-spline (implicit equidistant knot vector).
This basis is not interpolating, thus the curve does in general not go
through any of the control points directly. A big advantage of this
basis is that 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 makes this basis a good
choice to construct continuous multi-segment curves, as memory
consumption can be kept minimal.
##### Hermite Basis
For the cubic Hermite 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. These two points and two tangents make
up a cubic Hermite curve. 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. Different versions of Catmull-Rom splines can be easily
constructed using the Hermite basis, by calculating a proper tangent
buffer from the control points.
##### Catmull-Rom Basis
For the Catmull-Rom basis the indices point to the first of 4
consecutive control points in the vertex buffer. This basis goes
through p1 and p2, with tangents (p2-p0)/2 and (p3-p1)/2.
##### Flat Curves
The `RTC_GEOMETRY_TYPE_FLAT_*` flat mode is a fast mode designed to
render distant hair. In this mode the curve is rendered as a connected
sequence of ray facing quads. Individual quads are considered to have
subpixel size, and zooming onto the curve might show geometric
artifacts. The number of quads to subdivide into can be specified
through the `rtcSetGeometryTessellationRate` function. By default the
tessellation rate is 4.
##### Normal Oriented Curves
The `RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_*` mode is a mode designed to
render blades of grass. In this mode a vertex spline has to get
specified as for the previous modes, but additionally a normal spline
is required. If the Hermite basis is used, the `RTC_BUFFER_TYPE_NORMAL`
and `RTC_BUFFER_TYPE_NORMAL_DERIVATIVE` buffers have both to be set.
The curve is rendered as a flat band whose center approximately follows
the provided vertex spline, whose half width approximately follows the
provided radius spline, and whose normal orientation approximately
follows the provided normal spline.
To intersect the normal oriented curve, we perform a newton-raphson
style intersection of a ray with a tensor product surface of a linear
basis (perpendicular to the curve) and cubic Bézier basis (along the
curve). We use a guide curve and its derivatives to construct the
control points of that surface. The guide curve is defined by a sweep
surface defined by sweeping a line centered at the vertex spline
location along the curve. At each parameter value the half width of the
line matches the radius spline, and the direction matches the cross
product of the normal from the normal spline and tangent of the vertex
spline. Note that this construction does not work when the provided
normals are parallel to the curve direction. For this reason the
provided normals should best be kept as perpendicular to the curve
direction as possible. We further assume second order derivatives of
the center curve to be zero for this construction, as otherwise very
large curvatures occurring in corner cases, can thicken the constructed
curve significantly.
##### Round Curves
In the `RTC_GEOMETRY_TYPE_ROUND_*` round mode, a real geometric surface
is rendered for the curve, which is more expensive but allows closeup
views.
For the linear basis the round mode renders a cone that tangentially
touches a start-sphere and end-sphere. The start sphere is rendered
when no previous segments is indicated by the neighbor bits. The end
sphere is always rendered but parts that lie inside the next segment
are clipped away (if that next segment exists). This way a curve is
closed on both ends and the interior will render properly as long as
only neighboring segments penetrate into a segment. For this to work
properly it is important that the flags buffer is properly populated
with neighbor information.
For the cubic polynomial bases, the round mode renders a sweep surface
by sweeping a varying radius circle tangential along the curve. As a
limitation, the radius of the curve has to be smaller than the
curvature radius of the curve at each location on the curve.
The intersection with the curve segment stores the parametric hit
location along the curve segment as u-coordinate (range 0 to +1).
For flat curves, the v-coordinate is set to the normalized distance in
the range -1 to +1. For normal oriented curves the v-coordinate is in
the range 0 to 1. For the linear basis and in round mode the
v-coordinate is set to zero.
In flat mode, the geometry normal `Ng` is set to the tangent of the
curve at the hit location. In round mode and for normal oriented
curves, the geometry normal `Ng` is set to the non-normalized geometric
normal of the surface.
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` call. Then a vertex
buffer for each time step can be set using different buffer slots, and
all these buffers must have the same stride and size. For the Hermite
basis also a tangent buffer has to be set for each time step and for
normal oriented curves a normal buffer has to get specified for each
time step.
Also see tutorials [Hair] and [Curves] for examples of how to
create and use curve geometries.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [RTCCurveFlags]
RTC\_GEOMETRY\_TYPE\_POINT
--------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_SPHERE_POINT -
point geometry spheres
RTC_GEOMETRY_TYPE_DISC_POINT -
point geometry with ray-oriented discs
RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT -
point geometry with normal-oriented discs
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_SPHERE_POINT);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_DISC_POINT);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT);
#### DESCRIPTION {#description}
Points with per vertex radii are supported with sphere, ray-oriented
discs, and normal-oriented discs geometric representations. Such point
geometries are created by passing `RTC_GEOMETRY_TYPE_SPHERE_POINT`,
`RTC_GEOMETRY_TYPE_DISC_POINT`, or
`RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT` to the `rtcNewGeometry`
function. The point vertices can be specified t through a vertex buffer
(`RTC_BUFFER_TYPE_VERTEX`). For the normal oriented discs a normal
buffer (`RTC_BUFFER_TYPE_NORMAL`) has to get specified additionally.
See `rtcSetGeometryBuffer` and `rtcSetSharedGeometryBuffer` for more
details on how to set buffers.
The vertex buffer stores each control vertex in the form of a single
precision position and radius stored in (`x`, `y`, `z`, `r`) order in
memory (`RTC_FORMAT_FLOAT4` format). The number of vertices is inferred
from the size of this buffer. Similarly, the normal buffer stores a
single precision normal per control vertex (`x`, `y`, `z` order and
`RTC_FORMAT_FLOAT3` format).
In the `RTC_GEOMETRY_TYPE_SPHERE_POINT` mode, a real geometric surface
is rendered for the curve, which is more expensive but allows closeup
views.
The `RTC_GEOMETRY_TYPE_DISC_POINT` flat mode is a fast mode designed to
render distant points. In this mode the point is rendered as a ray
facing disc.
The `RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT` mode is a mode designed as
a midpoint geometrically between ray facing discs and spheres. In this
mode the point is rendered as a normal oriented disc.
For all point types, only the hit distance and geometry normal is
returned as hit information, u and v are set to zero.
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` call. Then a vertex
buffer for each time step can be set using different buffer slots, and
all these buffers must have the same stride and size.
Also see tutorial [Points] for an example of how to create and use
point geometries.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry]
RTC\_GEOMETRY\_TYPE\_USER
-------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_USER - user geometry type
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry geometry =
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);
#### DESCRIPTION {#description}
User-defined geometries contain a number of user-defined primitives,
just like triangle meshes contain multiple triangles. The shape of the
user-defined primitives is specified through registered callback
functions, which enable extending Embree with arbitrary types of
primitives.
User-defined geometries are created by passing `RTC_GEOMETRY_TYPE_USER`
to the `rtcNewGeometry` function call. One has to set the number of
primitives (see `rtcSetGeometryUserPrimitiveCount`), a user data
pointer (see `rtcSetGeometryUserData`), a bounding function closure
(see `rtcSetGeometryBoundsFunction`), as well as user-defined intersect
(see `rtcSetGeometryIntersectFunction`) and occluded (see
`rtcSetGeometryOccludedFunction`) callback functions. The bounding
function is used to query the bounds of all time steps of a user
primitive, while the intersect and occluded callback functions are
called to intersect the primitive with a ray. The user data pointer is
passed to each callback invocation and can be used to point to the
application's representation of the user geometry.
The creation of a user geometry typically looks the following:
RTCGeometry geometry = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);
rtcSetGeometryUserPrimitiveCount(geometry, numPrimitives);
rtcSetGeometryUserData(geometry, userGeometryRepresentation);
rtcSetGeometryBoundsFunction(geometry, boundsFunction);
rtcSetGeometryIntersectFunction(geometry, intersectFunction);
rtcSetGeometryOccludedFunction(geometry, occludedFunction);
Please have a look at the `rtcSetGeometryBoundsFunction`,
`rtcSetGeometryIntersectFunction`, and `rtcSetGeometryOccludedFunction`
functions on the implementation of the callback functions.
Primitives of a user geometry are ignored during rendering when their
bounds are empty, thus bounds have lower\>upper in at least one
dimension.
See tutorial [User Geometry] for an example of how to use the
user-defined geometries.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcSetGeometryUserPrimitiveCount],
[rtcSetGeometryUserData], [rtcSetGeometryBoundsFunction],
[rtcSetGeometryIntersectFunction], [rtcSetGeometryOccludedFunction]
RTC\_GEOMETRY\_TYPE\_INSTANCE
-----------------------------
#### NAME {#name}
RTC_GEOMETRY_TYPE_INSTANCE - instance geometry type
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCGeometry geometry =
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_INSTANCE);
#### DESCRIPTION {#description}
Embree supports instancing of scenes using affine transformations (3×3
matrix plus translation). As the instanced scene is stored only a
single time, even if instanced to multiple locations, this feature can
be used to create very complex scenes with small memory footprint.
Embree supports both single-level instancing and multi-level
instancing. The maximum instance nesting depth is
`RTC_MAX_INSTANCE_LEVEL_COUNT`; it can be configured at compile-time
using the constant `EMBREE_MAX_INSTANCE_LEVEL_COUNT`. Users should
adapt this constant to their needs: instances nested any deeper are
silently ignored in release mode, and cause assertions in debug mode.
Instances are created by passing `RTC_GEOMETRY_TYPE_INSTANCE` to the
`rtcNewGeometry` function call. The instanced scene can be set using
the `rtcSetGeometryInstancedScene` call, and the affine transformation
can be set using the `rtcSetGeometryTransform` function.
Please note that `rtcCommitScene` on the instanced scene should be
called first, followed by `rtcCommitGeometry` on the instance, followed
by `rtcCommitScene` for the top-level scene containing the instance.
If a ray hits the instance, the `geomID` and `primID` members of the
hit are set to the geometry ID and primitive ID of the hit primitive in
the instanced scene, and the `instID` member of the hit is set to the
geometry ID of the instance in the top-level scene.
The instancing scheme can also be implemented using user geometries. To
achieve this, the user geometry code should set the `instID` member of
the intersection context to the geometry ID of the instance, then trace
the transformed ray, and finally set the `instID` field of the
intersection context again to -1. The `instID` field is copied
automatically by each primitive intersector into the `instID` field of
the hit structure when the primitive is hit. See the [User Geometry]
tutorial for an example.
For multi-segment motion blur, the number of time steps must be first
specified using the `rtcSetGeometryTimeStepCount` function. Then a
transformation for each time step can be specified using the
`rtcSetGeometryTransform` function.
See tutorials [Instanced Geometry] and [Multi Level Instancing] for
examples of how to use instances.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcSetGeometryInstancedScene],
[rtcSetGeometryTransform]
RTCCurveFlags
-------------
#### NAME {#name}
RTCCurveFlags - per segment flags for curve geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
enum RTCCurveFlags { RTC\_CURVE\_FLAG\_NEIGHBOR\_LEFT = (1 \<\< 0),
RTC\_CURVE\_FLAG\_NEIGHBOR\_RIGHT = (1 \<\< 1) };
#### DESCRIPTION {#description}
The RTCCurveFlags type is used for linear curves to determine if the
left and/or right neighbor segment exist. Therefore one attaches a
buffer of type RTC\_BUFFER\_TYPE\_FLAGS to the curve geometry which
stores an individual byte per curve segment.
If the RTC\_CURVE\_FLAG\_NEIGHBOR\_LEFT flag in that byte is enabled
for a curve segment, then the left segment exists (which starts one
vertex before the start vertex of the current curve) and the current
segment is rendered to properly attach to that segment.
If the RTC\_CURVE\_FLAG\_NEIGHBOR\_RIGHT flag in that byte is enabled
for a curve segment, then the right segment exists (which ends one
vertex after the end vertex of the current curve) and the current
segment is rendered to properly attach to that segment.
When not properly specifying left and right flags for linear curves,
the rendering at the ending of these curves may not look correct, in
particular when round linear curves are viewed from the inside.
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_CURVE]
rtcRetainGeometry
-----------------
#### NAME {#name}
rtcRetainGeometry - increments the geometry reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcRetainGeometry(RTCGeometry geometry);
#### DESCRIPTION {#description}
Geometry objects are reference counted. The `rtcRetainGeometry`
function increments the reference count of the passed geometry object
(`geometry` argument). This function together with `rtcReleaseGeometry`
allows to use the internal reference counting in a C++ wrapper class to
handle the ownership of the object.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcReleaseGeometry]
rtcReleaseGeometry
------------------
#### NAME {#name}
rtcReleaseGeometry - decrements the geometry reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcReleaseGeometry(RTCGeometry geometry);
#### DESCRIPTION {#description}
Geometry objects are reference counted. The `rtcReleaseGeometry`
function decrements the reference count of the passed geometry object
(`geometry` argument). When the reference count falls to 0, the
geometry gets destroyed.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcRetainGeometry]
rtcCommitGeometry
-----------------
#### NAME {#name}
rtcCommitGeometry - commits geometry changes
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcCommitGeometry(RTCGeometry geometry);
#### DESCRIPTION {#description}
The `rtcCommitGeometry` function is used to commit all geometry changes
performed to a geometry (`geometry` parameter). After a geometry gets
modified, this function must be called to properly update the internal
state of the geometry to perform interpolations using `rtcInterpolate`
or to commit a scene containing the geometry using `rtcCommitScene`.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcInterpolate], [rtcCommitScene]
rtcEnableGeometry
-----------------
#### NAME {#name}
rtcEnableGeometry - enables the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcEnableGeometry(RTCGeometry geometry);
#### DESCRIPTION {#description}
The `rtcEnableGeometry` function enables the specified geometry
(`geometry` argument). Only enabled geometries are rendered. Each
geometry is enabled by default at construction time.
After enabling a geometry, the scene containing that geometry must be
committed using `rtcCommitScene` for the change to have effect.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcDisableGeometry], [rtcCommitScene]
rtcDisableGeometry
------------------
#### NAME {#name}
rtcDisableGeometry - disables the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcDisableGeometry(RTCGeometry geometry);
#### DESCRIPTION {#description}
The `rtcDisableGeometry` function disables the specified geometry
(`geometry` argument). A disabled geometry is not rendered. Each
geometry is enabled by default at construction time.
After disabling a geometry, the scene containing that geometry must be
committed using `rtcCommitScene` for the change to have effect.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcEnableGeometry], [rtcCommitScene]
rtcSetGeometryTimeStepCount
---------------------------
#### NAME {#name}
rtcSetGeometryTimeStepCount - sets the number of time steps of the
geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryTimeStepCount(
RTCGeometry geometry,
unsigned int timeStepCount
);
#### DESCRIPTION {#description}
The `rtcSetGeometryTimeStepCount` function sets the number of time
steps for multi-segment motion blur (`timeStepCount` parameter) of the
specified geometry (`geometry` parameter).
For triangle meshes (`RTC_GEOMETRY_TYPE_TRIANGLE`), quad meshes
(`RTC_GEOMETRY_TYPE_QUAD`), curves (`RTC_GEOMETRY_TYPE_CURVE`), points
(`RTC_GEOMETRY_TYPE_POINT`), and subdivision geometries
(`RTC_GEOMETRY_TYPE_SUBDIVISION`), the number of time steps directly
corresponds to the number of vertex buffer slots available
(`RTC_BUFFER_TYPE_VERTEX` buffer type). For these geometries, one
vertex buffer per time step must be specified when creating
multi-segment motion blur geometries.
For instance geometries (`RTC_GEOMETRY_TYPE_INSTANCE`), a
transformation must be specified for each time step (see
`rtcSetGeometryTransform`).
For user geometries, the registered bounding callback function must
provide a bounding box per primitive and time step, and the
intersection and occlusion callback functions should properly intersect
the motion-blurred geometry at the ray time.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcSetGeometryTimeRange]
rtcSetGeometryTimeRange
-----------------------
#### NAME {#name}
rtcSetGeometryTimeRange - sets the time range for a motion blur geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryTimeRange(
RTCGeometry geometry,
float startTime,
float endTime
);
#### DESCRIPTION {#description}
The `rtcSetGeometryTimeRange` function sets a time range which defines
the start (and end time) of the first (and last) time step of a motion
blur geometry. The time range is defined relative to the camera shutter
interval [0,1] but it can be arbitrary. Thus the startTime can be
smaller, equal, or larger 0, indicating a geometry whose animation
definition start before, at, or after the camera shutter opens. Similar
the endTime can be smaller, equal, or larger than 1, indicating a
geometry whose animation definition ends after, at, or before the
camera shutter closes. The startTime has to be smaller or equal to the
endTime.
The default time range when this function is not called is the entire
camera shutter [0,1]. For best performance at most one time segment
of the piece wise linear definition of the motion should fall outside
the shutter window to the left and to the right. Thus do not set the
startTime or endTime too far outside the [0,1] interval for best
performance.
This time range feature will also allow geometries to appear and
disappear during the camera shutter time if the specified time range is
a sub range of [0,1].
Please also have a look at the `rtcSetGeometryTimeStepCount` function
to see how to define the time steps for the specified time range.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryTimeStepCount]
rtcSetGeometryVertexAttributeCount
----------------------------------
#### NAME {#name}
rtcSetGeometryVertexAttributeCount - sets the number of vertex
attributes of the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryVertexAttributeCount(
RTCGeometry geometry,
unsigned int vertexAttributeCount
);
#### DESCRIPTION {#description}
The `rtcSetGeometryVertexAttributeCount` function sets the number of
slots (`vertexAttributeCount` parameter) for vertex attribute buffers
(`RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE`) that can be used for the specified
geometry (`geometry` parameter).
This function is supported only for triangle meshes
(`RTC_GEOMETRY_TYPE_TRIANGLE`), quad meshes (`RTC_GEOMETRY_TYPE_QUAD`),
curves (`RTC_GEOMETRY_TYPE_CURVE`), points (`RTC_GEOMETRY_TYPE_POINT`),
and subdivision geometries (`RTC_GEOMETRY_TYPE_SUBDIVISION`).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [RTCBufferType]
rtcSetGeometryMask
------------------
#### NAME {#name}
rtcSetGeometryMask - sets the geometry mask
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryMask(
RTCGeometry geometry,
unsigned int mask
);
#### DESCRIPTION {#description}
The `rtcSetGeometryMask` function sets a 32-bit geometry mask (`mask`
argument) for the specified geometry (`geometry` argument).
This geometry mask is used together with the ray mask stored inside the
`mask` field of the ray. The primitives of the geometry are hit by the
ray only if the bitwise `and` operation of the geometry mask with the
ray mask is not 0. This feature can be used to disable selected
geometries for specifically tagged rays, e.g. to disable shadow casting
for certain geometries.
Ray masks are disabled in Embree by default at compile time, and can be
enabled through the `EMBREE_RAY_MASK` parameter in CMake. One can query
whether ray masks are enabled by querying the
`RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED` device property using
`rtcGetDeviceProperty`.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTCRay], [rtcGetDeviceProperty]
rtcSetGeometryBuildQuality
--------------------------
#### NAME {#name}
rtcSetGeometryBuildQuality - sets the build quality for the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryBuildQuality(
RTCGeometry geometry,
enum RTCBuildQuality quality
);
#### DESCRIPTION {#description}
The `rtcSetGeometryBuildQuality` function sets the build quality
(`quality` argument) for the specified geometry (`geometry` argument).
The per-geometry build quality is only a hint and may be ignored.
Embree currently uses the per-geometry build quality when the scene
build quality is set to `RTC_BUILD_QUALITY_LOW`. In this mode a
two-level acceleration structure is build, and geometries build a
separate acceleration structure using the geometry build quality. The
per-geometry build quality can be one of:
- `RTC_BUILD_QUALITY_LOW`: Creates lower quality data structures,
e.g. for dynamic scenes.
- `RTC_BUILD_QUALITY_MEDIUM`: Default build quality for most usages.
Gives a good compromise between build and render performance.
- `RTC_BUILD_QUALITY_HIGH`: Creates higher quality data structures
for final-frame rendering. Enables a spatial split builder for
certain primitive types.
- `RTC_BUILD_QUALITY_REFIT`: Uses a BVH refitting approach when
changing only the vertex buffer.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetSceneBuildQuality]
rtcSetGeometryBuffer
--------------------
#### NAME {#name}
rtcSetGeometryBuffer - assigns a view of a buffer to the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryBuffer(
RTCGeometry geometry,
enum RTCBufferType type,
unsigned int slot,
enum RTCFormat format,
RTCBuffer buffer,
size_t byteOffset,
size_t byteStride,
size_t itemCount
);
#### DESCRIPTION {#description}
The `rtcSetGeometryBuffer` function binds a view of a buffer object
(`buffer` argument) to a geometry buffer type and slot (`type` and
`slot` argument) of the specified geometry (`geometry` argument).
One can specify the start of the first buffer element in bytes
(`byteOffset` argument), the byte stride between individual buffer
elements (`byteStride` argument), the format of the buffer elements
(`format` argument), and the number of elements to bind (`itemCount`).
The start address (`byteOffset` argument) and stride (`byteStride`
argument) must be both aligned to 4 bytes, otherwise the
`rtcSetGeometryBuffer` function will fail.
After successful completion of this function, the geometry will hold a
reference to the buffer object.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetSharedGeometryBuffer], [rtcSetNewGeometryBuffer]
rtcSetSharedGeometryBuffer
--------------------------
#### NAME {#name}
rtcSetSharedGeometryBuffer - assigns a view of a shared data buffer
to a geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetSharedGeometryBuffer(
RTCGeometry geometry,
enum RTCBufferType type,
unsigned int slot,
enum RTCFormat format,
const void* ptr,
size_t byteOffset,
size_t byteStride,
size_t itemCount
);
#### DESCRIPTION {#description}
The `rtcSetSharedGeometryBuffer` function binds a view of a shared
user-managed data buffer (`ptr` argument) to a geometry buffer type and
slot (`type` and `slot` argument) of the specified geometry (`geometry`
argument).
One can specify the start of the first buffer element in bytes
(`byteOffset` argument), the byte stride between individual buffer
elements (`byteStride` argument), the format of the buffer elements
(`format` argument), and the number of elements to bind (`itemCount`).
The start address (`byteOffset` argument) and stride (`byteStride`
argument) must be both aligned to 4 bytes; otherwise the
`rtcSetSharedGeometryBuffer` function will fail.
When the buffer will be used as a vertex buffer
(`RTC_BUFFER_TYPE_VERTEX` and `RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE`), the
last buffer element must be readable using 16-byte SSE load
instructions, thus padding the last element is required for certain
layouts. E.g. a standard `float3` vertex buffer layout should add
storage for at least one more float to the end of the buffer.
The buffer data must remain valid for as long as the buffer may be
used, and the user is responsible for freeing the buffer data when no
longer required.
Sharing buffers can significantly reduce the memory required by the
application, thus we recommend using this feature. When enabling the
`RTC_SCENE_FLAG_COMPACT` scene flag, the spatial index structures index
into the vertex buffer, resulting in even higher memory savings.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryBuffer], [rtcSetNewGeometryBuffer]
rtcSetNewGeometryBuffer
-----------------------
#### NAME {#name}
rtcSetNewGeometryBuffer - creates and assigns a new data buffer to
the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void* rtcSetNewGeometryBuffer(
RTCGeometry geometry,
enum RTCBufferType type,
unsigned int slot,
enum RTCFormat format,
size_t byteStride,
size_t itemCount
);
#### DESCRIPTION {#description}
The `rtcSetNewGeometryBuffer` function creates a new data buffer of
specified format (`format` argument), byte stride (`byteStride`
argument), and number of items (`itemCount` argument), and assigns it
to a geometry buffer slot (`type` and `slot` argument) of the specified
geometry (`geometry` argument). The buffer data is managed internally
and automatically freed when the geometry is destroyed.
The byte stride (`byteStride` argument) must be aligned to 4 bytes;
otherwise the `rtcSetNewGeometryBuffer` function will fail.
The allocated buffer will be automatically over-allocated slightly when
used as a vertex buffer, where a requirement is that each buffer
element should be readable using 16-byte SSE load instructions.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryBuffer], [rtcSetSharedGeometryBuffer]
RTCFormat
---------
#### NAME {#name}
RTCFormat - specifies format of data in buffers
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore_ray.h>
enum RTCFormat
{
RTC_FORMAT_UINT,
RTC_FORMAT_UINT2,
RTC_FORMAT_UINT3,
RTC_FORMAT_UINT4,
RTC_FORMAT_FLOAT,
RTC_FORMAT_FLOAT2,
RTC_FORMAT_FLOAT3,
RTC_FORMAT_FLOAT4,
RTC_FORMAT_FLOAT5,
RTC_FORMAT_FLOAT6,
RTC_FORMAT_FLOAT7,
RTC_FORMAT_FLOAT8,
RTC_FORMAT_FLOAT9,
RTC_FORMAT_FLOAT10,
RTC_FORMAT_FLOAT11,
RTC_FORMAT_FLOAT12,
RTC_FORMAT_FLOAT13,
RTC_FORMAT_FLOAT14,
RTC_FORMAT_FLOAT15,
RTC_FORMAT_FLOAT16,
RTC_FORMAT_FLOAT3X4_ROW_MAJOR,
RTC_FORMAT_FLOAT4X4_ROW_MAJOR,
RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR,
RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR,
RTC_FORMAT_GRID,
};
#### DESCRIPTION {#description}
The `RTFormat` structure defines the data format stored in data buffers
provided to Embree using the [rtcSetGeometryBuffer],
[rtcSetSharedGeometryBuffer], and [rtcSetNewGeometryBuffer] API
calls.
The `RTC_FORMAT_UINT/2/3/4` format are used to specify that data
buffers store unsigned integers, or unsigned integer vectors of size
2,3 or 4. This format has typically to get used when specifying index
buffers, e.g. `RTC_FORMAT_UINT3` for triangle meshes.
The `RTC_FORMAT_FLOAT/2/3/4...` format are used to specify that data
buffers store single precision floating point values, or vectors there
of (size 2,3,4, etc.). This format is typcally used to specify to
format of vertex buffers, e.g. the `RTC_FORMAT_FLOAT3` type for vertex
buffers of triangle meshes.
The `RTC_FORMAT_FLOAT3X4_ROW_MAJOR` and
`RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR` formats, specify a 3x4 floating
point matrix layed out either row major or column major. The
`RTC_FORMAT_FLOAT4X4_ROW_MAJOR` and `RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR`
formats, specify a 4x4 floating point matrix layed out either row major
or column major. These matrix formats are used in the
[rtcSetGeometryTransform] function in order to set a transformation
matrix for geometries.
The `RTC_FORMAT_GRID` is a special data format used to specify grid
primitives of layout RTCGrid when creating grid geometries (see
[RTC\_GEOMETRY\_TYPE\_GRID]).
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[rtcSetGeometryBuffer], [rtcSetSharedGeometryBuffer],
[rtcSetNewGeometryBuffer], [rtcSetGeometryTransform]
RTCBufferType
-------------
#### NAME {#name}
RTCFormat - specifies format of data in buffers
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore_ray.h>
enum RTCBufferType
{
RTC_BUFFER_TYPE_INDEX = 0,
RTC_BUFFER_TYPE_VERTEX = 1,
RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE = 2,
RTC_BUFFER_TYPE_NORMAL = 3,
RTC_BUFFER_TYPE_TANGENT = 4,
RTC_BUFFER_TYPE_NORMAL_DERIVATIVE = 5,
RTC_BUFFER_TYPE_GRID = 8,
RTC_BUFFER_TYPE_FACE = 16,
RTC_BUFFER_TYPE_LEVEL = 17,
RTC_BUFFER_TYPE_EDGE_CREASE_INDEX = 18,
RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT = 19,
RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX = 20,
RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT = 21,
RTC_BUFFER_TYPE_HOLE = 22,
RTC_BUFFER_TYPE_FLAGS = 32
};
#### DESCRIPTION {#description}
The `RTBufferType` structure defines slots to assign data buffers to
using the [rtcSetGeometryBuffer], [rtcSetSharedGeometryBuffer], and
[rtcSetNewGeometryBuffer] API calls.
For most geometry types the `RTC_BUFFER_TYPE_INDEX` slot is used to
assign an index buffer, while the `RTC_BUFFER_TYPE_VERTEX` is used to
assign the corresponding vertex buffer.
The `RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE` slot can get used to assign
arbitrary additional vertex data which can get interpolated using the
[rtcInterpolate] API call.
The `RTC_BUFFER_TYPE_NORMAL`, `RTC_BUFFER_TYPE_TANGENT`, and
`RTC_BUFFER_TYPE_NORMAL_DERIVATIVE` are special buffers required to
assign per vertex normals, tangents, and normal derivatives for some
curve types.
The `RTC_BUFFER_TYPE_GRID` buffer is used to assign the grid primitive
buffer for grid geometries (see [RTC\_GEOMETRY\_TYPE\_GRID]).
The `RTC_BUFFER_TYPE_FACE`, `RTC_BUFFER_TYPE_LEVEL`,
`RTC_BUFFER_TYPE_EDGE_CREASE_INDEX`,
`RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT`,
`RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX`,
`RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT`, and `RTC_BUFFER_TYPE_HOLE` are
special buffers required to create subdivision meshes (see
[RTC\_GEOMETRY\_TYPE\_SUBDIVISION]).
The `RTC_BUFFER_TYPE_FLAGS` can get used to add additional flag per
primitive of a geometry, and is currently only used for linear curves.
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[rtcSetGeometryBuffer], [rtcSetSharedGeometryBuffer],
[rtcSetNewGeometryBuffer]
rtcGetGeometryBufferData
------------------------
#### NAME {#name}
rtcGetGeometryBufferData - gets pointer to
the first buffer view element
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void* rtcGetGeometryBufferData(
RTCGeometry geometry,
enum RTCBufferType type,
unsigned int slot
);
#### DESCRIPTION {#description}
The `rtcGetGeometryBufferData` function returns a pointer to the first
element of the buffer view attached to the specified buffer type and
slot (`type` and `slot` argument) of the geometry (`geometry`
argument).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryBuffer], [rtcSetSharedGeometryBuffer],
[rtcSetNewGeometryBuffer]
rtcUpdateGeometryBuffer
-----------------------
#### NAME {#name}
rtcUpdateGeometryBuffer - marks a buffer view bound to the geometry
as modified
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcUpdateGeometryBuffer(
RTCGeometry geometry,
enum RTCBufferType type,
unsigned int slot
);
#### DESCRIPTION {#description}
The `rtcUpdateGeometryBuffer` function marks the buffer view bound to
the specified buffer type and slot (`type` and `slot` argument) of a
geometry (`geometry` argument) as modified.
If a data buffer is changed by the application, the
`rtcUpdateGeometryBuffer` call must be invoked for that buffer. Each
buffer view assigned to a buffer slot is initially marked as modified,
thus this function needs to be called only when doing buffer
modifications after the first `rtcCommitScene`.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewGeometry], [rtcCommitScene]
rtcSetGeometryIntersectFilterFunction
-------------------------------------
#### NAME {#name}
rtcSetGeometryIntersectFilterFunction - sets the intersection filter
for the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCFilterFunctionNArguments
{
int* valid;
void* geometryUserPtr;
const struct RTCIntersectContext* context;
struct RTCRayN* ray;
struct RTCHitN* hit;
unsigned int N;
};
typedef void (*RTCFilterFunctionN)(
const struct RTCFilterFunctionNArguments* args
);
void rtcSetGeometryIntersectFilterFunction(
RTCGeometry geometry,
RTCFilterFunctionN filter
);
#### DESCRIPTION {#description}
The `rtcSetGeometryIntersectFilterFunction` function registers an
intersection filter callback function (`filter` argument) for the
specified geometry (`geometry` argument).
Only a single callback function can be registered per geometry, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered intersection filter function is invoked for every hit
encountered during the `rtcIntersect`-type ray queries and can accept
or reject that hit. The feature can be used to define a silhouette for
a primitive and reject hits that are outside the silhouette. E.g. a
tree leaf could be modeled with an alpha texture that decides whether
hit points lie inside or outside the leaf.
If the `RTC_BUILD_QUALITY_HIGH` mode is set, the filter functions may
be called multiple times for the same primitive hit. Further, rays
hitting exactly the edge might also report two hits for the same
surface. For certain use cases, the application may have to work around
this limitation by collecting already reported hits (`geomID`/`primID`
pairs) and ignoring duplicates.
The filter function callback of type `RTCFilterFunctionN` gets passed a
number of arguments through the `RTCFilterFunctionNArguments`
structure. The `valid` parameter of that structure points to an integer
valid mask (0 means invalid and -1 means valid). The `geometryUserPtr`
member is a user pointer optionally set per geometry through the
`rtcSetGeometryUserData` function. The `context` member points to the
intersection context passed to the ray query function. The `ray`
parameter points to `N` rays in SOA layout. The `hit` parameter points
to `N` hits in SOA layout to test. The `N` parameter is the number of
rays and hits in `ray` and `hit`. The hit distance is provided as the
`tfar` value of the ray. If the hit geometry is instanced, the `instID`
member of the ray is valid, and the ray and the potential hit are in
object space.
The filter callback function has the task to check for each valid ray
whether it wants to accept or reject the corresponding hit. To reject a
hit, the filter callback function just has to write `0` to the integer
valid mask of the corresponding ray. To accept the hit, it just has to
leave the valid mask set to `-1`. The filter function is further
allowed to change the hit and decrease the `tfar` value of the ray but
it should not modify other ray data nor any inactive components of the
ray or hit.
When performing ray queries using `rtcIntersect1`, it is guaranteed
that the packet size is 1 when the callback is invoked. When performing
ray queries using the `rtcIntersect4/8/16` functions, it is not
generally guaranteed that the ray packet size (and order of rays inside
the packet) passed to the callback matches the initial ray packet.
However, under some circumstances these properties are guaranteed, and
whether this is the case can be queried using `rtcGetDeviceProperty`.
When performing ray queries using the stream API such as
`rtcIntersect1M`, `rtcIntersect1Mp`, `rtcIntersectNM`, or
`rtcIntersectNp` the order of rays and ray packet size of the callback
function might change to either 1, 4, 8, or 16.
For many usage scenarios, repacking and re-ordering of rays does not
cause difficulties in implementing the callback function. However,
algorithms that need to extend the ray with additional data must use
the `rayID` component of the ray to identify the original ray to access
the per-ray data.
The implementation of the filter function can choose to implement a
single code path that uses the ray access helper functions `RTCRay_XXX`
and hit access helper functions `RTCHit_XXX` to access ray and hit
data. Alternatively the code can branch to optimized implementations
for specific sizes of `N` and cast the `ray` and `hit` inputs to the
proper packet types.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryOccludedFilterFunction]
rtcSetGeometryOccludedFilterFunction
------------------------------------
#### NAME {#name}
rtcSetGeometryOccludedFilterFunction - sets the occlusion filter
for the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryOccludedFilterFunction(
RTCGeometry geometry,
RTCFilterFunctionN filter
);
#### DESCRIPTION {#description}
The `rtcSetGeometryOccludedFilterFunction` function registers an
occlusion filter callback function (`filter` argument) for the
specified geometry (`geometry` argument).
Only a single callback function can be registered per geometry, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered intersection filter function is invoked for every hit
encountered during the `rtcOccluded`-type ray queries and can accept or
reject that hit. The feature can be used to define a silhouette for a
primitive and reject hits that are outside the silhouette. E.g. a tree
leaf could be modeled with an alpha texture that decides whether hit
points lie inside or outside the leaf.
Please see the description of the
`rtcSetGeometryIntersectFilterFunction` for a description of the filter
callback function.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryIntersectFilterFunction]
rtcFilterIntersection
---------------------
#### NAME {#name}
rtcFilterIntersection - invokes the intersection filter function
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcFilterIntersection(
const struct RTCIntersectFunctionNArguments* args,
const struct RTCFilterFunctionNArguments* filterArgs
);
#### DESCRIPTION {#description}
The `rtcFilterIntersection` function can be called inside an
`RTCIntersectFunctionN` callback function to invoke the intersection
filter registered to the geometry and stored inside the context. For
this an `RTCFilterFunctionNArguments` structure must be created (see
`rtcSetGeometryIntersectFilterFunction`) which basically consists of a
valid mask, a hit packet to filter, the corresponding ray packet, and
the packet size. After the invocation of `rtcFilterIntersection`, only
rays that are still valid (valid mask set to -1) should update a hit.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcFilterOcclusion], [rtcSetGeometryIntersectFunction]
rtcFilterOcclusion
------------------
#### NAME {#name}
rtcFilterOcclusion - invokes the occlusion filter function
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcFilterOcclusion(
const struct RTCOccludedFunctionNArguments* args,
const struct RTCFilterFunctionNArguments* filterArgs
);
#### DESCRIPTION {#description}
The `rtcFilterOcclusion` function can be called inside an
`RTCOccludedFunctionN` callback function to invoke the occlusion filter
registered to the geometry and stored inside the context. For this an
`RTCFilterFunctionNArguments` structure must be created (see
`rtcSetGeometryIntersectFilterFunction`) which basically consists of a
valid mask, a hit packet to filter, the corresponding ray packet, and
the packet size. After the invocation of `rtcFilterOcclusion` only rays
that are still valid (valid mask set to -1) should signal an occlusion.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcFilterIntersection], [rtcSetGeometryOccludedFunction]
rtcSetGeometryUserData
----------------------
#### NAME {#name}
rtcSetGeometryUserData - sets the user-defined data pointer of the
geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryUserData(RTCGeometry geometry, void* userPtr);
#### DESCRIPTION {#description}
The `rtcSetGeometryUserData` function sets the user-defined data
pointer (`userPtr` argument) for a geometry (`geometry` argument). This
user data pointer is intended to be pointing to the application's
representation of the geometry, and is passed to various callback
functions. The application can use this pointer inside the callback
functions to access its geometry representation.
The `rtcGetGeometryUserData` function can be used to query an already
set user data pointer of a geometry.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetGeometryUserData]
rtcGetGeometryUserData
----------------------
#### NAME {#name}
rtcGetGeometryUserData - returns the user data pointer
of the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void* rtcGetGeometryUserData(RTCGeometry geometry);
#### DESCRIPTION {#description}
The `rtcGetGeometryUserData` function queries the user data pointer
previously set with `rtcSetGeometryUserData`. When
`rtcSetGeometryUserData` was not called yet, `NULL` is returned.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryUserData]
rtcSetGeometryUserPrimitiveCount
--------------------------------
#### NAME {#name}
rtcSetGeometryUserPrimitiveCount - sets the number of primitives
of a user-defined geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryUserPrimitiveCount(
RTCGeometry geometry,
unsigned int userPrimitiveCount
);
#### DESCRIPTION {#description}
The `rtcSetGeometryUserPrimitiveCount` function sets the number of
user-defined primitives (`userPrimitiveCount` parameter) of the
specified user-defined geometry (`geometry` parameter).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_USER]
rtcSetGeometryBoundsFunction
----------------------------
#### NAME {#name}
rtcSetGeometryBoundsFunction - sets a callback to query the
bounding box of user-defined primitives
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCBoundsFunctionArguments
{
void* geometryUserPtr;
unsigned int primID;
unsigned int timeStep;
struct RTCBounds* bounds_o;
};
typedef void (*RTCBoundsFunction)(
const struct RTCBoundsFunctionArguments* args
);
void rtcSetGeometryBoundsFunction(
RTCGeometry geometry,
RTCBoundsFunction bounds,
void* userPtr
);
#### DESCRIPTION {#description}
The `rtcSetGeometryBoundsFunction` function registers a bounding box
callback function (`bounds` argument) with payload (`userPtr` argument)
for the specified user geometry (`geometry` argument).
Only a single callback function can be registered per geometry, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered bounding box callback function is invoked to calculate
axis-aligned bounding boxes of the primitives of the user-defined
geometry during spatial acceleration structure construction. The
bounding box callback of `RTCBoundsFunction` type is invoked with a
pointer to a structure of type `RTCBoundsFunctionArguments` which
contains various arguments, such as: the user data of the geometry
(`geometryUserPtr` member), the ID of the primitive to calculate the
bounds for (`primID` member), the time step at which to calculate the
bounds (`timeStep` member), and a memory location to write the
calculated bound to (`bounds_o` member).
In a typical usage scenario one would store a pointer to the internal
representation of the user geometry object using
`rtcSetGeometryUserData`. The callback function can then read that
pointer from the `geometryUserPtr` field and calculate the proper
bounding box for the requested primitive and time, and store that
bounding box to the destination structure (`bounds_o` member).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_USER]
rtcSetGeometryIntersectFunction
-------------------------------
#### NAME {#name}
rtcSetGeometryIntersectFunction - sets the callback function to
intersect a user geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCIntersectFunctionNArguments
{
int* valid;
void* geometryUserPtr;
unsigned int primID;
struct RTCIntersectContext* context;
struct RTCRayHitN* rayhit;
unsigned int N;
unsigned int geomID;
};
typedef void (*RTCIntersectFunctionN)(
const struct RTCIntersectFunctionNArguments* args
);
void rtcSetGeometryIntersectFunction(
RTCGeometry geometry,
RTCIntersectFunctionN intersect
);
#### DESCRIPTION {#description}
The `rtcSetGeometryIntersectFunction` function registers a
ray/primitive intersection callback function (`intersect` argument) for
the specified user geometry (`geometry` argument).
Only a single callback function can be registered per geometry and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered callback function is invoked by `rtcIntersect`-type ray
queries to calculate the intersection of a ray packet of variable size
with one user-defined primitive. The callback function of type
`RTCIntersectFunctionN` gets passed a number of arguments through the
`RTCIntersectFunctionNArguments` structure. The value `N` specifies the
ray packet size, `valid` points to an array of integers that specify
whether the corresponding ray is valid (-1) or invalid (0), the
`geometryUserPtr` member points to the geometry user data previously
set through `rtcSetGeometryUserData`, the `context` member points to
the intersection context passed to the ray query, the `rayhit` member
points to a ray and hit packet of variable size `N`, and the `geomID`
and `primID` member identifies the geometry ID and primitive ID of the
primitive to intersect.
The `ray` component of the `rayhit` structure contains valid data, in
particular the `tfar` value is the current closest hit distance found.
All data inside the `hit` component of the `rayhit` structure are
undefined and should not be read by the function.
The task of the callback function is to intersect each active ray from
the ray packet with the specified user primitive. If the user-defined
primitive is missed by a ray of the ray packet, the function should
return without modifying the ray or hit. If an intersection of the
user-defined primitive with the ray was found in the valid range (from
`tnear` to `tfar`), it should update the hit distance of the ray
(`tfar` member) and the hit (`u`, `v`, `Ng`, `instID`, `geomID`,
`primID` members). In particular, the currently intersected instance is
stored in the `instID` field of the intersection context, which must be
deep copied into the `instID` member of the hit.
As a primitive might have multiple intersections with a ray, the
intersection filter function needs to be invoked by the user geometry
intersection callback for each encountered intersection, if filtering
of intersections is desired. This can be achieved through the
`rtcFilterIntersection` call.
Within the user geometry intersect function, it is safe to trace new
rays and create new scenes and geometries.
When performing ray queries using `rtcIntersect1`, it is guaranteed
that the packet size is 1 when the callback is invoked. When performing
ray queries using the `rtcIntersect4/8/16` functions, it is not
generally guaranteed that the ray packet size (and order of rays inside
the packet) passed to the callback matches the initial ray packet.
However, under some circumstances these properties are guaranteed, and
whether this is the case can be queried using `rtcGetDeviceProperty`.
When performing ray queries using the stream API such as
`rtcIntersect1M`, `rtcIntersect1Mp`, `rtcIntersectNM`, or
`rtcIntersectNp` the order of rays and ray packet size of the callback
function might change to either 1, 4, 8, or 16.
For many usage scenarios, repacking and re-ordering of rays does not
cause difficulties in implementing the callback function. However,
algorithms that need to extend the ray with additional data must use
the `rayID` component of the ray to identify the original ray to access
the per-ray data.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryOccludedFunction], [rtcSetGeometryUserData],
[rtcFilterIntersection]
rtcSetGeometryOccludedFunction
------------------------------
#### NAME {#name}
rtcSetGeometryOccludedFunction - sets the callback function to
test a user geometry for occlusion
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCOccludedFunctionNArguments
{
int* valid;
void* geometryUserPtr;
unsigned int primID;
struct RTCIntersectContext* context;
struct RTCRayN* ray;
unsigned int N;
unsigned int geomID;
};
typedef void (*RTCOccludedFunctionN)(
const struct RTCOccludedFunctionNArguments* args
);
void rtcSetGeometryOccludedFunction(
RTCGeometry geometry,
RTCOccludedFunctionN filter
);
#### DESCRIPTION {#description}
The `rtcSetGeometryOccludedFunction` function registers a ray/primitive
occlusion callback function (`filter` argument) for the specified user
geometry (`geometry` argument).
Only a single callback function can be registered per geometry, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered callback function is invoked by `rtcOccluded`-type ray
queries to test whether the rays of a packet of variable size are
occluded by a user-defined primitive. The callback function of type
`RTCOccludedFunctionN` gets passed a number of arguments through the
`RTCOccludedFunctionNArguments` structure. The value `N` specifies the
ray packet size, `valid` points to an array of integers which specify
whether the corresponding ray is valid (-1) or invalid (0), the
`geometryUserPtr` member points to the geometry user data previously
set through `rtcSetGeometryUserData`, the `context` member points to
the intersection context passed to the ray query, the `ray` member
points to a ray packet of variable size `N`, and the `geomID` and
`primID` member identifies the geometry ID and primitive ID of the
primitive to intersect.
The task of the callback function is to intersect each active ray from
the ray packet with the specified user primitive. If the user-defined
primitive is missed by a ray of the ray packet, the function should
return without modifying the ray. If an intersection of the
user-defined primitive with the ray was found in the valid range (from
`tnear` to `tfar`), it should set the `tfar` member of the ray to
`-inf`.
As a primitive might have multiple intersections with a ray, the
occlusion filter function needs to be invoked by the user geometry
occlusion callback for each encountered intersection, if filtering of
intersections is desired. This can be achieved through the
`rtcFilterOcclusion` call.
Within the user geometry occlusion function, it is safe to trace new
rays and create new scenes and geometries.
When performing ray queries using `rtcOccluded1`, it is guaranteed that
the packet size is 1 when the callback is invoked. When performing ray
queries using the `rtcOccluded4/8/16` functions, it is not generally
guaranteed that the ray packet size (and order of rays inside the
packet) passed to the callback matches the initial ray packet. However,
under some circumstances these properties are guaranteed, and whether
this is the case can be queried using `rtcGetDeviceProperty`. When
performing ray queries using the stream API such as `rtcOccluded1M`,
`rtcOccluded1Mp`, `rtcOccludedNM`, or `rtcOccludedNp` the order of rays
and ray packet size of the callback function might change to either 1,
4, 8, or 16.
For many usage scenarios, repacking and re-ordering of rays does not
cause difficulties in implementing the callback function. However,
algorithms that need to extend the ray with additional data must use
the `rayID` component of the ray to identify the original ray to access
the per-ray data.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometryIntersectFunction], [rtcSetGeometryUserData],
[rtcFilterOcclusion]
rtcSetGeometryPointQueryFunction
--------------------------------
#### NAME {#name}
rtcSetGeometryPointQueryFunction - sets the point query callback function
for a geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCPointQueryFunctionArguments
{
// the (world space) query object that was passed as an argument of rtcPointQuery.
struct RTCPointQuery* query;
// used for user input/output data. Will not be read or modified internally.
void* userPtr;
// primitive and geometry ID of primitive
unsigned int primID;
unsigned int geomID;
// the context with transformation and instance ID stack
struct RTCPointQueryContext* context;
// scaling factor indicating whether the current instance transformation
// is a similarity transformation.
float similarityScale;
};
typedef bool (*RTCPointQueryFunction)(
struct RTCPointQueryFunctionArguments* args
);
void rtcSetGeometryPointQueryFunction(
RTCGeometry geometry,
RTCPointQueryFunction queryFunc
);
#### DESCRIPTION {#description}
The `rtcSetGeometryPointQueryFunction` function registers a point query
callback function (`queryFunc` argument) for the specified geometry
(`geometry` argument).
Only a single callback function can be registered per geometry and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered callback function is invoked by [rtcPointQuery] for
every primitive of the geometry that intersects the corresponding point
query domain. The callback function of type `RTCPointQueryFunction`
gets passed a number of arguments through the
`RTCPointQueryFunctionArguments` structure. The `query` object is the
original point query object passed into [rtcPointQuery], `usrPtr` is
an arbitrary pointer to pass input into and store results of the
callback function. The `primID`, `geomID` and `context` (see
[rtcInitPointQueryContext] for details) can be used to identify the
geometry data of the primitive.
A `RTCPointQueryFunction` can also be passed directly as an argument to
[rtcPointQuery]. In this case the callback is invoked for all
primitives in the scene that intersect the query domain. If a callback
function is passed as an argument to [rtcPointQuery] and (a
potentially different) callback function is set for a geometry with
[rtcSetGeometryPointQueryFunction] both callback functions are
invoked and the callback function passed to [rtcPointQuery] will be
called before the geometry specific callback function.
If instancing is used, the parameter `simliarityScale` indicates
whether the current instance transform (top element of the stack in
`context`) is a similarity transformation or not. Similarity
transformations are composed of translation, rotation and uniform
scaling and if a matrix M defines a similarity transformation, there is
a scaling factor D such that for all x,y: dist(Mx, My) = D \* dist(x,
y). In this case the parameter `scalingFactor` is this scaling factor D
and otherwise it is 0. A valid similarity scale (`similarityScale` \>
0) allows to compute distance information in instance space and scale
the distances into world space (for example, to update the query
radius, see below) by dividing the instance space distance with the
similarity scale. If the current instance transform is not a similarity
transform (`similarityScale` is 0), the distance computation has to be
performed in world space to ensure correctness. In this case the
instance to world transformations given with the `context` should be
used to transform the primitive data into world space. Otherwise, the
query location can be transformed into instance space which can be more
efficient. If there is no instance transform, the similarity scale is
1.
The callback function will potentially be called for primitives outside
the query domain for two reasons: First, the callback is invoked for
all primitives inside a BVH leaf node since no geometry data of
primitives is determined internally and therefore individual primitives
are not culled (only their (aggregated) bounding boxes). Second, in
case non similarity transformations are used, the resulting ellipsoidal
query domain (in instance space) is approximated by its axis aligned
bounding box internally and therefore inner nodes that do not intersect
the original domain might intersect the approximative bounding box
which results in unnecessary callbacks. In any case, the callbacks are
conservative, i.e. if a primitive is inside the query domain a callback
will be invoked but the reverse is not necessarily true.
For efficiency, the radius of the `query` object can be decreased (in
world space) inside the callback function to improve culling of
geometry during BVH traversal. If the query radius was updated, the
callback function should return `true` to issue an update of internal
traversal information. Increasing the radius or modifying the time or
position of the query results in undefined behaviour.
Within the callback function, it is safe to call [rtcPointQuery]
again, for example when implementing instancing manually. In this case
the instance transformation should be pushed onto the stack in
`context`. Embree will internally compute the point query information
in instance space using the top element of the stack in `context` when
[rtcPointQuery] is called.
For a reference implementation of a closest point traversal of triangle
meshes using instancing and user defined instancing see the tutorial
[ClosestPoint].
#### SEE ALSO {#see-also}
[rtcPointQuery], [rtcInitPointQueryContext]
rtcSetGeometryInstancedScene
----------------------------
#### NAME {#name}
rtcSetGeometryInstancedScene - sets the instanced scene of
an instance geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryInstancedScene(
RTCGeometry geometry,
RTCScene scene
);
#### DESCRIPTION {#description}
The `rtcSetGeometryInstancedScene` function sets the instanced scene
(`scene` argument) of the specified instance geometry (`geometry`
argument).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_INSTANCE], [rtcSetGeometryTransform]
rtcSetGeometryTransform
-----------------------
#### NAME {#name}
rtcSetGeometryTransform - sets the transformation for a particular
time step of an instance geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryTransform(
RTCGeometry geometry,
unsigned int timeStep,
enum RTCFormat format,
const float* xfm
);
#### DESCRIPTION {#description}
The `rtcSetGeometryTransform` function sets the local-to-world affine
transformation (`xfm` parameter) of an instance geometry (`geometry`
parameter) for a particular time step (`timeStep` parameter). The
transformation is specified as a 3×4 matrix (3×3 linear transformation
plus translation), for which the following formats (`format` parameter)
are supported:
- `RTC_FORMAT_FLOAT3X4_ROW_MAJOR`: The 3×4 float matrix is laid out
in row-major form.
- `RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR`: The 3×4 float matrix is laid
out in column-major form.
- `RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR`: The 3×4 float matrix is laid
out in column-major form as a 4×4 homogeneous matrix with the last
row being equal to (0, 0, 0, 1).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_INSTANCE]
rtcSetGeometryTransformQuaternion
---------------------------------
#### NAME {#name}
rtcSetGeometryTransformQuaternion - sets the transformation for a particular
time step of an instance geometry as a decomposition of the
transformation matrix using quaternions to represent the rotation.
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryTransformQuaternion(
RTCGeometry geometry,
unsigned int timeStep,
const struct RTCQuaternionDecomposition* qd
);
#### DESCRIPTION {#description}
The `rtcSetGeometryTransformQuaternion` function sets the
local-to-world affine transformation (`qd` parameter) of an instance
geometry (`geometry` parameter) for a particular time step (`timeStep`
parameter). The transformation is specified as a
[RTCQuaternionDecomposition], which is a decomposition of an affine
transformation that represents the rotational component of an affine
transformation as a quaternion. This allows interpolating rotational
transformations exactly using spherical linear interpolation (such as a
turning wheel).
For more information about the decomposition see
[RTCQuaternionDecomposition]. The quaternion given in the
`RTCQuaternionDecomposition` struct will be normalized internally.
For correct results, the transformation matrices for all time steps
must be set either using `rtcSetGeometryTransform` or
`rtcSetGeometryTransformQuaternion`. Mixing both representations is not
allowed. Spherical linear interpolation will be used, iff the
transformation matizes are set with
`rtcSetGeometryTransformQuaternion`.
For an example of this feature see the tutorial [Quaternion Motion
Blur].
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcInitQuaternionDecomposition], [rtcSetGeometryTransform]
rtcGetGeometryTransform
-----------------------
#### NAME {#name}
rtcGetGeometryTransform - returns the interpolated instance
transformation for the specified time
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcGetGeometryTransform(
RTCGeometry geometry,
float time,
enum RTCFormat format,
void* xfm
);
#### DESCRIPTION {#description}
The `rtcGetGeometryTransform` function returns the interpolated local
to world transformation (`xfm` parameter) of an instance geometry
(`geometry` parameter) for a particular time (`time` parameter in range
$[0,1]$) in the specified format (`format` parameter).
Possible formats for the returned matrix are:
- `RTC_FORMAT_FLOAT3X4_ROW_MAJOR`: The 3×4 float matrix is laid out
in row-major form.
- `RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR`: The 3×4 float matrix is laid
out in column-major form.
- `RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR`: The 3×4 float matrix is laid
out in column-major form as a 4×4 homogeneous matrix with last row
equal to (0, 0, 0, 1).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_INSTANCE], [rtcSetGeometryTransform]
rtcSetGeometryTessellationRate
------------------------------
#### NAME {#name}
rtcSetGeometryTessellationRate - sets the tessellation rate of the
geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryTessellationRate(
RTCGeometry geometry,
float tessellationRate
);
#### DESCRIPTION {#description}
The `rtcSetGeometryTessellationRate` function sets the tessellation
rate (`tessellationRate` argument) for the specified geometry
(`geometry` argument). The tessellation rate can only be set for flat
curves and subdivision geometries. For curves, the tessellation rate
specifies the number of ray-facing quads per curve segment. For
subdivision surfaces, the tessellation rate specifies the number of
quads along each edge.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_CURVE], [RTC\_GEOMETRY\_TYPE\_SUBDIVISION]
rtcSetGeometryTopologyCount
---------------------------
#### NAME {#name}
rtcSetGeometryTopologyCount - sets the number of topologies of
a subdivision geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryTopologyCount(
RTCGeometry geometry,
unsigned int topologyCount
);
#### DESCRIPTION {#description}
The `rtcSetGeometryTopologyCount` function sets the number of
topologies (`topologyCount` parameter) for the specified subdivision
geometry (`geometry` parameter). The number of topologies of a
subdivision geometry must be greater or equal to 1.
To use multiple topologies, first the number of topologies must be
specified, then the individual topologies can be configured using
`rtcSetGeometrySubdivisionMode` and by setting an index buffer
(`RTC_BUFFER_TYPE_INDEX`) using the topology ID as the buffer slot.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_SUBDIVISION], [rtcSetGeometrySubdivisionMode]
rtcSetGeometrySubdivisionMode
-----------------------------
#### NAME {#name}
rtcSetGeometrySubdivisionMode - sets the subdivision mode
of a subdivision geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometrySubdivisionMode(
RTCGeometry geometry,
unsigned int topologyID,
enum RTCSubdivisionMode mode
);
#### DESCRIPTION {#description}
The `rtcSetGeometrySubdivisionMode` function sets the subdivision mode
(`mode` parameter) for the topology (`topologyID` parameter) of the
specified subdivision geometry (`geometry` parameter).
The subdivision modes can be used to force linear interpolation for
certain parts of the subdivision mesh:
- `RTC_SUBDIVISION_MODE_NO_BOUNDARY`: Boundary patches are ignored.
This way each rendered patch has a full set of control vertices.
- `RTC_SUBDIVISION_MODE_SMOOTH_BOUNDARY`: The sequence of boundary
control points are used to generate a smooth B-spline boundary
curve (default mode).
- `RTC_SUBDIVISION_MODE_PIN_CORNERS`: Corner vertices are pinned to
their location during subdivision.
- `RTC_SUBDIVISION_MODE_PIN_BOUNDARY`: All vertices at the border are
pinned to their location during subdivision. This way the boundary
is interpolated linearly. This mode is typically used for texturing
to also map texels at the border of the texture to the mesh.
- `RTC_SUBDIVISION_MODE_PIN_ALL`: All vertices at the border are
pinned to their location during subdivision. This way all patches
are linearly interpolated.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_SUBDIVISION]
rtcSetGeometryVertexAttributeTopology
-------------------------------------
#### NAME {#name}
rtcSetGeometryVertexAttributeTopology - binds a vertex
attribute to a topology of the geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcSetGeometryVertexAttributeTopology(
RTCGeometry geometry,
unsigned int vertexAttributeID,
unsigned int topologyID
);
#### DESCRIPTION {#description}
The `rtcSetGeometryVertexAttributeTopology` function binds a vertex
attribute buffer slot (`vertexAttributeID` argument) to a topology
(`topologyID` argument) for the specified subdivision geometry
(`geometry` argument). Standard vertex buffers are always bound to the
default topology (topology 0) and cannot be bound differently. A vertex
attribute buffer always uses the topology it is bound to when used in
the `rtcInterpolate` and `rtcInterpolateN` calls.
A topology with ID `i` consists of a subdivision mode set through
`rtcSetGeometrySubdivisionMode` and the index buffer bound to the index
buffer slot `i`. This index buffer can assign indices for each face of
the subdivision geometry that are different to the indices of the
default topology. These new indices can for example be used to
introduce additional borders into the subdivision mesh to map multiple
textures onto one subdivision geometry.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcSetGeometrySubdivisionMode], [rtcInterpolate],
[rtcInterpolateN]
rtcSetGeometryDisplacementFunction
----------------------------------
#### NAME {#name}
rtcSetGeometryDisplacementFunction - sets the displacement function
for a subdivision geometry
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCDisplacementFunctionNArguments
{
void* geometryUserPtr;
RTCGeometry geometry;
unsigned int primID;
unsigned int timeStep;
const float* u;
const float* v;
const float* Ng_x;
const float* Ng_y;
const float* Ng_z;
float* P_x;
float* P_y;
float* P_z;
unsigned int N;
};
typedef void (*RTCDisplacementFunctionN)(
const struct RTCDisplacementFunctionNArguments* args
);
void rtcSetGeometryDisplacementFunction(
RTCGeometry geometry,
RTCDisplacementFunctionN displacement
);
#### DESCRIPTION {#description}
The `rtcSetGeometryDisplacementFunction` function registers a
displacement callback function (`displacement` argument) for the
specified subdivision geometry (`geometry` argument).
Only a single callback function can be registered per geometry, and
further invocations overwrite the previously set callback function.
Passing `NULL` as function pointer disables the registered callback
function.
The registered displacement callback function is invoked to displace
points on the subdivision geometry during spatial acceleration
structure construction, during the `rtcCommitScene` call.
The callback function of type `RTCDisplacementFunctionN` is invoked
with a number of arguments stored inside the
`RTCDisplacementFunctionNArguments` structure. The provided user data
pointer of the geometry (`geometryUserPtr` member) can be used to point
to the application's representation of the subdivision mesh. A number
`N` of points to displace are specified in a structure of array layout.
For each point to displace, the local patch UV coordinates (`u` and `v`
arrays), the normalized geometry normal (`Ng_x`, `Ng_y`, and `Ng_z`
arrays), and the position (`P_x`, `P_y`, and `P_z` arrays) are
provided. The task of the displacement function is to use this
information and change the position data.
The geometry handle (`geometry` member) and primitive ID (`primID`
member) of the patch to displace are additionally provided as well as
the time step `timeStep`, which can be important if the displacement is
time-dependent and motion blur is used.
All passed arrays must be aligned to 64 bytes and properly padded to
make wide vector processing inside the displacement function easily
possible.
Also see tutorial [Displacement Geometry] for an example of how to
use the displacement mapping functions.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[RTC\_GEOMETRY\_TYPE\_SUBDIVISION]
rtcGetGeometryFirstHalfEdge
---------------------------
#### NAME {#name}
rtcGetGeometryFirstHalfEdge - returns the first half edge of a face
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
unsigned int rtcGetGeometryFirstHalfEdge(
RTCGeometry geometry,
unsigned int faceID
);
#### DESCRIPTION {#description}
The `rtcGetGeometryFirstHalfEdge` function returns the ID of the first
half edge belonging to the specified face (`faceID` argument). For
instance in the following example the first half edge of face `f1` is
`e4`.
![][imgHalfEdges]
This function can only be used for subdivision geometries. As all
topologies of a subdivision geometry share the same face buffer the
function does not depend on the topology ID.
Here f0 to f7 are 8 quadrilateral faces with 4 vertices each. The edges
e0 to e23 of these faces are shown with their orientation. For each
face the ID of the edges corresponds to the slots the face occupies in
the index array of the geometry. E.g. as the indices of face f1 start
at location 4 of the index array, the first edge is edge e4, the next
edge e5, etc.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetGeometryFirstHalfEdge], [rtcGetGeometryFace],
[rtcGetGeometryOppositeHalfEdge], [rtcGetGeometryNextHalfEdge],
[rtcGetGeometryPreviousHalfEdge]
rtcGetGeometryFace
------------------
#### NAME {#name}
rtcGetGeometryFace - returns the face of some half edge
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
unsigned int rtcGetGeometryFace(
RTCGeometry geometry,
unsigned int edgeID
);
#### DESCRIPTION {#description}
The `rtcGetGeometryFace` function returns the ID of the face the
specified half edge (`edgeID` argument) belongs to. For instance in the
following example the face `f1` is returned for edges `e4`, `e5`, `e6`,
and `e7`.
![][imgHalfEdges]
This function can only be used for subdivision geometries. As all
topologies of a subdivision geometry share the same face buffer the
function does not depend on the topology ID.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetGeometryFirstHalfEdge], [rtcGetGeometryFace],
[rtcGetGeometryOppositeHalfEdge], [rtcGetGeometryNextHalfEdge],
[rtcGetGeometryPreviousHalfEdge]
rtcGetGeometryNextHalfEdge
--------------------------
#### NAME {#name}
rtcGetGeometryNextHalfEdge - returns the next half edge
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
unsigned int rtcGetGeometryNextHalfEdge(
RTCGeometry geometry,
unsigned int edgeID
);
#### DESCRIPTION {#description}
The `rtcGetGeometryNextHalfEdge` function returns the ID of the next
half edge of the specified half edge (`edgeID` argument). For instance
in the following example the next half edge of `e10` is `e11`.
![][imgHalfEdges]
This function can only be used for subdivision geometries. As all
topologies of a subdivision geometry share the same face buffer the
function does not depend on the topology ID.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetGeometryFirstHalfEdge], [rtcGetGeometryFace],
[rtcGetGeometryOppositeHalfEdge], [rtcGetGeometryNextHalfEdge],
[rtcGetGeometryPreviousHalfEdge]
rtcGetGeometryPreviousHalfEdge
------------------------------
#### NAME {#name}
rtcGetGeometryPreviousHalfEdge - returns the previous half edge
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
unsigned int rtcGetGeometryPreviousHalfEdge(
RTCGeometry geometry,
unsigned int edgeID
);
#### DESCRIPTION {#description}
The `rtcGetGeometryPreviousHalfEdge` function returns the ID of the
previous half edge of the specified half edge (`edgeID` argument). For
instance in the following example the previous half edge of `e6` is
`e5`.
![][imgHalfEdges]
This function can only be used for subdivision geometries. As all
topologies of a subdivision geometry share the same face buffer the
function does not depend on the topology ID.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetGeometryFirstHalfEdge], [rtcGetGeometryFace],
[rtcGetGeometryOppositeHalfEdge], [rtcGetGeometryNextHalfEdge],
[rtcGetGeometryPreviousHalfEdge]
rtcGetGeometryOppositeHalfEdge
------------------------------
#### NAME {#name}
rtcGetGeometryOppositeHalfEdge - returns the opposite half edge
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
unsigned int rtcGetGeometryOppositeHalfEdge(
RTCGeometry geometry,
unsigned int topologyID,
unsigned int edgeID
);
#### DESCRIPTION {#description}
The `rtcGetGeometryOppositeHalfEdge` function returns the ID of the
opposite half edge of the specified half edge (`edgeID` argument) in
the specified topology (`topologyID` argument). For instance in the
following example the opposite half edge of `e6` is `e16`.
![][imgHalfEdges]
An opposite half edge does not exist if the specified half edge has
either no neighboring face, or more than 2 neighboring faces. In these
cases the function just returns the same edge `edgeID` again.
This function can only be used for subdivision geometries. The function
depends on the topology as the topologies of a subdivision geometry
have different index buffers assigned.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcGetGeometryFirstHalfEdge], [rtcGetGeometryFace],
[rtcGetGeometryOppositeHalfEdge], [rtcGetGeometryNextHalfEdge],
[rtcGetGeometryPreviousHalfEdge]
rtcInterpolate
--------------
#### NAME {#name}
rtcInterpolate - interpolates vertex attributes
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCInterpolateArguments
{
RTCGeometry geometry;
unsigned int primID;
float u;
float v;
enum RTCBufferType bufferType;
unsigned int bufferSlot;
float* P;
float* dPdu;
float* dPdv;
float* ddPdudu;
float* ddPdvdv;
float* ddPdudv;
unsigned int valueCount;
};
void rtcInterpolate(
const struct RTCInterpolateArguments* args
);
#### DESCRIPTION {#description}
The `rtcInterpolate` function smoothly interpolates per-vertex data
over the geometry. This interpolation is supported for triangle meshes,
quad meshes, curve geometries, and subdivision geometries. Apart from
interpolating the vertex attribute itself, it is also possible to get
the first and second order derivatives of that value. This
interpolation ignores displacements of subdivision surfaces and always
interpolates the underlying base surface.
The `rtcInterpolate` call gets passed a number of arguments inside a
structure of type `RTCInterpolateArguments`. For some geometry
(`geometry` parameter) this function smoothly interpolates the
per-vertex data stored inside the specified geometry buffer
(`bufferType` and `bufferSlot` parameters) to the u/v location (`u` and
`v` parameters) of the primitive (`primID` parameter). The number of
floating point values to interpolate and store to the destination
arrays can be specified using the `valueCount` parameter. As
interpolation buffer, one can specify vertex buffers
(`RTC_BUFFER_TYPE_VERTEX`) and vertex attribute buffers
(`RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE`) as well.
The `rtcInterpolate` call stores `valueCount` number of interpolated
floating point values to the memory location pointed to by `P`. One can
avoid storing the interpolated value by setting `P` to `NULL`.
The first order derivative of the interpolation by u and v are stored
at the `dPdu` and `dPdv` memory locations. One can avoid storing first
order derivatives by setting both `dPdu` and `dPdv` to `NULL`.
The second order derivatives are stored at the `ddPdudu`, `ddPdvdv`,
and `ddPdudv` memory locations. One can avoid storing second order
derivatives by setting these three pointers to `NULL`.
To use `rtcInterpolate` for a geometry, all changes to that geometry
must be properly committed using `rtcCommitGeometry`.
All input buffers and output arrays must be padded to 16 bytes, as the
implementation uses 16-byte SSE instructions to read and write into
these buffers.
See tutorial [Interpolation] for an example of using the
`rtcInterpolate` function.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcInterpolateN]
rtcInterpolateN
---------------
#### NAME {#name}
rtcInterpolateN - performs N interpolations of vertex attribute data
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCInterpolateNArguments
{
RTCGeometry geometry;
const void* valid;
const unsigned int* primIDs;
const float* u;
const float* v;
unsigned int N;
enum RTCBufferType bufferType;
unsigned int bufferSlot;
float* P;
float* dPdu;
float* dPdv;
float* ddPdudu;
float* ddPdvdv;
float* ddPdudv;
unsigned int valueCount;
};
void rtcInterpolateN(
const struct RTCInterpolateNArguments* args
);
#### DESCRIPTION {#description}
The `rtcInterpolateN` is similar to `rtcInterpolate`, but performs `N`
many interpolations at once. It additionally gets an array of u/v
coordinates and a valid mask (`valid` parameter) that specifies which
of these coordinates are valid. The valid mask points to `N` integers,
and a value of -1 denotes valid and 0 invalid. If the valid pointer is
`NULL` all elements are considers valid. The destination arrays are
filled in structure of array (SOA) layout. The value `N` must be
divisible by 4.
To use `rtcInterpolateN` for a geometry, all changes to that geometry
must be properly committed using `rtcCommitGeometry`.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcInterpolate]
rtcNewBuffer
------------
#### NAME {#name}
rtcNewBuffer - creates a new data buffer
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCBuffer rtcNewBuffer(
RTCDevice device,
size_t byteSize
);
#### DESCRIPTION {#description}
The `rtcNewBuffer` function creates a new data buffer object of
specified size in bytes (`byteSize` argument) that is bound to the
specified device (`device` argument). The buffer object is reference
counted with an initial reference count of 1. The returned buffer
object can be released using the `rtcReleaseBuffer` API call. The
specified number of bytes are allocated at buffer construction time and
deallocated when the buffer is destroyed.
When the buffer will be used as a vertex buffer
(`RTC_BUFFER_TYPE_VERTEX` and `RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE`), the
last buffer element must be readable using 16-byte SSE load
instructions, thus padding the last element is required for certain
layouts. E.g. a standard `float3` vertex buffer layout should add
storage for at least one more float to the end of the buffer.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcRetainBuffer], [rtcReleaseBuffer]
rtcNewSharedBuffer
------------------
#### NAME {#name}
rtcNewSharedBuffer - creates a new shared data buffer
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCBuffer rtcNewSharedBuffer(
RTCDevice device,
void* ptr,
size_t byteSize
);
#### DESCRIPTION {#description}
The `rtcNewSharedBuffer` function creates a new shared data buffer
object bound to the specified device (`device` argument). The buffer
object is reference counted with an initial reference count of 1. The
buffer can be released using the `rtcReleaseBuffer` function.
At construction time, the pointer to the user-managed buffer data
(`ptr` argument) including its size in bytes (`byteSize` argument) is
provided to create the buffer. At buffer construction time no buffer
data is allocated, but the buffer data provided by the application is
used. The buffer data must remain valid for as long as the buffer may
be used, and the user is responsible to free the buffer data when no
longer required.
When the buffer will be used as a vertex buffer
(`RTC_BUFFER_TYPE_VERTEX` and `RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE`), the
last buffer element must be readable using 16-byte SSE load
instructions, thus padding the last element is required for certain
layouts. E.g. a standard `float3` vertex buffer layout should add
storage for at least one more float to the end of the buffer.
The data pointer (`ptr` argument) must be aligned to 4 bytes; otherwise
the `rtcNewSharedBuffer` function will fail.
#### EXIT STATUS {#exit-status}
On failure `NULL` is returned and an error code is set that can be
queried using `rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcRetainBuffer], [rtcReleaseBuffer]
rtcRetainBuffer
---------------
#### NAME {#name}
rtcRetainBuffer - increments the buffer reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcRetainBuffer(RTCBuffer buffer);
#### DESCRIPTION {#description}
Buffer objects are reference counted. The `rtcRetainBuffer` function
increments the reference count of the passed buffer object (`buffer`
argument). This function together with `rtcReleaseBuffer` allows to use
the internal reference counting in a C++ wrapper class to handle the
ownership of the object.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewBuffer], [rtcReleaseBuffer]
rtcReleaseBuffer
----------------
#### NAME {#name}
rtcReleaseBuffer - decrements the buffer reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcReleaseBuffer(RTCBuffer buffer);
#### DESCRIPTION {#description}
Buffer objects are reference counted. The `rtcReleaseBuffer` function
decrements the reference count of the passed buffer object (`buffer`
argument). When the reference count falls to 0, the buffer gets
destroyed.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewBuffer], [rtcRetainBuffer]
rtcGetBufferData
----------------
#### NAME {#name}
rtcGetBufferData - gets a pointer to the buffer data
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void* rtcGetBufferData(RTCBuffer buffer);
#### DESCRIPTION {#description}
The `rtcGetBufferData` function returns a pointer to the buffer data of
the specified buffer object (`buffer` argument).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewBuffer]
RTCRay
------
#### NAME {#name}
RTCRay - single ray structure
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore_ray.h>
struct RTC_ALIGN(16) RTCRay
{
float org_x; // x coordinate of ray origin
float org_y; // y coordinate of ray origin
float org_z; // z coordinate of ray origin
float tnear; // start of ray segment
float dir_x; // x coordinate of ray direction
float dir_y; // y coordinate of ray direction
float dir_z; // z coordinate of ray direction
float time; // time of this ray for motion blur
float tfar; // end of ray segment (set to hit distance)
unsigned int mask; // ray mask
unsigned int id; // ray ID
unsigned int flags; // ray flags
};
#### DESCRIPTION {#description}
The `RTCRay` structure defines the ray layout for a single ray. The ray
contains the origin (`org_x`, `org_y`, `org_z` members), direction
vector (`dir_x`, `dir_y`, `dir_z` members), and ray segment (`tnear`
and `tfar` members). The ray direction does not have to be normalized,
and only the parameter range specified by the `tnear`/`tfar` interval
is considered valid.
The ray segment must be in the range $[0, \infty]$, thus ranges that
start behind the ray origin are not allowed, but ranges can reach to
infinity. For rays inside a ray stream, `tfar` \< `tnear` identifies an
inactive ray.
The ray further contains a motion blur time in the range $[0, 1]$
(`time` member), a ray mask (`mask` member), a ray ID (`id` member),
and ray flags (`flags` member). The ray mask can be used to mask out
some geometries for some rays (see `rtcSetGeometryMask` for more
details). The ray ID can be used to identify a ray inside a callback
function, even if the order of rays inside a ray packet or stream has
changed. The ray flags are reserved.
The `embree3/rtcore_ray.h` header additionally defines the same ray
structure in structure of array (SOA) layout for API functions
accepting ray packets of size 4 (`RTCRay4` type), size 8 (`RTCRay8`
type), and size 16 (`RTCRay16` type). The header additionally defines
an `RTCRayNt` template for ray packets of an arbitrary compile-time
size.
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTCHit]
RTCHit
------
#### NAME {#name}
RTCHit - single hit structure
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCHit
{
float Ng_x; // x coordinate of geometry normal
float Ng_y; // y coordinate of geometry normal
float Ng_z; // z coordinate of geometry normal
float u; // barycentric u coordinate of hit
float v; // barycentric v coordinate of hit
unsigned int primID; // geometry ID
unsigned int geomID; // primitive ID
unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance ID
};
#### DESCRIPTION {#description}
The `RTCHit` type defines the type of a ray/primitive intersection
result. The hit contains the unnormalized geometric normal in object
space at the hit location (`Ng_x`, `Ng_y`, `Ng_z` members), the
barycentric u/v coordinates of the hit (`u` and `v` members), as well
as the primitive ID (`primID` member), geometry ID (`geomID` member),
and instance ID stack (`instID` member) of the hit. The parametric
intersection distance is not stored inside the hit, but stored inside
the `tfar` member of the ray.
The `embree3/rtcore_ray.h` header additionally defines the same hit
structure in structure of array (SOA) layout for hit packets of size 4
(`RTCHit4` type), size 8 (`RTCHit8` type), and size 16 (`RTCHit16`
type). The header additionally defines an `RTCHitNt` template for hit
packets of an arbitrary compile-time size.
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTCRay], [Multi-Level Instancing]
RTCRayHit
---------
#### NAME {#name}
RTCRayHit - combined single ray/hit structure
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore_ray.h>
struct RTCORE_ALIGN(16) RTCRayHit
{
struct RTCRay ray;
struct RTCHit hit;
};
#### DESCRIPTION {#description}
The `RTCRayHit` structure is used as input for the `rtcIntersect`-type
functions and stores the ray to intersect and some hit fields that hold
the intersection result afterwards.
The `embree3/rtcore_ray.h` header additionally defines the same ray/hit
structure in structure of array (SOA) layout for API functions
accepting ray packets of size 4 (`RTCRayHit4` type), size 8
(`RTCRayHit8` type), and size 16 (`RTCRayHit16` type). The header
additionally defines an `RTCRayHitNt` template to generate ray/hit
packets of an arbitrary compile-time size.
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTCRay], [RTCHit]
RTCRayN
-------
#### NAME {#name}
RTCRayN - ray packet of runtime size
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore_ray.h>
struct RTCRayN;
float& RTCRayN_org_x(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_org_y(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_org_z(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_tnear(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_dir_x(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_dir_y(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_dir_z(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_time (RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_tfar (RTCRayN* ray, unsigned int N, unsigned int i);
unsigned int& RTCRayN_mask (RTCRayN* ray, unsigned int N, unsigned int i);
unsigned int& RTCRayN_id (RTCRayN* ray, unsigned int N, unsigned int i);
unsigned int& RTCRayN_flags(RTCRayN* ray, unsigned int N, unsigned int i);
#### DESCRIPTION {#description}
When the ray packet size is not known at compile time (e.g. when Embree
returns a ray packet in the `RTCFilterFuncN` callback function), Embree
uses the `RTCRayN` type for ray packets. These ray packets can only
have sizes of 1, 4, 8, or 16. No other packet size will be used.
You can either implement different special code paths for each of these
possible packet sizes and cast the ray to the appropriate ray packet
type, or implement one general code path that uses the `RTCRayN_XXX`
helper functions to access the ray packet components.
These helper functions get a pointer to the ray packet (`ray`
argument), the packet size (`N` argument), and returns a reference to a
component (e.g. x-component of origin) of the the i-th ray of the
packet (`i` argument).
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTCHitN]
RTCHitN
-------
#### NAME {#name}
RTCHitN - hit packet of runtime size
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct HitN;
float& RTCHitN_Ng_x(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_Ng_y(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_Ng_z(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_u(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_v(RTCHitN* hit, unsigned int N, unsigned int i);
unsigned& RTCHitN_primID(RTCHitN* hit, unsigned int N, unsigned int i);
unsigned& RTCHitN_geomID(RTCHitN* hit, unsigned int N, unsigned int i);
unsigned& RTCHitN_instID(RTCHitN* hit, unsigned int N, unsigned int i, unsigned int level);
#### DESCRIPTION {#description}
When the hit packet size is not known at compile time (e.g. when Embree
returns a hit packet in the `RTCFilterFuncN` callback function), Embree
uses the `RTCHitN` type for hit packets. These hit packets can only
have sizes of 1, 4, 8, or 16. No other packet size will be used.
You can either implement different special code paths for each of these
possible packet sizes and cast the hit to the appropriate hit packet
type, or implement one general code path that uses the `RTCHitN_XXX`
helper functions to access hit packet components.
These helper functions get a pointer to the hit packet (`hit`
argument), the packet size (`N` argument), and returns a reference to a
component (e.g. x component of `Ng`) of the the i-th hit of the packet
(`i` argument).
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTCRayN]
RTCRayHitN
----------
#### NAME {#name}
RTCRayHitN - combined ray/hit packet of runtime size
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore_ray.h>
struct RTCRayHitN;
struct RTCRayN* RTCRayHitN_RayN(struct RTCRayHitN* rayhit, unsigned int N);
struct RTCHitN* RTCRayHitN_HitN(struct RTCRayHitN* rayhit, unsigned int N);
#### DESCRIPTION {#description}
When the packet size of a ray/hit structure is not known at compile
time (e.g. when Embree returns a ray/hit packet in the
`RTCIntersectFunctionN` callback function), Embree uses the
`RTCRayHitN` type for ray packets. These ray/hit packets can only have
sizes of 1, 4, 8, or 16. No other packet size will be used.
You can either implement different special code paths for each of these
possible packet sizes and cast the ray/hit to the appropriate ray/hit
packet type, or extract the `RTCRayN` and `RTCHitN` components using
the `rtcGetRayN` and `rtcGetHitN` helper functions and use the
`RTCRayN_XXX` and `RTCHitN_XXX` functions to access the ray and hit
parts of the structure.
#### EXIT STATUS {#exit-status}
#### SEE ALSO {#see-also}
[RTCHitN]
rtcInitIntersectContext
-----------------------
#### NAME {#name}
rtcInitIntersectContext - initializes the intersection context
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
enum RTCIntersectContextFlags
{
RTC_INTERSECT_CONTEXT_FLAG_NONE,
RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT,
RTC_INTERSECT_CONTEXT_FLAG_COHERENT,
};
struct RTCIntersectContext
{
enum RTCIntersectContextFlags flags;
RTCFilterFunctionN filter;
#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
unsigned int instStackSize;
#endif
unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT];
#if RTC_MIN_WIDTH
float minWidthDistanceFactor;
#endif
};
void rtcInitIntersectContext(
struct RTCIntersectContext* context
);
#### DESCRIPTION {#description}
A per ray-query intersection context (`RTCIntersectContext` type) is
supported that can be used to configure intersection flags (`flags`
member), specify a filter callback function (`filter` member), specify
the chain of IDs of the current instance (`instID` and `instStackSize`
members), and to attach arbitrary data to the query (e.g. per ray
data).
The `rtcInitIntersectContext` function initializes the context to
default values and should be called to initialize every intersection
context. This function gets inlined, which minimizes overhead and
allows for compiler optimizations.
The intersection context flag can be used to tune the behavior of the
traversal algorithm. Using the `RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT`
flags uses an optimized traversal algorithm for incoherent rays
(default), while `RTC_INTERSECT_CONTEXT_FLAG_COHERENT` uses an
optimized traversal algorithm for coherent rays (e.g. primary camera
rays).
Best primary ray performance can be obtained by using the ray stream
API and setting the intersect context flag to
`RTC_INTERSECT_CONTEXT_FLAG_COHERENT`. For secondary rays, it is
typically better to use the `RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT`
flag, unless the rays are known to be very coherent too (e.g. for
primary transparency rays).
A filter function can be specified inside the context. This filter
function is invoked as a second filter stage after the per-geometry
intersect or occluded filter function is invoked. Only rays that passed
the first filter stage are valid in this second filter stage. Having
such a per ray-query filter function can be useful to implement
modifications of the behavior of the query, such as collecting all hits
or accumulating transparencies. The support for the context filter
function must be enabled for a scene by using the
`RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION` scene flag. In case of
instancing this feature has to get enabled also for each instantiated
scene.
The minWidthDistanceFactor value controls the target size of the curve
radii when the min-width feature is enabled. Please see the
[rtcSetGeometryMaxRadiusScale] function for more details on the
min-width feature.
It is guaranteed that the pointer to the intersection context passed to
a ray query is directly passed to the registered callback functions.
This way it is possible to attach arbitrary data to the end of the
intersection context, such as a per-ray payload.
Please note that the ray pointer is not guaranteed to be passed to the
callback functions, thus reading additional data from the ray pointer
passed to callbacks is not possible.
#### EXIT STATUS {#exit-status}
No error code is set by this function.
#### SEE ALSO {#see-also}
[rtcIntersect1], [rtcOccluded1]
rtcIntersect1
-------------
#### NAME {#name}
rtcIntersect1 - finds the closest hit for a single ray
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcIntersect1(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHit* rayhit
);
#### DESCRIPTION {#description}
The `rtcIntersect1` function finds the closest hit of a single ray with
the scene (`scene` argument). The provided ray/hit structure (`rayhit`
argument) contains the ray to intersect and some hit output fields that
are filled when a hit is found.
The user has to initialize the ray origin (`org` ray member), ray
direction (`dir` ray member), ray segment (`tnear`, `tfar` ray
members), and set the ray flags to `0` (`flags` ray member). If the
scene contains motion blur geometries, also the ray time (`time` ray
member) must be initialized to a value in the range $[0, 1]$. If ray
masks are enabled at compile time, the ray mask (`mask` ray member)
must be initialized as well. The ray segment has to be in the range
$[0, \infty]$, thus ranges that start behind the ray origin are not
valid, but ranges can reach to infinity. See Section [RTCRay] for the
ray layout description.
The geometry ID (`geomID` hit member) of the hit data must be
initialized to `RTC_INVALID_GEOMETRY_ID` (-1).
Further, an intersection context for the ray query function must be
created and initialized (see `rtcInitIntersectContext`).
When no intersection is found, the ray/hit data is not updated. When an
intersection is found, the hit distance is written into the `tfar`
member of the ray and all hit data is set, such as unnormalized
geometry normal in object space (`Ng` hit member), local hit
coordinates (`u`, `v` hit member), instance ID stack (`instID` hit
member), geometry ID (`geomID` hit member), and primitive ID (`primID`
hit member). See Section [RTCHit] for the hit layout description.
If the instance ID stack has a prefix of values not equal to
`RTC_INVALID_GEOMETRY_ID`, the instance ID on each level corresponds to
the geometry ID of the hit instance of the higher-level scene, the
geometry ID corresponds to the hit geometry inside the hit instanced
scene, and the primitive ID corresponds to the n-th primitive of that
geometry.
If level 0 of the instance ID stack is equal to
`RTC_INVALID_GEOMETRY_ID`, the geometry ID corresponds to the hit
geometry inside the top-level scene, and the primitive ID corresponds
to the n-th primitive of that geometry.
The implementation makes no guarantees that primitives whose hit
distance is exactly at (or very close to) `tnear` or `tfar` are hit or
missed. If you want to exclude intersections at `tnear` just pass a
slightly enlarged `tnear`, and if you want to include intersections at
`tfar` pass a slightly enlarged `tfar`.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The ray pointer passed to callback functions is not guaranteed to be
identical to the original ray provided. To extend the ray with
additional data to be accessed in callback functions, use the
intersection context.
The ray/hit structure must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccluded1], [RTCRayHit], [RTCRay], [RTCHit]
rtcOccluded1
------------
#### NAME {#name}
rtcOccluded1 - finds any hit for a single ray
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcOccluded1(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRay* ray
);
#### DESCRIPTION {#description}
The `rtcOccluded1` function checks for a single ray (`ray` argument)
whether there is any hit with the scene (`scene` argument).
The user must initialize the ray origin (`org` ray member), ray
direction (`dir` ray member), ray segment (`tnear`, `tfar` ray
members), and must set the ray flags to `0` (`flags` ray member). If
the scene contains motion blur geometries, also the ray time (`time`
ray member) must be initialized to a value in the range $[0, 1]$. If
ray masks are enabled at compile time, the ray mask (`mask` ray member)
must be initialized as well. The ray segment must be in the range
$[0, \infty]$, thus ranges that start behind the ray origin are not
valid, but ranges can reach to infinity. See Section [RTCRay] for the
ray layout description.
When no intersection is found, the ray data is not updated. In case a
hit was found, the `tfar` component of the ray is set to `-inf`.
The implementation makes no guarantees that primitives whose hit
distance is exactly at (or very close to) `tnear` or `tfar` are hit or
missed. If you want to exclude intersections at `tnear` just pass a
slightly enlarged `tnear`, and if you want to include intersections at
`tfar` pass a slightly enlarged `tfar`.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The ray pointer passed to callback functions is not guaranteed to be
identical to the original ray provided. To extend the ray with
additional data to be accessed in callback functions, use the
intersection context.
The ray must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccluded1], [RTCRay]
rtcIntersect4/8/16
------------------
#### NAME {#name}
rtcIntersect4/8/16 - finds the closest hits for a ray packet
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcIntersect4(
const int* valid,
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHit4* rayhit
);
void rtcIntersect8(
const int* valid,
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHit8* rayhit
);
void rtcIntersect16(
const int* valid,
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHit16* rayhit
);
#### DESCRIPTION {#description}
The `rtcIntersect4/8/16` functions finds the closest hits for a ray
packet of size 4, 8, or 16 (`rayhit` argument) with the scene (`scene`
argument). The ray/hit input contains a ray packet and hit packet. See
Section [rtcIntersect1] for a description of how to set up and trace
rays.
A ray valid mask must be provided (`valid` argument) which stores one
32-bit integer (`-1` means valid and `0` invalid) per ray in the
packet. Only active rays are processed, and hit data of inactive rays
is not changed.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The ray pointer passed to callback functions is not guaranteed to be
identical to the original ray provided. To extend the ray with
additional data to be accessed in callback functions, use the
intersection context.
The implementation of these functions is guaranteed to invoke callback
functions always with the same ray packet size and ordering of rays as
specified initially.
For `rtcIntersect4` the ray packet must be aligned to 16 bytes, for
`rtcIntersect8` the alignment must be 32 bytes, and for
`rtcIntersect16` the alignment must be 64 bytes.
The `rtcIntersect4`, `rtcIntersect8` and `rtcIntersect16` functions may
change the ray packet size and ray order when calling back into
intersect filter functions or user geometry callbacks. Under some
conditions the application can assume packets to stay intakt, which can
determined by querying the `RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED`,
`RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED`,
`RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED` properties through the
`rtcGetDeviceProperty` function. See [rtcGetDeviceProperty] for more
information.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccluded4/8/16]
rtcOccluded4/8/16
-----------------
#### NAME {#name}
rtcOccluded4/8/16 - finds any hits for a ray packet
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcOccluded4(
const int* valid,
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRay4* ray
);
void rtcOccluded8(
const int* valid,
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRay8* ray
);
void rtcOccluded16(
const int* valid,
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRay16* ray
);
#### DESCRIPTION {#description}
The `rtcOccluded4/8/16` functions checks for each active ray of the ray
packet of size 4, 8, or 16 (`ray` argument) whether there is any hit
with the scene (`scene` argument). See Section [rtcOccluded1] for a
description of how to set up and trace occlusion rays.
A ray valid mask must be provided (`valid` argument) which stores one
32-bit integer (`-1` means valid and `0` invalid) per ray in the
packet. Only active rays are processed, and hit data of inactive rays
is not changed.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The ray pointer passed to callback functions is not guaranteed to be
identical to the original ray provided. To extend the ray with
additional data to be accessed in callback functions, use the
intersection context.
The implementation of these functions is guaranteed to invoke callback
functions always with the same ray packet size and ordering of rays as
specified initially.
For `rtcOccluded4` the ray packet must be aligned to 16 bytes, for
`rtcOccluded8` the alignment must be 32 bytes, and for `rtcOccluded16`
the alignment must be 64 bytes.
The `rtcOccluded4`, `rtcOccluded8` and `rtcOccluded16` functions may
change the ray packet size and ray order when calling back into
intersect filter functions or user geometry callbacks. Under some
conditions the application can assume packets to stay intakt, which can
determined by querying the `RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED`,
`RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED`,
`RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED` properties through the
`rtcGetDeviceProperty` function. See [rtcGetDeviceProperty] for more
information.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccluded4/8/16]
rtcIntersect1M
--------------
#### NAME {#name}
rtcIntersect1M - finds the closest hits for a stream of M single
rays
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcIntersect1M(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHit* rayhit,
unsigned int M,
size_t byteStride
);
#### DESCRIPTION {#description}
The `rtcIntersect1M` function finds the closest hits for a stream of
`M` single rays (`rayhit` argument) with the scene (`scene` argument).
The `rayhit` argument points to an array of ray and hit data with
specified byte stride (`byteStride` argument) between the ray/hit
structures. See Section [rtcIntersect1] for a description of how to
set up and trace rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The stream size `M` can be an arbitrary positive integer including 0.
Each ray must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccluded1M]
rtcOccluded1M
-------------
#### NAME {#name}
rtcOccluded1M - finds any hits for a stream of M single rays
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcOccluded1M(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRay* ray,
unsigned int M,
size_t byteStride
);
#### DESCRIPTION {#description}
The `rtcOccluded1M` function checks whether there are any hits for a
stream of `M` single rays (`ray` argument) with the scene (`scene`
argument). The `ray` argument points to an array of rays with specified
byte stride (`byteStride` argument) between the rays. See Section
[rtcOccluded1] for a description of how to set up and trace occlusion
rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The stream size `M` can be an arbitrary positive integer including 0.
Each ray must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcIntersect1M]
rtcIntersect1Mp
---------------
#### NAME {#name}
rtcIntersect1Mp - finds the closest hits for a stream of M pointers
to single rays
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcIntersect1Mp(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHit** rayhit,
unsigned int M
);
#### DESCRIPTION {#description}
The `rtcIntersect1Mp` function finds the closest hits for a stream of
`M` single rays (`rayhit` argument) with the scene (`scene` argument).
The `rayhit` argument points to an array of pointers to the individual
ray/hit structures. See Section [rtcIntersect1] for a description of
how to set up and trace a ray.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The stream size `M` can be an arbitrary positive integer including 0.
Each ray must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccluded1Mp]
rtcOccluded1Mp
--------------
#### NAME {#name}
rtcOccluded1Mp - find any hits for a stream of M pointers to
single rays
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcOccluded1M(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRay** ray,
unsigned int M
);
#### DESCRIPTION {#description}
The `rtcOccluded1Mp` function checks whether there are any hits for a
stream of `M` single rays (`ray` argument) with the scene (`scene`
argument). The `ray` argument points to an array of pointers to rays.
Section [rtcOccluded1] for a description of how to set up and trace a
occlusion rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The stream size `M` can be an arbitrary positive integer including 0.
Each ray must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcIntersect1Mp]
rtcIntersectNM
--------------
#### NAME {#name}
rtcIntersectNM - finds the closest hits for a stream of M
ray packets of size N
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcIntersectNM(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHitN* rayhit,
unsigned int N,
unsigned int M,
size_t byteStride
);
#### DESCRIPTION {#description}
The `rtcIntersectNM` function finds the closest hits for a stream of
`M` ray packets (`rayhit` argument) of size `N` with the scene (`scene`
argument). The `rays` argument points to an array of ray and hit
packets with specified byte stride (`byteStride` argument) between the
ray/hit packets. See Section [rtcIntersect1] for a description of how
to set up and trace rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The packet size `N` must be larger than 0, and the stream size `M` can
be an arbitrary positive integer including 0. Each ray must be aligned
to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccludedNM]
rtcOccludedNM
-------------
#### NAME {#name}
rtcOccludedNM - finds any hits for a stream of M ray packets of
size N
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcOccludedNM(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayN* ray,
unsigned int N,
unsigned int M,
size_t byteStride
);
#### DESCRIPTION {#description}
The `rtcOccludedNM` function checks whether there are any hits for a
stream of `M` ray packets (`ray` argument) of size `N` with the scene
(`scene` argument). The `ray` argument points to an array of ray
packets with specified byte stride (`byteStride` argument) between the
ray packets. See Section [rtcOccluded1] for a description of how to
set up and trace occlusion rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The packet size `N` must be larger than 0, and the stream size `M` can
be an arbitrary positive integer including 0. Each ray must be aligned
to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcIntersectNM]
rtcIntersectNp
--------------
#### NAME {#name}
rtcIntersectNp - finds the closest hits for a SOA ray stream of
size N
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcIntersectNp(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayHitNp* rayhit,
unsigned int N
);
#### DESCRIPTION {#description}
The `rtcIntersectNp` function finds the closest hits for a SOA ray
stream (`rays` argument) of size `N` (basically a large ray packet)
with the scene (`scene` argument). The `rayhit` argument points to two
structures of pointers with one pointer for each ray and hit component.
Each of these pointers points to an array with the ray or hit component
data for each ray or hit. This way the individual components of the SOA
ray stream do not need to be stored sequentially in memory, which makes
it possible to have large varying size ray packets in SOA layout. See
Section [rtcIntersect1] for a description of how to set up and trace
rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The stream size `N` can be an arbitrary positive integer including 0.
Each ray component array must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcOccludedNp]
rtcOccludedNp
-------------
#### NAME {#name}
rtcOccludedNp - finds any hits for a SOA ray stream of size N
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcOccludedNp(
RTCScene scene,
struct RTCIntersectContext* context,
struct RTCRayNp* ray,
unsigned int N
);
#### DESCRIPTION {#description}
The `rtcOccludedNp` function checks whether there are any hits for a
SOA ray stream (`ray` argument) of size `N` (basically a large ray
packet) with the scene (`scene` argument). The `ray` argument points to
a structure of pointers with one pointer for each ray component. Each
of these pointers points to an array with the ray component data for
each ray. This way the individual components of the SOA ray stream do
not need to be stored sequentially in memory, which makes it possible
to have large varying size ray packets in SOA layout. See Section
[rtcOccluded1] for a description of how to set up and trace occlusion
rays.
The intersection context (`context` argument) can specify flags to
optimize traversal and a filter callback function to be invoked for
every intersection. Further, the pointer to the intersection context is
propagated to callback functions invoked during traversal and can thus
be used to extend the ray with additional data. See Section
`RTCIntersectContext` for more information.
The implementation of the stream ray query functions may re-order rays
arbitrarily and re-pack rays into ray packets of different size. For
this reason, callback functions may be invoked with an arbitrary packet
size (of size 1, 4, 8, or 16) and different ordering as specified
initially. For this reason, one may have to use the `rayID` component
of the ray to identify the original ray, e.g. to access a per-ray
payload.
A ray in a ray stream is considered inactive if its `tnear` value is
larger than its `tfar` value.
The stream size `N` can be an arbitrary positive integer including 0.
Each ray component array must be aligned to 16 bytes.
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcIntersectNp]
rtcInitPointQueryContext
------------------------
#### NAME {#name}
rtcInitPointQueryContext - initializes the context information (e.g.
stack of (multilevel-)instance transformations) for point queries
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTC_ALIGN(16) RTCPointQueryContext
{
// accumulated 4x4 column major matrices from world to instance space.
float world2inst[RTC_MAX_INSTANCE_LEVEL_COUNT][16];
// accumulated 4x4 column major matrices from instance to world space.
float inst2world[RTC_MAX_INSTANCE_LEVEL_COUNT][16];
// instance ids.
unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT];
// number of instances currently on the stack.
unsigned int instStackSize;
};
void rtcInitPointQueryContext(
struct RTCPointQueryContext* context
);
#### DESCRIPTION {#description}
A stack (`RTCPointQueryContext` type) which stores the IDs and instance
transformations during a BVH traversal for a point query. The
transformations are assumed to be affine transformations (3×3 matrix
plus translation) and therefore the last column is ignored (see
[RTC\_GEOMETRY\_TYPE\_INSTANCE] for details).
The `rtcInitPointContext` function initializes the context to default
values and should be called for initialization.
The context will be passed as an argument to the point query callback
function (see [rtcSetGeometryPointQueryFunction]) and should be used
to pass instance information down the instancing chain for user defined
instancing (see tutorial [ClosestPoint] for a reference
implementation of point queries with user defined instancing).
The context is an necessary argument to [rtcPointQuery] and Embree
internally uses the topmost instance transformation of the stack to
transform the point query into instance space.
#### EXIT STATUS {#exit-status}
No error code is set by this function.
#### SEE ALSO {#see-also}
[rtcPointQuery], [rtcSetGeometryPointQueryFunction]
rtcPointQuery
-------------
#### NAME {#name}
rtcPointQuery - traverses the BVH with a point query object
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTC_ALIGN(16) RTCPointQuery
{
// location of the query
float x;
float y;
float z;
// radius and time of the query
float radius;
float time;
};
void rtcPointQuery(
RTCScene scene,
struct RTCPointQuery* query,
struct RTCPointQueryContext* context,
struct RTCPointQueryFunction* queryFunc,
void* userPtr
);
#### DESCRIPTION {#description}
The `rtcPointQuery` function traverses the BVH using a `RTCPointQuery`
object (`query` argument) and calls a user defined callback function
(e.g `queryFunc` argument) for each primitive of the scene (`scene`
argument) that intersects the query domain.
The user has to initialize the query location (`x`, `y` and `z` member)
and query radius in the range $[0, \infty]$. If the scene contains
motion blur geometries, also the query time (`time` member) must be
initialized to a value in the range $[0, 1]$.
Further, a `RTCPointQueryContext` (`context` argument) must be created
and initialized. It contains ID and transformation information of the
instancing hierarchy if (multilevel-)instancing is used. See
[rtcInitPointQueryContext] for further information.
For every primitive that intersects the query domain, the callback
function (`queryFunc` argument) is called, in which distance
computations to the primitive can be implemented. The user will be
provided with the primID and geomID of the according primitive,
however, the geometry information (e.g. triangle index and vertex data)
has to be determined manually. The `userPtr` argument can be used to
input geometry data of the scene or output results of the point query
(e.g. closest point currently found on surface geometry (see tutorial
[ClosestPoint])).
The parameter `queryFunc` is optional and can be NULL, in which case
the callback function is not invoked. However, a callback function can
still get attached to a specific `RTCGeometry` object using
[rtcSetGeometryPointQueryFunction]. If a callback function is
attached to a geometry and (a potentially different) callback function
is passed as an argument to `rtcPointQuery`, both functions are called
for the primitives of the according geometries.
The query radius can be decreased inside the callback function, which
allows to efficiently cull parts of the scene during BVH traversal.
Increasing the query radius and modifying time or location of the query
will result in undefined behaviour.
The callback function will be called for all primitives in a leaf node
of the BVH even if the primitive is outside the query domain, since
Embree does not gather geometry information of primitives internally.
Point queries can be used with (multilevel)-instancing. However, care
has to be taken when the instance transformation contains anisotropic
scaling or sheering. In these cases distance computations have to be
performed in world space to ensure correctness and the ellipsoidal
query domain (in instance space) will be approximated with its axis
aligned bounding box internally. Therefore, the callback function might
be invoked even for primitives in inner BVH nodes that do not intersect
the query domain. See [rtcSetGeometryPointQueryFunction] for details.
The point query structure must be aligned to 16 bytes.
#### SUPPORTED PRIMITIVES
Currently, all primitive types are supported by the point query API
except of points (see [RTC\_GEOMETRY\_TYPE\_POINT]), curves (see
[RTC\_GEOMETRY\_TYPE\_CURVE]) and sudivision surfaces (see
[RTC\_GEOMETRY\_SUBDIVISION]).
#### EXIT STATUS {#exit-status}
For performance reasons this function does not do any error checks,
thus will not set any error flags on failure.
#### SEE ALSO {#see-also}
[rtcSetGeometryPointQueryFunction], [rtcInitPointQueryContext]
rtcCollide
----------
#### NAME {#name}
rtcCollide - intersects one BVH with another
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTCCollision {
unsigned int geomID0, primID0;
unsigned int geomID1, primID1;
};
typedef void (*RTCCollideFunc) (
void* userPtr,
RTCCollision* collisions,
size_t num_collisions);
void rtcCollide (
RTCScene hscene0,
RTCScene hscene1,
RTCCollideFunc callback,
void* userPtr
);
#### DESCRIPTION {#description}
The `rtcCollide` function intersects the BVH of `hscene0` with the BVH
of scene `hscene1` and calls a user defined callback function (e.g
`callback` argument) for each pair of intersecting primitives between
the two scenes. A user defined data pointer (`userPtr` argument) can
also be passed in.
For every pair of primitives that may intersect each other, the
callback function (`callback` argument) is called. The user will be
provided with the primID's and geomID's of multiple potentially
intersecting primitive pairs. Currently, only scene entirely composed
of user geometries are supported, thus the user is expected to
implement a primitive/primitive intersection to filter out false
positives in the callback function. The `userPtr` argument can be used
to input geometry data of the scene or output results of the
intersection query.
#### SUPPORTED PRIMITIVES {#supported-primitives}
Currently, the only supported type is the user geometry type (see
[RTC\_GEOMETRY\_TYPE\_USER]).
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
rtcNewBVH
---------
#### NAME {#name}
rtcNewBVH - creates a new BVH object
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
RTCBVH rtcNewBVH(RTCDevice device);
#### DESCRIPTION {#description}
This function creates a new BVH object and returns a handle to this
BVH. The BVH object is reference counted with an initial reference
count of 1. The handle can be released using the `rtcReleaseBVH` API
call.
The BVH object can be used to build a BVH in a user-specified format
over user-specified primitives. See the documentation of the
`rtcBuildBVH` call for more details.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcRetainBVH], [rtcReleaseBVH], [rtcBuildBVH]
rtcRetainBVH
------------
#### NAME {#name}
rtcRetainBVH - increments the BVH reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcRetainBVH(RTCBVH bvh);
#### DESCRIPTION {#description}
BVH objects are reference counted. The `rtcRetainBVH` function
increments the reference count of the passed BVH object (`bvh`
argument). This function together with `rtcReleaseBVH` allows to use
the internal reference counting in a C++ wrapper class to handle the
ownership of the object.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewBVH], [rtcReleaseBVH]
rtcReleaseBVH
-------------
#### NAME {#name}
rtcReleaseBVH - decrements the BVH reference count
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
void rtcReleaseBVH(RTCBVH bvh);
#### DESCRIPTION {#description}
BVH objects are reference counted. The `rtcReleaseBVH` function
decrements the reference count of the passed BVH object (`bvh`
argument). When the reference count falls to 0, the BVH gets destroyed.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewBVH], [rtcRetainBVH]
rtcBuildBVH
-----------
#### NAME {#name}
rtcBuildBVH - builds a BVH
#### SYNOPSIS {#synopsis}
#include <embree3/rtcore.h>
struct RTC_ALIGN(32) RTCBuildPrimitive
{
float lower_x, lower_y, lower_z;
unsigned int geomID;
float upper_x, upper_y, upper_z;
unsigned int primID;
};
typedef void* (*RTCCreateNodeFunction) (
RTCThreadLocalAllocator allocator,
unsigned int childCount,
void* userPtr
);
typedef void (*RTCSetNodeChildrenFunction) (
void* nodePtr,
void** children,
unsigned int childCount,
void* userPtr
);
typedef void (*RTCSetNodeBoundsFunction) (
void* nodePtr,
const struct RTCBounds** bounds,
unsigned int childCount,
void* userPtr
);
typedef void* (*RTCCreateLeafFunction) (
RTCThreadLocalAllocator allocator,
const struct RTCBuildPrimitive* primitives,
size_t primitiveCount,
void* userPtr
);
typedef void (*RTCSplitPrimitiveFunction) (
const struct RTCBuildPrimitive* primitive,
unsigned int dimension,
float position,
struct RTCBounds* leftBounds,
struct RTCBounds* rightBounds,
void* userPtr
);
typedef bool (*RTCProgressMonitorFunction)(
void* userPtr, double n
);
enum RTCBuildFlags
{
RTC_BUILD_FLAG_NONE,
RTC_BUILD_FLAG_DYNAMIC
};
struct RTCBuildArguments
{
size_t byteSize;
enum RTCBuildQuality buildQuality;
enum RTCBuildFlags buildFlags;
unsigned int maxBranchingFactor;
unsigned int maxDepth;
unsigned int sahBlockSize;
unsigned int minLeafSize;
unsigned int maxLeafSize;
float traversalCost;
float intersectionCost;
RTCBVH bvh;
struct RTCBuildPrimitive* primitives;
size_t primitiveCount;
size_t primitiveArrayCapacity;
RTCCreateNodeFunction createNode;
RTCSetNodeChildrenFunction setNodeChildren;
RTCSetNodeBoundsFunction setNodeBounds;
RTCCreateLeafFunction createLeaf;
RTCSplitPrimitiveFunction splitPrimitive;
RTCProgressMonitorFunction buildProgress;
void* userPtr;
};
struct RTCBuildArguments rtcDefaultBuildArguments();
void* rtcBuildBVH(
const struct RTCBuildArguments* args
);
#### DESCRIPTION {#description}
The `rtcBuildBVH` function can be used to build a BVH in a user-defined
format over arbitrary primitives. All arguments to the function are
provided through the `RTCBuildArguments` structure. The first member of
that structure must be set to the size of the structure in bytes
(`bytesSize` member) which allows future extensions of the structure.
It is recommended to initialize the build arguments structure using the
`rtcDefaultBuildArguments` function.
The `rtcBuildBVH` function gets passed the BVH to build (`bvh` member),
the array of primitives (`primitives` member), the capacity of that
array (`primitiveArrayCapacity` member), the number of primitives
stored inside the array (`primitiveCount` member), callback function
pointers, and a user-defined pointer (`userPtr` member) that is passed
to all callback functions when invoked. The `primitives` array can be
freed by the application after the BVH is built. All callback functions
are typically called from multiple threads, thus their implementation
must be thread-safe.
Four callback functions must be registered, which are invoked during
build to create BVH nodes (`createNode` member), to set the pointers to
all children (`setNodeChildren` member), to set the bounding boxes of
all children (`setNodeBounds` member), and to create a leaf node
(`createLeaf` member).
The function pointer to the primitive split function (`splitPrimitive`
member) may be `NULL`, however, then no spatial splitting in high
quality mode is possible. The function pointer used to report the build
progress (`buildProgress` member) is optional and may also be `NULL`.
Further, some build settings are passed to configure the BVH build.
Using the build quality settings (`buildQuality` member), one can
select between a faster, low quality build which is good for dynamic
scenes, and a standard quality build for static scenes. One can also
specify the desired maximum branching factor of the BVH
(`maxBranchingFactor` member), the maximum depth the BVH should have
(`maxDepth` member), the block size for the SAH heuristic
(`sahBlockSize` member), the minimum and maximum leaf size
(`minLeafSize` and `maxLeafSize` member), and the estimated costs of
one traversal step and one primitive intersection (`traversalCost` and
`intersectionCost` members). When enabling the `RTC_BUILD_FLAG_DYNAMIC`
build flags (`buildFlags` member), re-build performance for dynamic
scenes is improved at the cost of higher memory requirements.
To spatially split primitives in high quality mode, the builder needs
extra space at the end of the build primitive array to store split
primitives. The total capacity of the build primitive array is passed
using the `primitiveArrayCapacity` member, and should be about twice
the number of primitives when using spatial splits.
The `RTCCreateNodeFunc` and `RTCCreateLeafFunc` callbacks are passed a
thread local allocator object that should be used for fast allocation
of nodes using the `rtcThreadLocalAlloc` function. We strongly
recommend using this allocation mechanism, as alternative approaches
like standard `malloc` can be over 10× slower. The allocator object
passed to the create callbacks may be used only inside the current
thread. Memory allocated using `rtcThreadLocalAlloc` is automatically
freed when the `RTCBVH` object is deleted. If you use your own memory
allocation scheme you have to free the memory yourself when the
`RTCBVH` object is no longer used.
The `RTCCreateNodeFunc` callback additionally gets the number of
children for this node in the range from 2 to `maxBranchingFactor`
(`childCount` argument).
The `RTCSetNodeChildFunc` callback function gets a pointer to the node
as input (`nodePtr` argument), an array of pointers to the children
(`childPtrs` argument), and the size of this array (`childCount`
argument).
The `RTCSetNodeBoundsFunc` callback function gets a pointer to the node
as input (`nodePtr` argument), an array of pointers to the bounding
boxes of the children (`bounds` argument), and the size of this array
(`childCount` argument).
The `RTCCreateLeafFunc` callback additionally gets an array of
primitives as input (`primitives` argument), and the size of this array
(`primitiveCount` argument). The callback should read the `geomID` and
`primID` members from the passed primitives to construct the leaf.
The `RTCSplitPrimitiveFunc` callback is invoked in high quality mode to
split a primitive (`primitive` argument) at the specified position
(`position` argument) and dimension (`dimension` argument). The
callback should return bounds of the clipped left and right parts of
the primitive (`leftBounds` and `rightBounds` arguments).
The `RTCProgressMonitorFunction` callback function is called with the
estimated completion rate `n` in the range $[0,1]$. Returning `true`
from the callback lets the build continue; returning `false` cancels
the build.
#### EXIT STATUS {#exit-status}
On failure an error code is set that can be queried using
`rtcGetDeviceError`.
#### SEE ALSO {#see-also}
[rtcNewBVH]
RTCQuaternionDecomposition
--------------------------
#### NAME {#name}
RTCQuaternionDecomposition - structure that represents a quaternion
decomposition of an affine transformation
#### SYNOPSIS {#synopsis}
struct RTCQuaternionDecomposition
{
float scale_x, scale_y, scale_z;
float skew_xy, skew_xz, skew_yz;
float shift_x, shift_y, shift_z;
float quaternion_r, quaternion_i, quaternion_j, quaternion_k;
float translation_x, translation_y, translation_z;
};
#### DESCRIPTION {#description}
The struct `RTCQuaternionDecomposition` represents an affine
transformation decomposed into three parts. An upper triangular
scaling/skew/shift matrix
$$
S = \left( \begin{array}{cccc}
scale_x & skew_{xy} & skew_{xz} & shift_x \
0 & scale_y & skew_{yz} & shift_y \
0 & 0 & scale_z & shift_z \
0 & 0 & 0 & 1 \
\end{array} \right),
$$
a translation matrix
$$
T = \left( \begin{array}{cccc}
1 & 0 & 0 & translation_x \
0 & 1 & 0 & translation_y \
0 & 0 & 1 & translation_z \
0 & 0 & 0 & 1 \
\end{array} \right),
$$
and a rotation matrix $R$, represented as a quaternion
$quaternion_r + quaternion_i \mathbf{i} + quaternion_j \mathbf{i} + quaternion_k \mathbf{k}$
where $\mathbf{i}$, $\mathbf{j}$ $\mathbf{k}$ are the imaginary
quaternion units. The passed quaternion will be normalized internally.
The affine transformation matrix corresponding to a
`RTCQuaternionDecomposition` is $TRS$ and a point
$p = (p_x, p_y, p_z, 1)^T$ will be transformed as
$$p' = T R S p.$$
The functions `rtcInitQuaternionDecomposition`,
`rtcQuaternionDecompositionSetQuaternion`,
`rtcQuaternionDecompositionSetScale`,
`rtcQuaternionDecompositionSetSkew`,
`rtcQuaternionDecompositionSetShift`, and
`rtcQuaternionDecompositionSetTranslation` allow to set the fields of
the structure more conveniently.
#### EXIT STATUS {#exit-status}
No error code is set by this function.
#### SEE ALSO {#see-also}
[rtcSetGeometryTransformQuaternion],
[rtcInitQuaternionDecomposition]
rtcInitQuaternionDecomposition
------------------------------
#### NAME {#name}
rtcInitQuaternionDecomposition - initializes quaternion decomposition
#### SYNOPSIS {#synopsis}
void rtcInitQuaternionDecomposition(
struct RTCQuaternionDecomposition* qd
);
#### DESCRIPTION {#description}
The `rtcInitQuaternionDecomposition` function initializes a
`RTCQuaternionDecomposition` structure to represent an identity
transformation.
#### EXIT STATUS {#exit-status}
No error code is set by this function.
#### SEE ALSO {#see-also}
[rtcSetGeometryTransformQuaternion], [RTCQuaternionDecomposition]
Performance Recommendations
===========================
MXCSR control and status register
---------------------------------
It is strongly recommended to have the `Flush to Zero` and
`Denormals are Zero` mode of the MXCSR control and status register
enabled for each thread before calling the `rtcIntersect`-type and
`rtcOccluded`-type functions. Otherwise, under some circumstances
special handling of denormalized floating point numbers can
significantly reduce application and Embree performance. When using
Embree together with the Intel® Threading Building Blocks, it is
sufficient to execute the following code at the beginning of the
application main thread (before the creation of the
`tbb::task_scheduler_init` object):
#include <xmmintrin.h>
#include <pmmintrin.h>
...
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
If using a different tasking system, make sure each rendering thread
has the proper mode set.
Thread Creation and Affinity Settings
-------------------------------------
Tasking systems like TBB create worker threads on demand, which will
add a runtime overhead for the very first `rtcCommitScene` call. In
case you want to benchmark the scene build time, you should start the
threads at application startup. You can let Embree start TBB threads by
passing `start_threads=1` to the `cfg` parameter of `rtcNewDevice`.
On machines with a high thread count (e.g. dual-socket Xeon or Xeon Phi
machines), affinitizing TBB worker threads increases build and
rendering performance. You can let Embree affinitize TBB worker threads
by passing `set_affinity=1` to the `cfg` parameter of `rtcNewDevice`.
By default, threads are not affinitized by Embree with the exception of
Xeon Phi Processors where they are affinitized by default.
All Embree tutorials automatically start and affinitize TBB worker
threads by passing `start_threads=1,set_affinity=1` to `rtcNewDevice`.
Fast Coherent Rays
------------------
For getting the highest performance for highly coherent rays, e.g.
primary or hard shadow rays, it is recommended to use packets or
streams of single rays/packets with setting the
`RTC_INTERSECT_CONTEXT_FLAG_COHERENT` flag in the `RTCIntersectContext`
passed to the `rtcIntersect`/`rtcOccluded` calls. The total number of
rays in a coherent stream of ray packets should be around 64, e.g. 8
times 8-wide packets, or 4 times 16-wide packets. The rays inside each
packet should be grouped as coherent as possible.
Huge Page Support
-----------------
It is recommended to use huge pages under Linux to increase rendering
performance. Embree supports 2MB huge pages under Windows, Linux, and
macOS. Under Linux huge page support is enabled by default, and under
Windows and macOS disabled by default. Huge page support can be enabled
in Embree by passing `hugepages=1` to `rtcNewDevice` or disabled by
passing `hugepages=0` to `rtcNewDevice`.
We recommend using 2MB huge pages with Embree under Linux as this
improves ray tracing performance by about 5-10%. Under Windows using
huge pages requires the application to run in elevated mode which is a
security issue, thus likely not an option for most use cases. Under
macOS huge pages are rarely available as memory tends to get quickly
fragmented, thus we do not recommend using huge pages on macOS.
### Huge Pages under Linux
Linux supports transparent huge pages and explicit huge pages. To
enable transparent huge page support under Linux, execute the following
as root:
echo always > /sys/kernel/mm/transparent_hugepage/enabled
When transparent huge pages are enabled, the kernel tries to merge 4KB
pages to 2MB pages when possible as a background job. Many Linux
distributions have transparent huge pages enabled by default. See the
following webpage for more information on [transparent huge pages under
Linux](https://www.kernel.org/doc/Documentation/vm/transhuge.txt). In
this mode each application, including your rendering application based
on Embree, will automatically tend to use huge pages.
Using transparent huge pages, the transitioning from 4KB to 2MB pages
might take some time. For that reason Embree also supports allocating
2MB pages directly when a huge page pool is configured. Such a pool can
be configured by writing some number of huge pages to allocate to
`/proc/sys/vm/nr_overcommit_hugepages` as root user. E.g. to configure
2GB of address space for huge page allocation, execute the following as
root:
echo 1000 > /proc/sys/vm/nr_overcommit_hugepages
See the following webpage for more information on [huge pages under
Linux](https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt).
### Huge Pages under Windows
To use huge pages under Windows, the current user must have the "Lock
pages in memory" (SeLockMemoryPrivilege) assigned. This can be
configured through the "Local Security Policy" application, by adding a
user to "Local Policies" -\> "User Rights Assignment" -\> "Lock pages
in memory". You have to log out and in again for this change to take
effect.
Further, your application must be executed as an elevated process ("Run
as administrator") and the "SeLockMemoryPrivilege" must be explicitly
enabled by your application. Example code on how to enable this
privilege can be found in the "common/sys/alloc.cpp" file of Embree.
Alternatively, Embree will try to enable this privilege when passing
`enable_selockmemoryprivilege=1` to `rtcNewDevice`. Further, huge pages
should be enabled in Embree by passing `hugepages=1` to `rtcNewDevice`.
When the system has been running for a while, physical memory gets
fragmented, which can slow down the allocation of huge pages
significantly under Windows.
### Huge Pages under macOS
To use huge pages under macOS you have to pass `hugepages=1` to
`rtcNewDevice` to enable that feature in Embree.
When the system has been running for a while, physical memory gets
quickly fragmented, and causes huge page allocations to fail. For this
reason, huge pages are not very useful under macOS in practice.
Avoid store-to-load forwarding issues with single rays
------------------------------------------------------
We recommend to use a single SSE store to set up the `org` and `tnear`
components, and a single SSE store to set up the `dir` and `time`
components of a single ray (`RTCRay` type). Storing these values using
scalar stores causes a store-to-load forwarding penalty because Embree
is reading these components using SSE loads later on.
Embree Tutorials
================
Embree comes with a set of tutorials aimed at helping users understand
how Embree can be used and extended. There is a very basic minimal
that can be compiled as both C and C++, which should get new users started quickly.
All other tutorials exist in an Intel® ISPC and C++ version to demonstrate
the two versions of the API. Look for files
named `tutorialname_device.ispc` for the Intel® ISPC implementation of the
tutorial, and files named `tutorialname_device.cpp` for the single ray C++
version of the tutorial. To start the C++ version use the `tutorialname`
executables, to start the Intel® ISPC version use the `tutorialname_ispc`
executables. All tutorials can print available command line options
using the `--help` command line parameter.
For all tutorials except minimal, you can select an initial camera using
the `--vp` (camera position), `--vi` (camera look-at point), `--vu`
(camera up vector), and `--fov` (vertical field of view) command line
parameters:
./triangle_geometry --vp 10 10 10 --vi 0 0 0
You can select the initial window size using the `--size` command line
parameter, or start the tutorials in full screen using the `--fullscreen`
parameter:
./triangle_geometry --size 1024 1024
./triangle_geometry --fullscreen
The initialization string for the Embree device (`rtcNewDevice` call)
can be passed to the ray tracing core through the `--rtcore` command
line parameter, e.g.:
./triangle_geometry --rtcore verbose=2,threads=1
The navigation in the interactive display mode follows the camera orbit
model, where the camera revolves around the current center of interest.
With the left mouse button you can rotate around the center of interest
(the point initially set with `--vi`). Holding Control pressed while
clicking the left mouse button rotates the camera around its location.
You can also use the arrow keys for navigation.
You can use the following keys:
F1
: Default shading
F2
: Gray EyeLight shading
F3
: Traces occlusion rays only.
F4
: UV Coordinate visualization
F5
: Geometry normal visualization
F6
: Geometry ID visualization
F7
: Geometry ID and Primitive ID visualization
F8
: Simple shading with 16 rays per pixel for benchmarking.
F9
: Switches to render cost visualization. Pressing again reduces
brightness.
F10
: Switches to render cost visualization. Pressing again increases
brightness.
f
: Enters or leaves full screen mode.
c
: Prints camera parameters.
ESC
: Exits the tutorial.
q
: Exits the tutorial.
Minimal
-------
This tutorial is designed to get new users started with Embree.
It can be compiled as both C and C++. It demonstrates how to initialize
a device and scene, and how to intersect rays with the scene.
There is no image output to keep the tutorial as simple as possible.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/minimal/minimal.cpp)
Triangle Geometry
-----------------
[![][imgTriangleGeometry]](https://github.com/embree/embree/blob/master/tutorials/triangle_geometry/triangle_geometry_device.cpp)
This tutorial demonstrates the creation of a static cube and ground
plane using triangle meshes. It also demonstrates the use of the
`rtcIntersect1` and `rtcOccluded1` functions to render primary visibility
and hard shadows. The cube sides are colored based on the ID of the hit
primitive.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/triangle_geometry/triangle_geometry_device.cpp)
Dynamic Scene
-------------
[![][imgDynamicScene]](https://github.com/embree/embree/blob/master/tutorials/dynamic_scene/dynamic_scene_device.cpp)
This tutorial demonstrates the creation of a dynamic scene, consisting
of several deforming spheres. Half of the spheres use the
`RTC_BUILD_QUALITY_REFIT` geometry build quality, which allows Embree
to use a refitting strategy for these spheres, the other half uses the
`RTC_BUILD_QUALITY_LOW` geometry build quality, causing a high
performance rebuild of their spatial data structure each frame. The
spheres are colored based on the ID of the hit sphere geometry.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/dynamic_scene/dynamic_scene_device.cpp)
Multi Scene Geometry
-------------
[![][imgDynamicScene]](https://github.com/embree/embree/blob/master/tutorials/multiscene_geometry/multiscene_geometry_device.cpp)
This tutorial demonstrates the creation of multiple scenes sharing the
same geometry objects. Here, three scenes are built. One with all
the dynamic spheres of the Dynamic Scene test and two others each with
half. The ground plane is shared by all three scenes. The space bar
is used to cycle the scene chosen for rendering.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/multiscene_geometry/multiscene_geometry_device.cpp)
User Geometry
-------------
[![][imgUserGeometry]](https://github.com/embree/embree/blob/master/tutorials/user_geometry/user_geometry_device.cpp)
This tutorial shows the use of user-defined geometry, to re-implement
instancing, and to add analytic spheres. A two-level scene is created,
with a triangle mesh as ground plane, and several user geometries that
instance other scenes with a small number of spheres of different kinds.
The spheres are colored using the instance ID and geometry ID of the hit
sphere, to demonstrate how the same geometry instanced in different
ways can be distinguished.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/user_geometry/user_geometry_device.cpp)
Viewer
------
[![][imgViewer]](https://github.com/embree/embree/blob/master/tutorials/viewer/viewer_device.cpp)
This tutorial demonstrates a simple OBJ viewer that traces primary
visibility rays only. A scene consisting of multiple meshes is created,
each mesh sharing the index and vertex buffer with the application.
It also demonstrates how to support additional per-vertex data, such as
shading normals.
You need to specify an OBJ file at the command line for this tutorial to
work:
./viewer -i model.obj
[Source Code](https://github.com/embree/embree/blob/master/tutorials/viewer/viewer_device.cpp)
Stream Viewer
-------------
[![][imgViewerStream]](https://github.com/embree/embree/blob/master/tutorials/viewer_stream/viewer_stream_device.cpp)
This tutorial is a simple OBJ viewer that demonstrates the use of ray
streams. You need to specify an OBJ file at the command line for this
tutorial to work:
./viewer_stream -i model.obj
[Source Code](https://github.com/embree/embree/blob/master/tutorials/viewer_stream/viewer_stream_device.cpp)
Intersection Filter
-------------------
[![][imgIntersectionFilter]](https://github.com/embree/embree/blob/master/tutorials/intersection_filter/intersection_filter_device.cpp)
This tutorial demonstrates the use of filter callback functions to
efficiently implement transparent objects. The filter function used for
primary rays lets the ray pass through the geometry if it is entirely
transparent. Otherwise, the shading loop handles the transparency
properly, by potentially shooting secondary rays. The filter function
used for shadow rays accumulates the transparency of all surfaces along
the ray, and terminates traversal if an opaque occluder is hit.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/intersection_filter/intersection_filter_device.cpp)
Instanced Geometry
------------------
[![][imgInstancedGeometry]](https://github.com/embree/embree/blob/master/tutorials/instanced_geometry/instanced_geometry_device.cpp)
This tutorial demonstrates the in-build instancing feature of Embree, by
instancing a number of other scenes built from triangulated spheres. The
spheres are again colored using the instance ID and geometry ID of the
hit sphere, to demonstrate how the same geometry instanced in different
ways can be distinguished.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/instanced_geometry/instanced_geometry_device.cpp)
Multi Level Instancing
----------------------
[![][imgMultiLevelInstancing]](https://github.com/embree/embree/blob/master/tutorials/multi_instanced_geometry/multi_instanced_geometry_device.cpp)
This tutorial demonstrates multi-level instancing, i.e., nesting instances
into instances. To enable the tutorial, set the compile-time variable
`EMBREE_MAX_INSTANCE_LEVEL_COUNT` to a value other than the default 1.
This variable is available in the code as `RTC_MAX_INSTANCE_LEVEL_COUNT`.
The renderer uses a basic path tracing approach, and the
image will progressively refine over time.
There are two levels of instances in this scene: multiple instances of
the same tree nest instances of a twig.
Intersections on up to `RTC_MAX_INSTANCE_LEVEL_COUNT` nested levels of
instances work out of the box. Users may obtain the *instance ID stack* for
a given hitpoint from the `instID` member.
During shading, the instance ID stack is used to accumulate
normal transformation matrices for each hit. The tutorial visualizes
transformed normals as colors.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/multi_instanced_geometry/multi_instanced_geometry_device.cpp)
Path Tracer
-----------
[![][imgPathtracer]](https://github.com/embree/embree/blob/master/tutorials/pathtracer/pathtracer_device.cpp)
This tutorial is a simple path tracer, based on the viewer tutorial.
You need to specify an OBJ file and light source at the command line for
this tutorial to work:
./pathtracer -i model.obj --ambientlight 1 1 1
As example models we provide the "Austrian Imperial Crown" model by
[Martin Lubich](http://www.loramel.net) and the "Asian Dragon" model from the
[Stanford 3D Scanning Repository](http://graphics.stanford.edu/data/3Dscanrep/).
[crown.zip](https://github.com/embree/models/releases/download/release/crown.zip)
[asian_dragon.zip](https://github.com/embree/models/releases/download/release/asian_dragon.zip)
To render these models execute the following:
./pathtracer -c crown/crown.ecs
./pathtracer -c asian_dragon/asian_dragon.ecs
[Source Code](https://github.com/embree/embree/blob/master/tutorials/pathtracer/pathtracer_device.cpp)
Hair
----
[![][imgHairGeometry]](https://github.com/embree/embree/blob/master/tutorials/hair_geometry/hair_geometry_device.cpp)
This tutorial demonstrates the use of the hair geometry to render a
hairball.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/hair_geometry/hair_geometry_device.cpp)
Curve Geometry
--------------
[![][imgCurveGeometry]](https://github.com/embree/embree/blob/master/tutorials/curve_geometry/curve_geometry_device.cpp)
This tutorial demonstrates the use of the Linear Basis, B-Spline, and Catmull-Rom curve geometries.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/curve_geometry/curve_geometry_device.cpp)
Subdivision Geometry
--------------------
[![][imgSubdivisionGeometry]](https://github.com/embree/embree/blob/master/tutorials/subdivision_geometry/subdivision_geometry_device.cpp)
This tutorial demonstrates the use of Catmull-Clark subdivision
surfaces.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/subdivision_geometry/subdivision_geometry_device.cpp)
Displacement Geometry
---------------------
[![][imgDisplacementGeometry]](https://github.com/embree/embree/blob/master/tutorials/displacement_geometry/displacement_geometry_device.cpp)
This tutorial demonstrates the use of Catmull-Clark subdivision
surfaces with procedural displacement mapping using a constant edge
tessellation level.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/displacement_geometry/displacement_geometry_device.cpp)
Grid Geometry
---------------------
[![][imgGridGeometry]](https://github.com/embree/embree/tree/master/tutorials/grid_geometry)
This tutorial demonstrates the use of the memory efficient grid
primitive to handle highly tessellated and displaced geometry.
[Source Code](https://github.com/embree/embree/tree/master/tutorials/grid_geometry)
Point Geometry
---------------------
[![][imgPointGeometry]](https://github.com/embree/embree/blob/master/tutorials/point_geometry/point_geometry_device.cpp)
This tutorial demonstrates the use of the three representations
of point geometry.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/point_geometry/point_geometry_device.cpp)
Motion Blur Geometry
--------------------
[![][imgMotionBlurGeometry]](https://github.com/embree/embree/blob/master/tutorials/motion_blur_geometry/motion_blur_geometry_device.cpp)
This tutorial demonstrates rendering of motion blur using the
multi-segment motion blur feature. Shown is motion blur of a triangle mesh,
quad mesh, subdivision surface, line segments, hair geometry, Bézier
curves, instantiated triangle mesh where the instance moves,
instantiated quad mesh where the instance and the quads move, and user
geometry.
The number of time steps used can be configured using the `--time-steps
<int>` and `--time-steps2 <int>` command line parameters, and the
geometry can be rendered at a specific time using the the `--time
<float>` command line parameter.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/motion_blur_geometry/motion_blur_geometry_device.cpp)
Quaternion Motion Blur
----------------------
[![][imgQuaternionMotionBlur]](https://github.com/embree/embree/blob/master/tutorials/quaternion_motion_blur/quaternion_motion_blur_device.cpp)
This tutorial demonstrates rendering of motion blur using quaternion
interpolation. Shown is motion blur using spherical linear interpolation of
the rotational component of the instance transformation on the left and
simple linear interpolation of the instance transformation on the right. The
number of time steps can be modified as well.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/quaternion_motion_blur/quaternion_motion_blur_device.cpp)
Interpolation
-------------
[![][imgInterpolation]](https://github.com/embree/embree/blob/master/tutorials/interpolation/interpolation_device.cpp)
This tutorial demonstrates interpolation of user-defined per-vertex data.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/interpolation/interpolation_device.cpp)
Closest Point
----------------------
[![][imgClosestPoint]](https://github.com/embree/embree/blob/master/tutorials/closest_point/closest_point_device.cpp)
This tutorial demonstrates a use-case of the point query API. The scene
consists of a simple collection of objects that are instanced and for several
point in the scene (red points) the closest point on the surfaces of the
scene are computed (white points). The closest point functionality is
implemented for Embree internal and for user-defined instancing. The tutorial
also illustrates how to handle instance transformations that are not
similarity transforms.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/closest_point/closest_point_device.cpp)
Voronoi
----------------------
[![][imgVoronoi]](https://github.com/embree/embree/blob/master/tutorials/voronoi/voronoi_device.cpp)
This tutorial demonstrates how to implement nearest neighbour lookups using
the point query API. Several colored points are located on a plane and the
corresponding voroni regions are illustrated.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/voronoi/voronoi_device.cpp)
Collision Detection
----------------------
[![][imgCollision]](https://github.com/embree/embree/blob/master/tutorials/collide/collide_device.cpp)
This tutorial demonstrates how to implement collision detection using
the collide API. A simple cloth solver is setup to collide with a sphere.
The cloth can be reset with the `space` bar. The sim stepped once with `n`
and continuous simulation started and paused with `p`.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/collide/collide_device.cpp)
BVH Builder
-----------
This tutorial demonstrates how to use the templated hierarchy builders
of Embree to build a bounding volume hierarchy with a user-defined
memory layout using a high-quality SAH builder using spatial splits, a
standard SAH builder, and a very fast Morton builder.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/bvh_builder/bvh_builder_device.cpp)
BVH Access
-----------
This tutorial demonstrates how to access the internal triangle
acceleration structure build by Embree. Please be aware that the
internal Embree data structures might change between Embree updates.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/bvh_access/bvh_access.cpp)
Find Embree
-----------
This tutorial demonstrates how to use the `FIND_PACKAGE` CMake feature
to use an installed Embree. Under Linux and macOS the tutorial finds
the Embree installation automatically, under Windows the `embree_DIR`
CMake variable must be set to the following folder of the Embree
installation: `C:\Program Files\Intel\Embree3`.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/find_embree/CMakeLists.txt)
Next Hit
-----------
This tutorial demonstrates how to robustly enumerate all hits along
the ray using multiple ray queries and an intersection filter
function. To improve performance, the tutorial also supports
collecting the next N hits in a single ray query.
[Source Code](https://github.com/embree/embree/blob/master/tutorials/next_hit/next_hit_device.cpp)
[Embree API]: #embree-api
[Embree Tutorials]: #embree-tutorials
[Ray Layout]: #ray-layout
[Extending the Ray Structure]: #extending-the-ray-structure
[Embree Example Renderer]: https://embree.github.io/renderer.html
[Triangle Geometry]: #triangle-geometry
[Stream Viewer]: #stream-viewer
[User Geometry]: #user-geometry
[Instanced Geometry]: #instanced-geometry
[Multi Level Instancing]: #multi-level-instancing
[Intersection Filter]: #intersection-filter
[Hair]: #hair
[Curves]: #bézier-curves
[Subdivision Geometry]: #subdivision-geometry
[Displacement Geometry]: #displacement-geometry
[Quaternion Motion Blur]: #quaternion-motion-blur
[BVH Builder]: #bvh-builder
[Interpolation]: #interpolation
[Closest Point]: #closest-point
[Voronoi]: #voronoi
[imgHalfEdges]: https://embree.github.io/images/half_edges.png
[imgTriangleUV]: https://embree.github.io/images/triangle_uv.png
[imgQuadUV]: https://embree.github.io/images/quad_uv.png
[imgTriangleGeometry]: https://embree.github.io/images/triangle_geometry.jpg
[imgDynamicScene]: https://embree.github.io/images/dynamic_scene.jpg
[imgUserGeometry]: https://embree.github.io/images/user_geometry.jpg
[imgViewer]: https://embree.github.io/images/viewer.jpg
[imgViewerStream]: https://embree.github.io/images/viewer_stream.jpg
[imgInstancedGeometry]: https://embree.github.io/images/instanced_geometry.jpg
[imgMultiLevelInstancing]: https://embree.github.io/images/multi_level_instancing.jpg
[imgIntersectionFilter]: https://embree.github.io/images/intersection_filter.jpg
[imgPathtracer]: https://embree.github.io/images/pathtracer.jpg
[imgHairGeometry]: https://embree.github.io/images/hair_geometry.jpg
[imgCurveGeometry]: https://embree.github.io/images/curve_geometry.jpg
[imgSubdivisionGeometry]: https://embree.github.io/images/subdivision_geometry.jpg
[imgDisplacementGeometry]: https://embree.github.io/images/displacement_geometry.jpg
[imgGridGeometry]: https://embree.github.io/images/grid_geometry.jpg
[imgPointGeometry]: https://embree.github.io/images/point_geometry.jpg
[imgMotionBlurGeometry]: https://embree.github.io/images/motion_blur_geometry.jpg
[imgQuaternionMotionBlur]: https://embree.github.io/images/quaternion_motion_blur.jpg
[imgInterpolation]: https://embree.github.io/images/interpolation.jpg
[imgClosestPoint]: https://embree.github.io/images/closest_point.jpg
[imgVoronoi]: https://embree.github.io/images/voronoi.jpg
[imgCollision]: https://embree.github.io/images/collide.jpg
|