Russian

665 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
665
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Russian

  1. 1. . “ ”( ) “ ”( 7) 3D- . .( 7-112) . . . . . .( 7) 1 2009 .
  2. 2. 3D- - . - - ( 3D- - ). - , - 3D- , - . : - , . , - . , : 1) - 3D- , ; 2) . - . ( . . 3D- ) . - 1.5-3 , - , CPU. 1
  3. 3. 4 1. 6 1.1. 6 1.2. 7 1.3. 11 1.4. 14 1.5. 15 1.6. 18 1.7. CPU 19 2. 22 2.1. BVH 22 2.1.1. 22 2.1.2. BVH CPU 24 2.2. 27 2.2.1. SIMD- 29 2.2.2. 32 2.2.3. 34 2.2.4. SIMD- 34 2.2.5. CPU 36 2.3. BVH - 36 2.3.1. 37 2.3.2. 39 2.3.3. 42 2.3.4. BVH 44 2.3.5. 45 2.3.6. 47 2.4. 48 2.4.1. 51 2.4.2. 52 3. 55 3.1. - 55 3.2. 55 2
  4. 4. 3.2.1. 55 3.2.2. 56 3.2.3. 56 3.2.4. 58 3.2.5. 59 3.2.6. 59 4. 60 4.1. 60 4.2. , 61 4.3. BVH 63 4.3.1. 63 4.3.2. , 67 4.3.3. CPU 68 4.3.4. 69 4.3.5. , 71 4.4. 72 4.4.1. 72 4.4.2. CPU 77 4.4.3. 78 4.4.4. , 79 81 83 3
  5. 5. 3D- . 3D- - (GPU, graphics proc- essing unit) - . , - . - . ( . . , – ). , - . - 3D- , ( – 3D- ). - , . . 3D- - . , , , . , - , . . . - , . , . - 4
  6. 6. . - , - 3D- , . - - . , , , 3D- . 3D- . , , - . CPU. • - , , - 3D- . • - . , . - - ; , - . , , - . 5
  7. 7. 1. 1.1. 3D- . , . : , , NURBS, - . 3D- , - - , ( - ). . - - 3D- , . . , ( , 3D- ). . - 3D- , ( . . 3D- ). , 3D- , 3D- . . - , . SAH- . SAH- (Surface Area Heuristic) , SAH , . . - 3D- ( . SAH- [GS87; Hav01]). AABB. - 3D- . AABB X = xa, X = xb, Y = ya, Y = yb, Z = za, Z = zb ( . . ) , 3D- [xa, xb], [ya, yb], [za, zb]. AABB 3D- min/max . BVH. Bounding Volume Hierarchy – - ( ) 3D- , - . SAH- , AABB . 6
  8. 8. . 3D- ( - ‘ ’, ). SIMD. Single Instruction Multiply Data. SIMD- - : , ( ) 4 ( - CPU). SIMD- – , - . 1.2. , , - . [Whi80; Shi00; CPC84]. . . ( . . 1.1) - – . . . . - - , , . , , , . ( - ), ( . . 1.1). . 1.1: . «1» - , «3» - , «2» - . 7
  9. 9. - . , . , . , , . , . ( -) , , . . – , - , – . , . . . ( . . 1.2) Int Ray ( – ): Pwri Pwri Int ( Ray ) = K C ∑ C i dot ( N , L ) + K ∑ C i dot ( R ,V ) P + K r Int ( RayR ) (1.1) d m 2 i s 2 i i Ti i Ti Int (Ray ) - , . Int ( Ray ) ∈ [0..1] dot ( a, b) - C - .C ∈ [0..1] m m K - . K ∈ [0, ∞) d d C - i- . C ∈ [0..1] i i Pwr - i- . Pwr ∈ [0, ∞) i i T - i- i N - L - , i- i K - . K ∈ [0, ∞) s s R - i V - , P - . P ∈ [1, ∞) K - . K ∈ [0,1] r r RayR - , Ray 8
  10. 10. , , . - . . - . , RGB. - : , - . (1.1) . . 1.2: ( ). Int Int: d Pwri Int =K C ∑ Ci dot ( N , Li ) (1.2) Ti2 d d m i - π : K ⋅ I l ⋅ cos α , α ∈ [0, ] - d 2 Pwri , Il = Ci - Ti 2 ( . . 1.2). L, N– . cos α = dot ( L, N ) . C Int Int : s Pwri Int = K ∑ C dot ( Ri ,V ) P (1.3) s s 2 i i Ti 9
  11. 11. , . - . R - - , V- , . - : K ⋅ I l ⋅ cos P y , s γ - R V. P - « » « » . R V- , : K ⋅ I l ⋅ dot ( R , V ) P . s V = − Ray.Dir , Ray.Dir - R = − L + 2 ⋅ dot ( L , N ) ⋅ N K , K , K - , . a d s . , , . - , , - . . 1.3 - . . 1.3: . - , . - 10
  12. 12. . - , 3D- [CPC84]. 1.3. . 3D- , - . - , . , - 3D- . , . - 3D- , . - . - SAH (Surface Area Heuristic [Hav01, GS87]). , - N, : SA( N L ) SA( N R ) SAHCost ( N ) = ⋅ Count ( N L ) + ⋅ Count ( N R ) (1.4) SA( N ) SA( N ) : SA(N) – AABB(N) N; Count(N) – N; NL NR – N. (1.4) [Hav01]. , - . - . (1.4). - . , - [Wal07; WBS07] [HMFS07; Gar08]. - (1.4), , . 11
  13. 13. 3D- . 3D- , 3D- . , ( . . 1.4). . 1.4: 3D- . : 1. : (n), n– . 2. (3D- ). 3. 3D- - . : 1. ( ), 3D- . - ‘ ’ . . 3D- , . kd-tree. 3D- , 3D- , - X = divx, Y = divy, Z = divz ( . . 1.5). - divx, divy, divy , - . SAH- [GS87; Hav01]. . 1.5: kd-tree. 12
  14. 14. : 1. 3D- . 2. 3D- - . 3. SAH- . : 1. SAH- : O(n * log n), n– - . 2. - , . . kd-tree . 3. ‘ ’ ( kd-tree 1- ). . kd-tree 1 2 - BVH. 3 . 2 3 BVH. BVH (bounding volume hierarchy). ( ) 3D- , ( . . 1.6). BVH - AABB . - . BVH, SAH, AABB , - . . 1.6: BVH. : 1. . BVH - , kd-tree. 2. SAH- - ( ). 13
  15. 15. BVH - , , – BVH ‘ ’ ( . . ), kd-tree. : 1. SAH- : O(n * log n), n– - . 2. 3D- . 3. 3D- BVH. 4. AABB ( , . . 1.6). . kd-tree BVH 1. 3 4 BVH kd-tree ( 2), . . kd-tree. 3D- BVH, . . ( - ). 1.4. 3D- , - ( . . 1.7a). . 1.7: . - , . . ( BVH). , - 14
  16. 16. , - BVH, AABB . ( - 3D- ) - . , . - - . ‘ ’ ( . . 1.7b), . - , - ( . . 1.7c), . . , 3D- BVH . . , . . , . 1.5. [Whi80; CPC84; Shi00] - , , , [Dut03]. , - . , (BVH) [KK86], kd-tree [Hav01], 3D- 5D- [AK87], - 3D- , (log n), n– 3D- ( ). 3D- [Wal07; HM08]. - . . - 15
  17. 17. . - [RSH05; WBS07; HM08]. , , , - . , ( 3D- ) , . , . - SIMD- - [Wal04] [Res07]. , . - BVH SIMD- [DHK08; WBB08]. , SIMD- 100%, - . , SIMD- [SCS*08] ( 16- ). . [PKGH97] , . [GR08] , - . , - . [ORM08] , / - . [BWB08] - , / - , , SIMD- 16
  18. 18. , ( BVH). ( , - , ) - ( ) - SIMD. . - - . - [WMG*07]. BVH kd-tree , - , 2 - ( . . ). - [WBKP08]. [Wal07] BVH - AABB. BVH - , , 3D- AABB . [WK06] 3D- . 1D - AABB (3D- )( BIH – bounding interval hierarchy). , kd-tree. , [HMFS07], , 3D- . - , , , - . , - . , . [YCM07] BVH, . , - 17
  19. 19. , , - . [Gar08] BVH ( , 3D- ). - ( AABB - [WBS07]; BVH - BVH; BVH, - ). , BVH. - , BVH - ( . . ). [IWRP06; SSK07] ( 3D- kd-tree) CPU, AMD Opteron Intel Core 2. [WIP08] - BVH CPU. , - CPU , - , BVH . ( ), ( ) - . ( . . ), - . [ZHWG08; LGS*09] - kd-tree BVH - (GPU, ) [NVI]. , - . , - CPU. 1.6. [NBS06; SNB07] – z- , - 18
  20. 20. . [SSGH01]. - (level of detail, LOD). [GWH01] - (radiosity – ), - , . [GWH01] - 3D- . [GFW*06; GFSS06] - , , 3D- . - ; - kd-tree, . , , . - kd-tree, , ( ) kd-tree - . [LYTM08] 2- - . - ( – ), . (kd-tree BVH) , . - - , . 1.7. CPU , , - . 3D- , , - . . - . - / , , - 19
  21. 21. . . - . . 1.8 Intel Core 2 , Core 2 Duo, Core 2 Quad. - (SMP ). Pen- tium III CPU (Intel, AMD) SIMD- , . . 1.8: SMP CPU. - CPU . , - ( . . CPU), - . ( . . 1.8 6Gb/sec). ( ). 20
  22. 22. - ( . . , - ). - BVH ( . 2.3). - CPU, - ( . 2.2) - ( . 2.4) . SIMD- , . . - . , - SIMD- . , . . - , . CPU GPU ( ) [NVI] , - - . , GPU , . . GPU , CPU. CPU. - CPU [Ben06]. 21
  23. 23. 2. - BVH [Wal07] (bounding volume hierarchy, - ) [WBS07] SIMD- [Wal04; Ben06; Res07]. BVH - , . 2.1. BVH BVH [Wal07]. ‘ ’. - , . . ( - , ), SAH- BVH , . , - CPU. 2.1.1. 3D- 2 . - ( ) ( ) ( 4 32- ). BVH, - AABB. - SAH ( 1.3, (1.4)). - SAH - ( ) AABB N ( . . 2.1). AABB N , . N AABB . , i, i = int(0.999 K (x – a) / (b – a)), x – , int() – . - AABB . 22
  24. 24. AABB, , - ( . . 2.1). K-1 2 - ( , NL N R, . 2.1). - SAH (1.4) , . . - SA(NL), SA(NR) Count(NL), Count(NR). SA(NL) Count(NL) AABB , . SA(NR) Count(NR). K-1 SAH - , SAH. - , NL (NR), ( ) . . 2.1: ( ) N. AABB N K . - K-1 , . SAH , SAH. [Wal07] , K = 32, BVH , , . BVH , . . K, - , 2 . 23
  25. 25. SAH (1.4) . BVH - SAH (1.4) - ( SAH). 2.1.2. BVH CPU BVH, . - , . , BVH SMP , - ( . 1.7). – - BVH , / . BVH . , BVH , . . BVH - , . - 3D- BVH. - M , - 2M – 1 ( M – 1). - BVH . , . . . BVH , - 2 . [Wal07]. , , , BVH . 3D- . , - AABB , . , 1/6, [WK06]. . : AABB , . 24
  26. 26. . 2.2: 3D- . C 3D- , 3D- . T . T , /T 3D- ( . . 2.2). , , - : BMin, BMax – AABB 3D- . R = ( Rx , Ry , Rz ) – . X– . R ⋅ 0.999 F = ⋅ ( X − BMin ) – , , . BMax − BMin Id.x = int(F.x), Id.y = int(F.y), Id.z = int(F.z) – . : int() . AABB . , - . ( . 25
  27. 27. . 2.2). - . , . . . 3D- AABB. , - ‘ ’ BVH ( . 2.1). - . ‘ ’ BVH, 3D- ( . . ). ( - ). . - , . - - . : 1. BVH. BVH ( 3D- ) SAH, AABB , - . 2. 3D- - 3D- . . - BVH - . BVH . : 1. BVH - . - . BVH : , . . - . , - . 26
  28. 28. 2. [Wal07] BVH 5.5- 8 Xeon. , - , CPU . [Wal07] BVH, BVH ( . 2.1) ‘ ’ . - BVH. , , - . - 1 , - BVH , - CPU. 2.2. 3D- , - ( . . 2.3). kd-tree BVH [RSH05; WBS07] . . 2.3: 3D- , . . , - (3D- ). ‘ ’. , , - 27
  29. 29. 3D- . , , . , , BVH, - AABB . , ( . . 2.3), - , ( . . - ( ) ). [WBS07] ( . 2.1) - BVH. , 64, 256, 1024 . 2.1. BVH int BoxTest(int ActiveRayID, PACKET P, BVH_NODE * B) { // если пирамида пакета точно не пересекает охватывающий шестигранник if(AABBCulling(P.Frustum, B->AABB)) return P.N; // если пирамида пакета пересекает AABB, // то проверяются все отдельные лучи пакета до поиска первого пересечения for(int i = ActiveRayID; i < P.N; i++) { if(RayAABBTest(P.Ray[i], B->AABB)) // если луч пересекает AABB, см. 2.2.1 return i; } return P.N; } void PacketTraversal(BVH Bvh, PACKET P) { prepare(P.Frustum); // инициализация охватывающей пирамиды, см. в разделе 2.2.2 BVH_NODE * B = Bvh.Root; // текущий узел BVH int ActiveRayID = 0; // первый активный луч Init(Stack); while(true) { if((ActiveRayID = BoxTest(ActiveRayID, P, B)) < P.N) { // пакет пересекает AABB текущего узла B if(B.IsLeaf){ // если лист BVH // тест на пересечение с лучами для всех треугольников в листе for(all triangles in leaf) for(int i = ActiveRayID; i < P.N; i++){ // для всех лучей пакета RayTriangleTest(B->Tri[t], P.Ray[i]); // поиск ближайшего треугольника, см. 2.2.1 } else { // спуск глубже в BVH // отложить дальний узел их двух потомков узла B // (‘дальний узел’ - по отношению к основаниям пакета лучей) push(Stack, [ActiveRayID, FarChildNodePtr(B, P)]); // 2 значения в стек B = NearChildNodePtr(B, P); // а пока тестировать ближний узел continue; } } if(Stack.empty) break; [B, ActiveRayID] = pop(Stack); // извлечь 2 значения из стека } } ( - 3D- ) - 28
  30. 30. . CPU: BVH , . , CPU, . . BVH. 2.2.1. SIMD- [Wal04] SIMD [Intel-b] - ( 4 ) 4- . SIMD- - 4- ( float, 4 ). ( __m128, 16 ), , - 4- . - SoA ( ), . . 2.4. . 2.4: , SoA . 2.4, forg[0] (forg[1], forg[2]) x- (y-, z- ) . fdir . fT +1e+10, . ti orgi i- diri , . - trii. . 2.4, - 4 , SIMD- . 29
  31. 31. SIMD- AABB ( RayAABBTest, . 2.1). // ri – индекс SIMD-луча // P.Org4[0] = (__m128 *) forg[0]; и т.д. – см. рис. 2.4. P.T4 = (__m128 *) fT; // iDir4 = 1 / P.Dir4, т.е. обратное значение направления предварительно вычислено // sse_0 = [0, 0, 0, 0] // операторы *, -, + выполняют _mm_mul_ps, _mm_sub_ps, _mm_add_ps void RayAABBTest(unsigned int ri, PACKET P, AABB BV) { // см. Алгоритм 2.1 // эту репликацию можно вынести за скобки (за верхний цикл по лучам) const __m128 BV4[6] = {_mm_set_ps1(BV[0]),_mm_set_ps1(BV[1]),_mm_set_ps1(BV[2]), _mm_set_ps1(BV[3]), _mm_set_ps1(BV[4]), _mm_set_ps1(BV[5])}; const __m128 Org[3] = {P.Org4[0][ri], P.Org4[1][ri], P.Org4[2][ri]}; const __m128 iDir[3] = {P.iDir4[0][ri], P.iDir4[1][ri], P.iDir4[1][ri]}; const __m128 T[6] = {(BV4[0] - Org[0]) * iDir[0], (BV4[1] - Org[1]) * iDir[1], (BV4[2] - Org[2]) * iDir[2], (BV4[3] - Org[0]) * iDir[0], (BV4[4] - Org[1]) * iDir[1], (BV4[5] - Org[2]) * iDir[2]}; const __m128 taX = _mm_min_ps(T[0], T[3]), tbX = _mm_max_ps(T[0], T[3]); const __m128 taY = _mm_min_ps(T[1], T[4]), tbY = _mm_max_ps(T[1], T[4]); const __m128 taZ = _mm_min_ps(T[2], T[5]), tbZ = _mm_max_ps(T[2], T[5]); const __m128 ta = _mm_max_ps(_mm_max_ps(taX, taY), _mm_max_ps(taZ,sse_0)); const __m128 tb = _mm_min_ps(_mm_min_ps(tbX, tbY), _mm_min_ps(tbZ,P.T4[ri])); if(_mm_movemask_ps(_mm_cmple_ps(ta, tb))) // если какой-то луч пересекает AABB return true; // то считается, что SIMD-луч пересекает AABB return false; } SIMD- ( RayTriangleTest, . 2.1). [Wal04] ( . . 2.5). X B Y B` H A ab` C H` Z A` ac` dir C` org . 2.5: [org,dir] 2D- YZ. u, v t. , X YZ ( . . 2.5) 2D- . : , - . Cross( a, b) – , Dot(a, b) – . [A, B, ] – , [org, dir] – ( ). ab = B − A , ac = C − A , N = Cross( ab, ac) , N `= N / N . x = [1, N . y / N . x, N . z / N . y ] - 1 ( N`): 30
  32. 32. t = ( Dot( A, N `) − Dot(org , N `)) / Dot(dir, N `) = ( DAN − Dot(org , N `)) / Dot( dir, N `) H = org + t ⋅ dir – . YZ: H `= [0, H . y, H . z ] , A`= [0, A. y , A. z ] , ab`= [0, ab. y , ab. z ] , ac`= [0, ac. y , ac. z ] , ah`= H `− A` . H − A = u ⋅ ab + v ⋅ ac , u, v – H. ah`= u ⋅ ab`+ v ⋅ ac` , . . u v . ah`. y = u ⋅ ab`. y + v ⋅ ac`. y ah`. z = u ⋅ ab`. z + v ⋅ ac`. z , : ah`. y ⋅ ac`.z − ah`.z ⋅ ac`. y ah`. y ⋅ ac`.z − ah`.z ⋅ ac`. y u= = ab`. y ⋅ ac`.z − ab`.z ⋅ ac`. y N .x ab`. y ⋅ ah`.z − ab`.z ⋅ ah`. y ab`. y ⋅ ah`.z − ab`.z ⋅ ah`. y v= = , : ab`. y ⋅ ac`.z − ab`.z ⋅ ac`. y N .x ac`.z − ac`. y A`.z ⋅ ac`. y − A`. y ⋅ ac`.z u = H `. y ⋅ + H `.z ⋅ + = H `. y ⋅ KUY + H `.z ⋅ KUZ + KUD N .x N .x N .x − ab`.z ab`. y A`. y ⋅ ab`.z − A`.z ⋅ ab`. y v = H `. y ⋅ + H `.z ⋅ + = H `. y ⋅ KVY + H `.z ⋅ KVZ + KVD N .x N .x N .x 0≤t, , . 0 ≤ u , 0 ≤ v , u + v ≤1, H . // P.Org4[0] = (__m128 *) forg[0]; и т.д. - см. рис. 2.4 // P.T4 = (__m128 *) fT; P.Tri4 = (__m128i *) ftri; // sse_0 = [0, 0, 0, 0], sse_1 = [1, 1, 1, 1] // __m128i NewTri4 = [TriID, TriID, TriID, TriID], где TriID – индекс треугольника A,B,C // операторы *, -, + выполняют _mm_mul_ps, _mm_sub_ps, _mm_add_ps // _mm_inverse_ps(a) = 1 / a (быстрое вычисление обратного значения) void PacketTriangleTest(float3 A, float3 B, float3 C, PACKET P) { // SIMD-тест из [Wal04] // Определить (X,Y,Z) (проекция вдоль X на плоскость YZ), где тройка может принимать значения: // (0,1,2), (1,2,0) или (2,1,0), где 0..2 – индексы для выбора значений компонент 3D данных. // Предварительно здесь вычислить DAN, N`, KUY, KUZ, KUD, KVY, KVZ, KVD for(int ri = 0; ri < P.N; ri++) { const __m128 Org[3] = {P.Org4[0][ri], P.Org4[1][ri], P.Org4[2][ri]}; const __m128 Dir[3] = {P.Dir4[0][ri], P.Dir4[1][ri], P.Dir4[2][ri]}; const __m128 Nom = DAN4 - Org[X] – N`[Y] * Org[Y] - N`[Z] * Org[Z] const __m128 T = Nom * _mm_inverse_ps(Dir[X] + N`[Y] * Dir[Y] + N`[Z] * Dir[Z]); __m128 mask = _mm_and_ps(_mm_cmplt_ps(sse_0, T), _mm_cmple_ps(T, P.T4[ri])); if(!_mm_movemask_ps(mask4)) continue; // 0 < t < сохранённый t const __m128 HY = Org[Y] + T * Dir[Y], HZ = Org[Z] + T * Dir[Z]; const __m128 U = KUY4 * HY + KUZ4 * HZ + KUD4; mask = _mm_and_ps(mask, _mm_cmple_ps(sse_0, U)); if(!_mm_movemask_ps(mask)) continue; const __m128 V = KVY4 * HY + KVZ4 * HZ + KVD4; mask = _mm_and_ps(mask, _mm_and_ps(_mm_cmple_ps(sse_0, V), _mm_cmple_ps(U + V, sse_1))); if(!_mm_movemask_ps(mask)) continue; // если есть какое-то пересечение, то обновить t и ссылку на треуг-ник tri для SIMD-луча // на основе полученной маски const __m128i imask = _mm_castps_si128(mask); P.T4[ri] = _mm_or_ps(_mm_and_ps(mask,T),_mm_andnot_ps(mask,P.T4[ri])); P.Tri4[ri] = _mm_or_si128(_mm_and_si128(imask,NewTri4),_mm_andnot_si128(imask,P.Tri4[ri])); } } 31
  33. 33. 2.2.2. ( . . 2.3) 2- , ( . 2.3 YZ) [Res07; ORM08]. . . , - ( , ) - . . 2.3 - X. : - , X- ( +, -). X- , 2, . X- - ab ( a < b), AABB 3D- ( . . 2.6). a b AABB 3D- X . 2.6: 1D- X. X=a X=b. X=a X=b - ( Y Z, . 2.3). 4- [a, y00, z00], [a, y01, z00], [a, y00, z01], [a, y01, z01], 4- [b, y10, z10], [b, y11, z10], [b, y10, z11], [b, y11, z11]. , . 2.3. - ( . . 2.7): N0 = [y00-y10, b-a, 0], N1 = [z00-z10, 0, b-a], N2 = [y11-y01, a-b, 0], N3 = [z11-z01, 0, a-b]. 32
  34. 34. BV[3+Y] BV[3+Z] 2D AABB BV[X] BV[3+X] BV[X] BV[3+X] Y Z BV[Y] BV[Z] y11 z11 y01 N2 z01 N3 2D AABB y00 N0 z00 N1 y10 z10 a b X a b X . 2.7: 2D- ( . . 2.3) AABB. . [Vx, Vy, Vz] - N0 , : Dot( N 0 , [Vx,Vy,Vz ] − [a, y 00 , z 00 ]) = Vx ⋅ ( y 00 − y10 ) + Vy ⋅ (b − a ) + a ⋅ y10 − b ⋅ y 00 Vx ⋅ ( y 00 − y10 ) /(b − a ) + (Vy + a ⋅ y10 − b ⋅ y 00 ) /(b − a ) < 0 . : q 0 = [b − a , b − a , b − a , b − a ] , q2 = [ y00 − y10 , z00 − z10 , y11 − y01 , z11 − z01 ] / q0 , q1 = [a ⋅ y10 − b ⋅ y00 , a ⋅ z10 − b ⋅ z00 , b ⋅ y01 − a ⋅ y11 , b ⋅ z01 − a ⋅ z11 ] / q0 , SIMD- ([Res07]): // операторы *, -, + выполняют _mm_mul_ps, _mm_sub_ps, _mm_add_ps // Тройка (X,Y,Z) (где X - базовая ось пакета лучей) может принимать значения: // (0,1,2), (1,2,0) или (2,1,0), где 0..2 – индексы для выбора значений компонент 3D данных int VertexCulling(FRUSTUM F, float3 V) { const int BitCull56 = (V[F.X] < F.a ? 0x10 : 0) | (V[F.X] > F.b ? 0x20 : 0); const __m128 ZYZY = _mm_set_ps(-V[F.Z], -V[F.Y], V[F.Z], V[F.Y]); const int BitCull4x = _mm_movemask_ps(F.q1 + _mm_set_ps1(V[F.X]) * F.q2 + ZYZY); // Если битовый код содержит 1 в некоторой позиции, то точка V лежит по внешнюю сторону // (т.е. отсечена) от соответственной плоскости пирамиды // Битовый код нужен для отсечения треугольников от пирамиды. return BitCull56 | BitCull4x; } AABB ( 6 ) AABB . AABB 1D- , - float BV[6] , . 2.7. - BV ( AABB) - : S0 x = y00 − y10 < 0 ? X : 3 + X S0 y = b − a < 0 ? Y : 3 + Y ; 33

×