kernels.cl 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. #pragma OPENCL EXTENSION cl_khr_fp64 : enable
  2. typedef struct {
  3. double w;
  4. double x;
  5. double y;
  6. double z;
  7. } RI_vector_4;
  8. typedef struct {
  9. double x;
  10. double y;
  11. double z;
  12. } RI_vector_3;
  13. typedef struct {
  14. double x;
  15. double y;
  16. } RI_vector_2;
  17. typedef struct {
  18. RI_vector_3 position_0, position_1, position_2;
  19. RI_vector_3 normal_0, normal_1, normal_2;
  20. RI_vector_2 uv_0, uv_1, uv_2;
  21. short min_screen_x, max_screen_x, min_screen_y, max_screen_y;
  22. uchar should_render;
  23. ushort texture_width, texture_height;
  24. uint texture_index;
  25. } RI_renderable_face;
  26. typedef struct {
  27. RI_vector_3 position_0;
  28. RI_vector_3 position_1;
  29. RI_vector_3 position_2;
  30. RI_vector_3 normal_0;
  31. RI_vector_3 normal_1;
  32. RI_vector_3 normal_2;
  33. RI_vector_2 uv_0;
  34. RI_vector_2 uv_1;
  35. RI_vector_2 uv_2;
  36. uchar should_render;
  37. } RI_face;
  38. typedef struct {
  39. RI_vector_3 position;
  40. RI_vector_4 rotation;
  41. RI_vector_3 scale;;
  42. uchar active;
  43. uchar has_normals;
  44. uchar has_uvs;
  45. ushort material_index;
  46. uint face_index;
  47. uint face_count;
  48. } RI_actor;
  49. typedef struct {
  50. RI_vector_3 position;
  51. RI_vector_4 rotation;
  52. float FOV, min_clip, max_clip;
  53. } RI_camera;
  54. // value-wise multiplacation.
  55. // multiply the whole vector by 1 value
  56. void vector_2_times(RI_vector_2 *vector, double value){
  57. vector->x *= value;
  58. vector->y *= value;
  59. }
  60. void global_vector_2_times(__global RI_vector_2 *vector, double value){
  61. vector->x *= value;
  62. vector->y *= value;
  63. }
  64. // set all values of a vector 3
  65. void vector_3_memset(RI_vector_3 *vector, double value){
  66. vector->x = value;
  67. vector->y = value;
  68. vector->z = value;
  69. }
  70. // value-wise multiplacation.
  71. // multiply the whole vector by 1 value
  72. void vector_3_times(RI_vector_3 *vector, double value){
  73. vector->x *= value;
  74. vector->y *= value;
  75. vector->z *= value;
  76. }
  77. void global_vector_3_times(__global RI_vector_3 *vector, double value){
  78. vector->x *= value;
  79. vector->y *= value;
  80. vector->z *= value;
  81. }
  82. // hadamard multiplacation.
  83. // multiply each value of one vector with the matching one on the other vector
  84. void vector_3_hadamard(RI_vector_3 *multiplicand, RI_vector_3 multiplicator){
  85. multiplicand->x *= multiplicator.x;
  86. multiplicand->y *= multiplicator.y;
  87. multiplicand->z *= multiplicator.z;
  88. }
  89. void global_vector_3_hadamard(__global RI_vector_3 *multiplicand, RI_vector_3 multiplicator){
  90. multiplicand->x *= multiplicator.x;
  91. multiplicand->y *= multiplicator.y;
  92. multiplicand->z *= multiplicator.z;
  93. }
  94. // "hadamard" addition.
  95. // add each value of one vector with the matching one on the other vector
  96. void vector_2_element_wise_add(RI_vector_2 *addend_a, RI_vector_2 addend_b){
  97. addend_a->x += addend_b.x;
  98. addend_a->y += addend_b.y;
  99. }
  100. void global_vector_2_element_wise_add(__global RI_vector_2 *addend_a, RI_vector_2 addend_b){
  101. addend_a->x += addend_b.x;
  102. addend_a->y += addend_b.y;
  103. }
  104. // "hadamard" addition.
  105. // add each value of one vector with the matching one on the other vector
  106. void vector_3_element_wise_add(RI_vector_3 *addend_a, RI_vector_3 addend_b){
  107. addend_a->x += addend_b.x;
  108. addend_a->y += addend_b.y;
  109. addend_a->z += addend_b.z;
  110. }
  111. void global_vector_3_element_wise_add(__global RI_vector_3 *addend_a, RI_vector_3 addend_b){
  112. addend_a->x += addend_b.x;
  113. addend_a->y += addend_b.y;
  114. addend_a->z += addend_b.z;
  115. }
  116. // "hadamard" subtraction.
  117. // subtraction each value of one vector with the matching one on the other vector
  118. void vector_3_element_wise_subtract(RI_vector_3 *minuend, RI_vector_3 subtrahend){
  119. minuend->x -= subtrahend.x;
  120. minuend->y -= subtrahend.y;
  121. minuend->z -= subtrahend.z;
  122. }
  123. void global_vector_3_element_wise_subtract(__global RI_vector_3 *minuend, RI_vector_3 subtrahend){
  124. minuend->x -= subtrahend.x;
  125. minuend->y -= subtrahend.y;
  126. minuend->z -= subtrahend.z;
  127. }
  128. // conjugate a quaterion.
  129. // (flip the sign of the x, y, z values)
  130. void quaternion_conjugate(RI_vector_4* quaternion){
  131. quaternion->x *= -1.0;
  132. quaternion->y *= -1.0;
  133. quaternion->z *= -1.0;
  134. }
  135. void globla_quaternion_conjugate(__global RI_vector_4* quaternion){
  136. quaternion->x *= -1.0;
  137. quaternion->y *= -1.0;
  138. quaternion->z *= -1.0;
  139. }
  140. // quaternion multiplacation
  141. void quaternion_multiply(RI_vector_4* a, RI_vector_4 b){
  142. double w1 = a->w; double x1 = a->x; double y1 = a->y; double z1 = a->z;
  143. double w2 = b.w; double x2 = b.x; double y2 = b.y; double z2 = b.z;
  144. double w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
  145. double x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
  146. double y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
  147. double z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
  148. *a = (RI_vector_4){w, x, y, z};
  149. }
  150. void global_quaternion_multiply(__global RI_vector_4* a, RI_vector_4 b){
  151. double w1 = a->w; double x1 = a->x; double y1 = a->y; double z1 = a->z;
  152. double w2 = b.w; double x2 = b.x; double y2 = b.y; double z2 = b.z;
  153. double w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
  154. double x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
  155. double y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
  156. double z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
  157. *a = (RI_vector_4){w, x, y, z};
  158. }
  159. // linear interpolate between 2 vectors
  160. void vector_2_lerp(RI_vector_2 vector_a, RI_vector_2 vector_b, RI_vector_2 *result, double w1){
  161. double w0 = 1.0 - w1;
  162. vector_2_times(result, 0);
  163. vector_2_times(&vector_a, w0);
  164. vector_2_times(&vector_b, w1);
  165. vector_2_element_wise_add(result, vector_a);
  166. vector_2_element_wise_add(result, vector_b);
  167. }
  168. void global_vector_2_lerp(RI_vector_2 vector_a, RI_vector_2 vector_b, __global RI_vector_2 *result, double w1){
  169. double w0 = 1.0 - w1;
  170. global_vector_2_times(result, 0);
  171. vector_2_times(&vector_a, w0);
  172. vector_2_times(&vector_b, w1);
  173. global_vector_2_element_wise_add(result, vector_a);
  174. global_vector_2_element_wise_add(result, vector_b);
  175. }
  176. // linear interpolate between 2 vectors
  177. void vector_3_lerp(RI_vector_3 vector_a, RI_vector_3 vector_b, RI_vector_3 *result, double w1){
  178. double w0 = 1.0 - w1;
  179. vector_3_memset(result, 0);
  180. vector_3_times(&vector_a, w0);
  181. vector_3_times(&vector_b, w1);
  182. vector_3_element_wise_add(result, vector_a);
  183. vector_3_element_wise_add(result, vector_b);
  184. }
  185. void global_vector_3_lerp(RI_vector_3 vector_a, RI_vector_3 vector_b, __global RI_vector_3 *result, double w1){
  186. double w0 = 1.0 - w1;
  187. global_vector_3_times(result, 0);
  188. vector_3_times(&vector_a, w0);
  189. vector_3_times(&vector_b, w1);
  190. global_vector_3_element_wise_add(result, vector_a);
  191. global_vector_3_element_wise_add(result, vector_b);
  192. }
  193. void quaternion_rotate(RI_vector_3 *position, RI_vector_4 rotation){
  194. RI_vector_4 pos_quat = {0, position->x, position->y, position->z};
  195. RI_vector_4 rotation_conjugation = rotation;
  196. quaternion_conjugate(&rotation_conjugation);
  197. quaternion_multiply(&rotation, pos_quat);
  198. quaternion_multiply(&rotation, rotation_conjugation);
  199. *position = (RI_vector_3){rotation.x, rotation.y, rotation.z};
  200. }
  201. void global_quaternion_rotate(__global RI_vector_3 *position, RI_vector_4 rotation){
  202. RI_vector_4 pos_quat = {0, position->x, position->y, position->z};
  203. RI_vector_4 rotation_conjugation = rotation;
  204. quaternion_conjugate(&rotation_conjugation);
  205. quaternion_multiply(&rotation, pos_quat);
  206. quaternion_multiply(&rotation, rotation_conjugation);
  207. *position = (RI_vector_3){rotation.x, rotation.y, rotation.z};
  208. }
  209. __kernel void transformer(__global RI_face *faces, __global RI_renderable_face *renderable_faces, double actor_x, double actor_y, double actor_z, double actor_r_w, double actor_r_x, double actor_r_y, double actor_r_z, double actor_s_x, double actor_s_y, double actor_s_z, int has_normals, int has_uvs, int face_array_offset_index, int face_count, int width, int height, double horizontal_fov_factor, double vertical_fov_factor, float min_clip, float max_clip, double camera_x, double camera_y, double camera_z, double camera_r_w, double camera_r_x, double camera_r_y, double camera_r_z, int renderable_face_offset, int face_sqrt, ushort texture_width, ushort texture_height, uint texture_index){
  210. int face_index = get_global_id(1) * face_sqrt + get_global_id(0); if (face_index >= face_count) return;
  211. RI_vector_3 current_actor_position = (RI_vector_3){actor_x, actor_y, actor_z};
  212. RI_vector_4 current_actor_rotation = (RI_vector_4){actor_r_w, actor_r_x, actor_r_y, actor_r_z};
  213. RI_vector_3 current_actor_scale = (RI_vector_3){actor_s_x, actor_s_y, actor_s_z};
  214. RI_vector_3 camera_position = (RI_vector_3){camera_x, camera_y, camera_z};
  215. RI_vector_4 camera_rotation = (RI_vector_4){camera_r_w, camera_r_x, camera_r_y, camera_r_z};
  216. __global RI_face *cur_face = &faces[face_index + face_array_offset_index];
  217. __global RI_renderable_face *cur_r_face = &renderable_faces[face_index * 2 + renderable_face_offset];
  218. // set split face not to render
  219. renderable_faces[face_index * 2 + renderable_face_offset + 1].should_render = 0;
  220. cur_r_face->should_render = 1;
  221. // cur_r_face->material = current_actor.material;
  222. cur_r_face->position_0 = cur_face->position_0;
  223. cur_r_face->position_1 = cur_face->position_1;
  224. cur_r_face->position_2 = cur_face->position_2;
  225. cur_r_face->normal_0 = cur_face->normal_0;
  226. cur_r_face->normal_1 = cur_face->normal_1;
  227. cur_r_face->normal_2 = cur_face->normal_2;
  228. if (has_uvs){
  229. cur_r_face->uv_0 = cur_face->uv_0;
  230. cur_r_face->uv_1 = cur_face->uv_1;
  231. cur_r_face->uv_2 = cur_face->uv_2;
  232. }
  233. cur_r_face->texture_width = texture_width;
  234. cur_r_face->texture_height = texture_height;
  235. cur_r_face->texture_index = texture_index;
  236. // scale
  237. global_vector_3_hadamard(&cur_r_face->position_0, current_actor_scale);
  238. global_vector_3_hadamard(&cur_r_face->position_1, current_actor_scale);
  239. global_vector_3_hadamard(&cur_r_face->position_2, current_actor_scale);
  240. // actor rotation
  241. global_quaternion_rotate(&cur_r_face->position_0, current_actor_rotation);
  242. global_quaternion_rotate(&cur_r_face->position_1, current_actor_rotation);
  243. global_quaternion_rotate(&cur_r_face->position_2, current_actor_rotation);
  244. global_quaternion_rotate(&cur_r_face->normal_0, current_actor_rotation);
  245. global_quaternion_rotate(&cur_r_face->normal_1, current_actor_rotation);
  246. global_quaternion_rotate(&cur_r_face->normal_2, current_actor_rotation);
  247. // object position
  248. global_vector_3_element_wise_add(&cur_r_face->position_0, current_actor_position);
  249. global_vector_3_element_wise_add(&cur_r_face->position_1, current_actor_position);
  250. global_vector_3_element_wise_add(&cur_r_face->position_2, current_actor_position);
  251. // camera position & rotation
  252. global_vector_3_element_wise_subtract(&cur_r_face->position_0, camera_position);
  253. global_vector_3_element_wise_subtract(&cur_r_face->position_1, camera_position);
  254. global_vector_3_element_wise_subtract(&cur_r_face->position_2, camera_position);
  255. global_quaternion_rotate(&cur_r_face->position_0, camera_rotation);
  256. global_quaternion_rotate(&cur_r_face->position_1, camera_rotation);
  257. global_quaternion_rotate(&cur_r_face->position_2, camera_rotation);
  258. __global RI_vector_3 *pos_0 = &cur_r_face->position_0;
  259. __global RI_vector_3 *pos_1 = &cur_r_face->position_1;
  260. __global RI_vector_3 *pos_2 = &cur_r_face->position_2;
  261. int is_0_clipped = pos_0->z < min_clip;
  262. int is_1_clipped = pos_1->z < min_clip;
  263. int is_2_clipped = pos_2->z < min_clip;
  264. int clip_count = is_0_clipped + is_1_clipped + is_2_clipped;
  265. cur_r_face->should_render = 1;
  266. switch(clip_count){
  267. case 3: {// ignore polygon, it's behind the camera
  268. return;
  269. break;
  270. }
  271. case 2:{ // shrink poylgon
  272. __global RI_vector_3 *unclipped_point, *point_a, *point_b;
  273. __global RI_vector_3 *unclipped_normal, *normal_a, *normal_b;
  274. __global RI_vector_2 *unclipped_uv, *uv_a, *uv_b;
  275. if (!is_0_clipped){
  276. unclipped_point = &cur_r_face->position_0;
  277. point_a = &cur_r_face->position_1;
  278. point_b = &cur_r_face->position_2;
  279. unclipped_normal = &cur_r_face->normal_0;
  280. normal_a = &cur_r_face->normal_1;
  281. normal_b = &cur_r_face->normal_2;
  282. unclipped_uv = &cur_r_face->uv_0;
  283. uv_a = &cur_r_face->uv_1;
  284. uv_b = &cur_r_face->uv_2;
  285. }
  286. else if (!is_1_clipped){
  287. unclipped_point = &cur_r_face->position_1;
  288. point_a = &cur_r_face->position_2;
  289. point_b = &cur_r_face->position_0;
  290. unclipped_normal = &cur_r_face->normal_1;
  291. normal_a = &cur_r_face->normal_2;
  292. normal_b = &cur_r_face->normal_0;
  293. unclipped_uv = &cur_r_face->uv_1;
  294. uv_a = &cur_r_face->uv_2;
  295. uv_b = &cur_r_face->uv_0;
  296. }
  297. else if (!is_2_clipped){
  298. unclipped_point = &cur_r_face->position_2;
  299. point_a = &cur_r_face->position_0;
  300. point_b = &cur_r_face->position_1;
  301. unclipped_normal = &cur_r_face->normal_2;
  302. normal_a = &cur_r_face->normal_0;
  303. normal_b = &cur_r_face->normal_1;
  304. unclipped_uv = &cur_r_face->uv_2;
  305. uv_a = &cur_r_face->uv_0;
  306. uv_b = &cur_r_face->uv_1;
  307. }
  308. double fraction_a_to_unclip = (min_clip - unclipped_point->z) / (point_a->z - unclipped_point->z);
  309. double fraction_b_to_unclip = (min_clip - unclipped_point->z) / (point_b->z - unclipped_point->z);
  310. global_vector_3_lerp(*unclipped_point, *point_a, point_a, fraction_a_to_unclip);
  311. global_vector_3_lerp(*unclipped_point, *point_b, point_b, fraction_b_to_unclip);
  312. global_vector_3_lerp(*unclipped_normal, *normal_a, normal_a, fraction_a_to_unclip);
  313. global_vector_3_lerp(*unclipped_normal, *normal_b, normal_b, fraction_b_to_unclip);
  314. global_vector_2_lerp(*unclipped_uv, *uv_a, uv_a, fraction_a_to_unclip);
  315. global_vector_2_lerp(*unclipped_uv, *uv_b, uv_b, fraction_b_to_unclip);
  316. break;}
  317. case 1: {// split polygon
  318. RI_vector_3 clipped_point, point_a, point_b;
  319. RI_vector_3 clipped_normal, normal_a, normal_b;
  320. RI_vector_2 clipped_uv, uv_a, uv_b;
  321. if (is_0_clipped){
  322. clipped_point = cur_r_face->position_0;
  323. point_a = cur_r_face->position_1;
  324. point_b = cur_r_face->position_2;
  325. clipped_normal = cur_r_face->normal_0;
  326. normal_a = cur_r_face->normal_1;
  327. normal_b = cur_r_face->normal_2;
  328. clipped_uv = cur_r_face->uv_0;
  329. uv_a = cur_r_face->uv_1;
  330. uv_b = cur_r_face->uv_2;
  331. }
  332. else if (is_1_clipped){
  333. clipped_point = cur_r_face->position_1;
  334. point_a = cur_r_face->position_2;
  335. point_b = cur_r_face->position_0;
  336. clipped_normal = cur_r_face->normal_1;
  337. normal_a = cur_r_face->normal_2;
  338. normal_b = cur_r_face->normal_0;
  339. clipped_uv = cur_r_face->uv_1;
  340. uv_a = cur_r_face->uv_2;
  341. uv_b = cur_r_face->uv_0;
  342. }
  343. else if (is_2_clipped){
  344. clipped_point = cur_r_face->position_2;
  345. point_a = cur_r_face->position_0;
  346. point_b = cur_r_face->position_1;
  347. clipped_normal = cur_r_face->normal_2;
  348. normal_a = cur_r_face->normal_0;
  349. normal_b = cur_r_face->normal_1;
  350. clipped_uv = cur_r_face->uv_2;
  351. uv_a = cur_r_face->uv_0;
  352. uv_b = cur_r_face->uv_1;
  353. }
  354. double fraction_a_to_clip = (min_clip - clipped_point.z) / (point_a.z - clipped_point.z);
  355. double fraction_b_to_clip = (min_clip - clipped_point.z) / (point_b.z - clipped_point.z);
  356. RI_vector_3 new_point_a, new_point_b; // the new points that move along the polygon's edge to match the z value of min_clip.
  357. RI_vector_3 new_normal_a, new_normal_b; // they come from the clipped point which was originally only 1
  358. RI_vector_2 new_uv_a, new_uv_b;
  359. vector_3_lerp(clipped_point, point_a, &new_point_a, fraction_a_to_clip);
  360. vector_3_lerp(clipped_point, point_b, &new_point_b, fraction_b_to_clip);
  361. vector_3_lerp(clipped_normal, normal_a, &new_normal_a, fraction_a_to_clip);
  362. vector_3_lerp(clipped_normal, normal_b, &new_normal_b, fraction_b_to_clip);
  363. vector_2_lerp(clipped_uv, uv_a, &new_uv_a, fraction_a_to_clip);
  364. vector_2_lerp(clipped_uv, uv_b, &new_uv_b, fraction_b_to_clip);
  365. // okay, now we have a quad (in clockwise order, point a, point b, new point b, new point a)
  366. // quads are easy to turn into tris >w<
  367. __global RI_renderable_face *cur_r_split_face = &renderable_faces[face_index * 2 + renderable_face_offset + 1];
  368. // cur_r_split_face->parent_actor = current_actor;
  369. // cur_r_split_face->material = cur_r_face->material;
  370. cur_r_face->position_0 = point_a;
  371. cur_r_face->position_1 = point_b;
  372. cur_r_face->position_2 = new_point_a;
  373. cur_r_face->normal_0 = normal_a;
  374. cur_r_face->normal_1 = normal_b;
  375. cur_r_face->normal_2 = new_normal_a;
  376. cur_r_face->uv_0 = uv_a;
  377. cur_r_face->uv_1 = uv_b;
  378. cur_r_face->uv_2 = new_uv_a;
  379. cur_r_split_face->position_0 = point_b;
  380. cur_r_split_face->position_1 = new_point_b;
  381. cur_r_split_face->position_2 = new_point_a;
  382. cur_r_split_face->normal_0 = normal_b;
  383. cur_r_split_face->normal_1 = new_normal_b;
  384. cur_r_split_face->normal_2 = new_normal_a;
  385. cur_r_split_face->uv_0 = uv_b;
  386. cur_r_split_face->uv_1 = new_uv_b;
  387. cur_r_split_face->uv_2 = new_uv_a;
  388. cur_r_split_face->position_0.x = cur_r_split_face->position_0.x / cur_r_split_face->position_0.z * horizontal_fov_factor;
  389. cur_r_split_face->position_0.y = cur_r_split_face->position_0.y / cur_r_split_face->position_0.z * vertical_fov_factor;
  390. cur_r_split_face->position_1.x = cur_r_split_face->position_1.x / cur_r_split_face->position_1.z * horizontal_fov_factor;
  391. cur_r_split_face->position_1.y = cur_r_split_face->position_1.y / cur_r_split_face->position_1.z * vertical_fov_factor;
  392. cur_r_split_face->position_2.x = cur_r_split_face->position_2.x / cur_r_split_face->position_2.z * horizontal_fov_factor;
  393. cur_r_split_face->position_2.y = cur_r_split_face->position_2.y / cur_r_split_face->position_2.z * vertical_fov_factor;
  394. cur_r_split_face->min_screen_x = cur_r_split_face->position_0.x;
  395. if (cur_r_split_face->position_1.x < cur_r_split_face->min_screen_x) cur_r_split_face->min_screen_x = cur_r_split_face->position_1.x;
  396. if (cur_r_split_face->position_2.x < cur_r_split_face->min_screen_x) cur_r_split_face->min_screen_x = cur_r_split_face->position_2.x;
  397. cur_r_split_face->min_screen_x = max(cur_r_split_face->min_screen_x, (short)(-width / 2));
  398. cur_r_split_face->max_screen_x = cur_r_split_face->position_0.x;
  399. if (cur_r_split_face->position_1.x > cur_r_split_face->max_screen_x) cur_r_split_face->max_screen_x = cur_r_split_face->position_1.x;
  400. if (cur_r_split_face->position_2.x > cur_r_split_face->max_screen_x) cur_r_split_face->max_screen_x = cur_r_split_face->position_2.x;
  401. cur_r_split_face->max_screen_x = min(cur_r_split_face->max_screen_x, (short)(width / 2));
  402. cur_r_split_face->min_screen_y = cur_r_split_face->position_0.y;
  403. if (cur_r_split_face->position_1.y < cur_r_split_face->min_screen_y) cur_r_split_face->min_screen_y = cur_r_split_face->position_1.y;
  404. if (cur_r_split_face->position_2.y < cur_r_split_face->min_screen_y) cur_r_split_face->min_screen_y = cur_r_split_face->position_2.y;
  405. cur_r_split_face->min_screen_y = max(cur_r_split_face->min_screen_y, (short)(-height / 2));
  406. cur_r_split_face->max_screen_y = cur_r_split_face->position_0.y;
  407. if (cur_r_split_face->position_1.y > cur_r_split_face->max_screen_y) cur_r_split_face->max_screen_y = cur_r_split_face->position_1.y;
  408. if (cur_r_split_face->position_2.y > cur_r_split_face->max_screen_y) cur_r_split_face->max_screen_y = cur_r_split_face->position_2.y;
  409. cur_r_split_face->max_screen_y = min(cur_r_split_face->max_screen_y, (short)(height / 2));
  410. cur_r_split_face->should_render = 1;
  411. cur_r_split_face->texture_width = texture_width;
  412. cur_r_split_face->texture_height = texture_height;
  413. cur_r_split_face->texture_index = texture_index;
  414. break;
  415. }
  416. case 0:{ // no issues, ignore
  417. break;
  418. }
  419. }
  420. // current_actor.material->vertex_shader(&cur_r_face->position_0, &cur_r_face->position_1, &cur_r_face->position_2, horizontal_fov_factor, vertical_fov_factor);
  421. cur_r_face->position_0.x = cur_r_face->position_0.x / cur_r_face->position_0.z * horizontal_fov_factor;
  422. cur_r_face->position_0.y = cur_r_face->position_0.y / cur_r_face->position_0.z * vertical_fov_factor;
  423. cur_r_face->position_1.x = cur_r_face->position_1.x / cur_r_face->position_1.z * horizontal_fov_factor;
  424. cur_r_face->position_1.y = cur_r_face->position_1.y / cur_r_face->position_1.z * vertical_fov_factor;
  425. cur_r_face->position_2.x = cur_r_face->position_2.x / cur_r_face->position_2.z * horizontal_fov_factor;
  426. cur_r_face->position_2.y = cur_r_face->position_2.y / cur_r_face->position_2.z * vertical_fov_factor;
  427. cur_r_face->min_screen_x = pos_0->x;
  428. if (pos_1->x < cur_r_face->min_screen_x) cur_r_face->min_screen_x = pos_1->x;
  429. if (pos_2->x < cur_r_face->min_screen_x) cur_r_face->min_screen_x = pos_2->x;
  430. cur_r_face->min_screen_x = max(cur_r_face->min_screen_x, (short)(-width / 2));
  431. cur_r_face->max_screen_x = pos_0->x;
  432. if (pos_1->x > cur_r_face->max_screen_x) cur_r_face->max_screen_x = pos_1->x;
  433. if (pos_2->x > cur_r_face->max_screen_x) cur_r_face->max_screen_x = pos_2->x;
  434. cur_r_face->max_screen_x = min(cur_r_face->max_screen_x, (short)(width / 2));
  435. cur_r_face->min_screen_y = pos_0->y;
  436. if (pos_1->y < cur_r_face->min_screen_y) cur_r_face->min_screen_y = pos_1->y;
  437. if (pos_2->y < cur_r_face->min_screen_y) cur_r_face->min_screen_y = pos_2->y;
  438. cur_r_face->min_screen_y = max(cur_r_face->min_screen_y, (short)(-height / 2));
  439. cur_r_face->max_screen_y = pos_0->y;
  440. if (pos_1->y > cur_r_face->max_screen_y) cur_r_face->max_screen_y = pos_1->y;
  441. if (pos_2->y > cur_r_face->max_screen_y) cur_r_face->max_screen_y = pos_2->y;
  442. cur_r_face->max_screen_y = min(cur_r_face->max_screen_y, (short)(height / 2));
  443. return;
  444. }
  445. __kernel void rasterizer(__global RI_renderable_face *renderable_faces, __global uint* textures, __global uint *frame_buffer, int width, int height, int half_width, int half_height, int number_of_renderable_faces, int number_of_split_renderable_faces){
  446. int pixel_x = get_global_id(0); if (pixel_x >= width) return;
  447. int pixel_y = get_global_id(1); if (pixel_y >= height) return;
  448. int idx = pixel_y * width + pixel_x;
  449. int x = pixel_x - half_width;
  450. int y = height - pixel_y - half_height;
  451. double z = INFINITY;
  452. uint pixel_color = 0x11111111;
  453. for (int face_i = 0; face_i < number_of_renderable_faces * 2; ++face_i){
  454. __global RI_renderable_face *current_face = &renderable_faces[face_i];
  455. if (!current_face->should_render) continue;
  456. RI_vector_2 uv_0 = current_face->uv_0;
  457. RI_vector_2 uv_1 = current_face->uv_1;
  458. RI_vector_2 uv_2 = current_face->uv_2;
  459. RI_vector_3 normal_0 = current_face->normal_0;
  460. RI_vector_3 normal_1 = current_face->normal_1;
  461. RI_vector_3 normal_2 = current_face->normal_2;
  462. RI_vector_3 pos_0 = current_face->position_0;
  463. RI_vector_3 pos_1 = current_face->position_1;
  464. RI_vector_3 pos_2 = current_face->position_2;
  465. if (x < current_face->min_screen_x || x > current_face->max_screen_x || y < current_face->min_screen_y || y > current_face->max_screen_y)
  466. continue;
  467. double denominator, w0, w1, w2;
  468. denominator = (pos_1.y - pos_2.y) * (pos_0.x - pos_2.x) + (pos_2.x - pos_1.x) * (pos_0.y - pos_2.y);
  469. if (denominator >= 0) continue;
  470. w0 = ((pos_1.y - pos_2.y) * (x - pos_2.x) + (pos_2.x - pos_1.x) * (y - pos_2.y)) / denominator;
  471. w1 = ((pos_2.y - pos_0.y) * (x - pos_0.x) + (pos_0.x - pos_2.x) * (y - pos_0.y)) / denominator;
  472. w2 = 1.0 - w0 - w1;
  473. double w_over_z = (w0 / pos_0.z + w1 / pos_1.z + w2 / pos_2.z);
  474. double interpolated_z = 1.0 / w_over_z;
  475. if (!(w0 >= 0 && w1 >= 0 && w2 >= 0)){
  476. continue;
  477. }
  478. if (interpolated_z >= z){
  479. continue;
  480. }
  481. double alpha = 1;
  482. float ux = (w0 * (uv_0.x / pos_0.z) + w1 * (uv_1.x / pos_1.z) + w2 * (uv_2.x / pos_2.z)) / w_over_z;
  483. float uy = (w0 * (uv_0.y / pos_0.z) + w1 * (uv_1.y / pos_1.z) + w2 * (uv_2.y / pos_2.z)) / w_over_z;
  484. RI_vector_3 interpolated_normal = {0};
  485. uint texel_x = current_face->texture_width * ux;
  486. uint texel_y = current_face->texture_height * uy;
  487. uint texel_index = current_face->texture_index +
  488. texel_y * current_face->texture_width + texel_x;
  489. pixel_color = textures[texel_index];
  490. z = interpolated_z;
  491. }
  492. frame_buffer[idx] = pixel_color;
  493. return;
  494. }