Advertisement
Guest User

Untitled

a guest
Jun 20th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.48 KB | None | 0 0
  1. import numpy as np
  2. import math
  3. from PIL import Image
  4. import time
  5. import threading
  6. import random
  7. from multiprocessing import Pool
  8.  
  9. zz = 2 ** 9
  10. aspect_ratio = 16.0 / 9.0
  11. height = zz
  12. width = math.floor(zz * aspect_ratio)
  13. print('%d by %d, w/h' % (width, height))
  14.  
  15. data = np.zeros((height, width, 3))
  16. MAX_DEPTH = 1
  17. DIFFUSE_RAYS = 4
  18. DIFFUSE_DEPTH = 1
  19. DIFFUSE_DEPTH_OFFSET = MAX_DEPTH - DIFFUSE_DEPTH
  20.  
  21. FOV = 70.0
  22.  
  23. fov = FOV * math.pi / 180.0
  24.  
  25. upscale_factor = 2
  26.  
  27. # gamma
  28. random_light_spread = 0.6
  29. G = 2.2
  30. brightness = 0.1
  31. contrast = 0.5
  32. EV = 150
  33.  
  34. # alpha for phong
  35. alpha = 10.0
  36. bias = 0.0
  37. vert_division = 10
  38. hor_division = 10
  39.  
  40.  
  41. class Ray:
  42. ray_direction = np.array((0.0, 0.0, -1.0))
  43. ray_origin = np.array((0.0, 0.0, 0.0))
  44.  
  45. refraction_index = 1.0
  46.  
  47. def __init__(self, _dir, _or, _ior=None):
  48. self.ray_direction = _dir
  49. self.ray_origin = _or
  50. if _ior is not None:
  51. self.refraction_index = _ior
  52.  
  53. def reflect(self, normal):
  54. return self.ray_direction - 2 * normal * np.inner(self.ray_direction, normal)
  55.  
  56. def point_at_distance(self, _dist):
  57. return self.ray_origin + _dist * self.ray_direction
  58.  
  59. def refract(self, ior, normal):
  60. Nrefr = normal
  61. n_dot_incident = np.inner(Nrefr, self.ray_direction)
  62. ior_1 = self.refraction_index
  63. ior_2 = ior
  64. if n_dot_incident < 0:
  65. # outside
  66. n_dot_incident *= -1
  67. else:
  68. # we are inside, swap normal
  69. Nrefr = -normal
  70. ior_1 = ior
  71. ior_2 = self.refraction_index
  72.  
  73. mu = ior_2 / ior_1
  74.  
  75. k = 1 - mu ** 2 * (1 - n_dot_incident ** 2)
  76.  
  77. if k < 0:
  78. k *= -1
  79. return mu * self.ray_direction + mu * (n_dot_incident - math.sqrt(k)) * Nrefr
  80.  
  81.  
  82. class Object:
  83. color = np.array((1.0, 1.0, 1.0))
  84. center = np.array((0, 0, 0))
  85.  
  86. radius = 0
  87.  
  88. spec = 0.5
  89. emissivity = 0
  90. lambert = 0.6
  91. ambient = 0.18
  92. refraction_index = 0.0
  93. alpha = 1.0
  94. max_int_dist = 0.0
  95.  
  96. type = 'object'
  97.  
  98. def __init__(self, color=None):
  99. if color is not None:
  100. self.color = color
  101. self.max_internal_distance()
  102.  
  103. def intersect(self, ray):
  104. print('super class has no intersect defined')
  105.  
  106. def normal_at_point(self, point):
  107. print('super class has no normal defined')
  108.  
  109. def intersection_point(self, ray):
  110. print('super class has no intersection_point defined')
  111.  
  112. def max_internal_distance(self):
  113. print('super class has no max_internal_distance func')
  114.  
  115.  
  116. class Sphere(Object):
  117. radius = 1.0
  118. type = 'sphere'
  119.  
  120. emissivity = 0.0
  121.  
  122. def __init__(self, color=None, radius=None):
  123. if radius is not None:
  124. self.radius = radius
  125. super(Sphere, self).__init__(color)
  126.  
  127. def intersect(self, ray):
  128. part_d = np.dot(ray.ray_direction, np.subtract(ray.ray_origin, self.center)) ** 2 - (
  129. np.linalg.norm(np.subtract(ray.ray_origin, self.center)) ** 2 - self.radius ** 2)
  130. if part_d >= 0:
  131. return self.distance(ray, part_d)
  132.  
  133. else:
  134. return math.inf
  135.  
  136. def distance(self, ray, part_d):
  137. d1 = -1.0 * (np.matmul(ray.ray_direction, np.subtract(ray.ray_origin, self.center))) - math.sqrt(part_d)
  138. # d2 = -1.0*(np.matmul(ray.ray_direction, np.subtract(ray.ray_origin, self.center))) + math.sqrt(part_d)
  139. # d2 will be larger dan d1
  140. return d1
  141.  
  142. def intersection_point(self, ray):
  143. t = self.intersect(ray)
  144. the_point = np.add(ray.ray_origin, ray.ray_direction * t)
  145. return the_point
  146.  
  147. def normal_at_point(self, point):
  148. return normalise(np.subtract(point, self.center))
  149.  
  150. def max_internal_distance(self):
  151. self.max_int_dist = self.radius
  152.  
  153.  
  154. class Plane(Object):
  155. normal = np.array((0.0, 1.0, 0.0))
  156. type = 'plane'
  157.  
  158. def __init__(self, color=None, normal=None):
  159. if normal is not None:
  160. self.normal = normal
  161. super(Plane, self).__init__(color)
  162.  
  163. def intersect(self, ray):
  164. dot_product = np.inner(self.normal, ray.ray_direction)
  165. if dot_product == 0:
  166. return math.inf
  167. else:
  168. return self.distance(ray)
  169.  
  170. def distance(self, ray):
  171. distance = np.linalg.norm(ray.ray_origin - self.intersection_point(ray))
  172. return distance
  173.  
  174. def intersection_point(self, ray):
  175. _N = np.inner(self.normal, ray.ray_direction)
  176. d = 0
  177. if _N == 0:
  178. d = math.inf
  179. else:
  180. d = np.inner((self.center - ray.ray_origin), self.normal) / np.inner(self.normal, ray.ray_direction)
  181. if d > 0:
  182. return ray.point_at_distance(d)
  183. else:
  184. return np.array((math.inf, math.inf, math.inf))
  185.  
  186. def normal_at_point(self, point):
  187. return self.normal
  188.  
  189. def max_internal_distance(self):
  190. self.max_int_dist = math.inf
  191.  
  192.  
  193. class Light:
  194. direction = np.array((-1.0, -1.0, 0.0))
  195. color = np.array((1.0, 1.0, 1.0))
  196. origin = np.array((-1.0, -1.0, 0))
  197. intensity = 1.0
  198.  
  199. def __init__(self, direction=None):
  200. if direction is not None:
  201. self.direction = direction
  202.  
  203. def set_origin(self, x, y, z):
  204. self.origin = np.array((x, y, z))
  205.  
  206. def set_direction(self, x, y, z):
  207. self.direction = np.array((x, y, z))
  208.  
  209.  
  210. def calc_normal(_p1, _p2, _p3):
  211. P1P2 = _p2 - _p1
  212. P1P3 = _p3 - _p1
  213. return normalise(np.cross(P1P2, P1P3))
  214.  
  215.  
  216. class Triangle(Plane):
  217. p2 = np.array((1.0, 0.0, -1.0))
  218. p3 = np.array((1.0, 1.0, -1.0))
  219.  
  220. bary_center = np.array((0.0, 0.0, 0.0))
  221.  
  222. A = 0.0
  223.  
  224. type = 'triangle'
  225.  
  226. def __init__(self, color, normal, _p1, _p2, _p3):
  227. if _p1 is not None:
  228. self.center = _p1
  229. if _p2 is not None:
  230. self.p2 = _p2
  231. if _p3 is not None:
  232. self.p3 = _p3
  233. self.A = self.area(_p1, _p2, _p3)
  234. self.bary_center = (_p1 + _p2 + _p3) / 3.0
  235. super(Triangle, self).__init__(color, normal)
  236.  
  237. def intersect(self, ray):
  238. int_pt = self.intersection_point(ray)
  239.  
  240. if np.linalg.norm(int_pt) < math.inf:
  241. A1 = self.area(int_pt, self.center, self.p2)
  242. A2 = self.area(int_pt, self.p2, self.p3)
  243. A3 = self.area(int_pt, self.center, self.p3)
  244.  
  245. if abs(A1 + A2 + A3 - self.A) < 0.0001:
  246. return self.distance(ray)
  247. else:
  248. return math.inf
  249. else:
  250. return math.inf
  251.  
  252. def area(self, P1, P2, P3):
  253. P1P2 = P2 - P1
  254. P1P3 = P3 - P1
  255. return np.linalg.norm(np.cross(P1P2, P1P3)) * 0.5
  256.  
  257. def max_internal_distance(self):
  258. d_p1p2 = np.linalg.norm(self.center - self.p2)
  259. d_p2p3 = np.linalg.norm(self.p2 - self.p3)
  260. d_p3p1 = np.linalg.norm(self.p3 - self.center)
  261. self.max_int_dist = np.amax((d_p1p2, d_p2p3, d_p3p1))
  262.  
  263.  
  264. def normalise(vector):
  265. norm = np.linalg.norm(vector)
  266. if norm != 0:
  267. return vector * (1 / np.linalg.norm(vector))
  268.  
  269.  
  270. s1 = Sphere(np.array((0.65, 0.44, 0.39)), 1.0)
  271. s1.center = np.array((-2.0, 1.0, -5.0))
  272. s1.lambert = 0.2
  273. s1.spec = 0.0
  274. s1.ambient = 0.18
  275. s1.refraction_index = 1.4
  276. s1.alpha = 1.0
  277. s1.emissivity = 1.0
  278.  
  279. s2 = Sphere(np.array((1.0, 1.0, 1.0)), 1.0)
  280. s2.center = np.array((0.0, 1.0, -5.0))
  281. s2.lambert = 1.0
  282. s2.ambient = 0.18
  283. s2.spec = 0.0
  284. s2.alpha = 1.0
  285. s2.refraction_index = 1.4
  286. s2.emissivity = 1.0
  287.  
  288. s3 = Sphere(np.array((1.0, 0.78, 0.34)), 1.0)
  289. s3.center = np.array((2.0, 1.0, -3.0))
  290. s3.lambert = 0.2
  291. s3.ambient = 0.18
  292. s3.spec = 0.5
  293. s3.alpha = 1.0
  294. s3.refraction_index = 1.4
  295. s3.emissivity = 1.0
  296.  
  297. s4 = Sphere(np.array((0.0, 1.0, 1.0)), 0.4)
  298. s4.center = np.array((4.0, 3.0, -2.0))
  299. s4.lambert = 0.0
  300. s4.ambient = 0.18
  301. s4.spec = 1.0
  302. s4.alpha = 0.0
  303. s4.refraction_index = 1.4
  304. s4.emissivity = 1.0
  305. s4.type = 'light'
  306.  
  307. s5 = Sphere(np.array((0.95, 0.5, 0.2)), 0.4)
  308. s5.center = np.array((4.0, 3.0, -6.0))
  309. s5.lambert = 0.0
  310. s5.ambient = 0.18
  311. s5.spec = 1.0
  312. s5.alpha = 0.0
  313. s5.refraction_index = 1.4
  314. s5.emissivity = 1.0
  315. s5.type = 'light'
  316.  
  317.  
  318. # plane
  319. p1 = Plane(np.array((1.0, 1.0, 1.0)), np.array((0.0, 1.0, 0.0)))
  320. p1.center = np.array((0.0, 0.0, 0.0))
  321. p1.spec = 0.0
  322. p1.lambert = 1.0
  323. p1.ambient = 0.18
  324. p1.alpha = 1.0
  325. p1.refraction_index = 1.4
  326.  
  327. # triangle points
  328. spiegel = -10
  329. t_pt1 = np.array((-5.0, 0.0, spiegel))
  330. t_pt2 = np.array((5.0, 0.0, spiegel))
  331. t_pt3 = np.array((0.0, 5.0, spiegel))
  332. test_triangle_color = np.array((1.0, 1.0, 1.0))
  333.  
  334. test_triangle = Triangle(test_triangle_color, calc_normal(t_pt1, t_pt2, t_pt3), t_pt1, t_pt2, t_pt3)
  335. test_triangle.lambert = 0.0
  336. test_triangle.ambient = 0.0
  337. test_triangle.spec = 1.0
  338. test_triangle.emissivity = 1.0
  339.  
  340. # triangle 2
  341. tt_pt1 = np.array((-5.0, 0.0, -spiegel))
  342. tt_pt2 = np.array((5.0, 0.0, -spiegel))
  343. tt_pt3 = np.array((0.0, 5.0, -spiegel))
  344. test_triangle2_color = np.array((1.0, 1.0, 1.0))
  345.  
  346. test_triangle2 = Triangle(test_triangle_color, calc_normal(tt_pt1, tt_pt2, tt_pt3), tt_pt1, tt_pt2, tt_pt3)
  347. test_triangle2.lambert = 0.1
  348. test_triangle2.ambient = 0.1
  349. test_triangle2.spec = 1.0
  350.  
  351. # triangle 3
  352. et_pt1 = np.array((4.0, 0.0, -4.0))
  353. et_pt2 = np.array((4.0, 2.0, -3.0))
  354. et_pt3 = np.array((4.2, 2.0, -6.0))
  355. test_triangle_color = np.array((1.0, 1.0, 1.0))
  356. test_triangle3 = Triangle(test_triangle_color, calc_normal(et_pt1, et_pt2, et_pt3), et_pt1, et_pt2, et_pt3)
  357. test_triangle3.lambert = 0.1
  358. test_triangle3.ambient = 0.0
  359. test_triangle3.spec = 1.0
  360. test_triangle3.emissivity = 1.0
  361. test_triangle3.refraction_index = 1.4
  362. test_triangle3.type = 'light'
  363.  
  364. # camera
  365. camera_point = np.array((0.0, 3.0, 5.0))
  366. view_direction = normalise(np.array([0.0, -0.1, -1.0]))
  367.  
  368. scene = [s1, s2, s3, p1, test_triangle, s4, test_triangle3, s5]
  369.  
  370. light1 = Light(np.array((0.0, -1.0, 0.0)))
  371. light1.set_origin(1.0, 2.3, -3.0)
  372. light1.intensity = 0.0
  373. light1.color = np.array((1.0, 1.0, 1.0))
  374.  
  375. lights = []
  376. lights.append(light1)
  377.  
  378. surface_lights = [s4, s5,test_triangle3]
  379.  
  380.  
  381.  
  382. # for x in range(0, 10):
  383. # random_loc = np.random.rand(3) * 2.0 + np.array((0, 0, 1))
  384. # random_radius = np.random.rand(1) * 2.0
  385. # random_color = np.random.rand(3)
  386. #
  387. # random_sphere = Sphere(random_color, random_radius)
  388. # random_sphere.center = random_loc
  389. #
  390. # # random specs
  391. # random_specs = np.random.rand(3)
  392. # random_sphere.lambert = random_specs[0]
  393. # random_sphere.spec = random_specs[1]
  394. # random_sphere.ambient = random_specs[2]
  395. #
  396. # scene.append(random_sphere)
  397.  
  398.  
  399. def make_rot_matrix(rx, ry, rz):
  400. cx, sx = np.cos(rx), np.sin(rx)
  401. cy, sy = np.cos(ry), np.sin(ry)
  402. cz, sz = np.cos(rz), np.sin(rz)
  403. Ry = np.array(((cy, 0, sy), (0, 1, 0), (-sy, 0, cy)))
  404. Rx = np.array(((1, 0, 0), (0, cx, -sx), (0, sx, cx)))
  405. Rz = np.array(((cz, -sz, 0), (sz, cz, 0), (0, 0, 1)))
  406. return np.dot(Rz, np.dot(Ry, Rx))
  407.  
  408.  
  409. def rotate_vector(vect, rot_mat):
  410. return np.dot(rot_mat, vect)
  411.  
  412.  
  413. def make_rot_matrix_from_normals(_u, _v):
  414. c = np.inner(_u, _v)
  415. _R = np.zeros((3, 3)) - np.identity(3)
  416. if c == 1:
  417. _R = np.identity(3)
  418. if abs(c) != 1:
  419. _a = np.cross(_u, _v)
  420. _a_cross = np.array(((0, -_a[2], _a[1]),
  421. (_a[2], 0, -_a[0]),
  422. (-_a[1], _a[0], 0)))
  423. _a_cross_sq = np.dot(_a_cross, _a_cross)
  424. _R = np.identity(3) + _a_cross + _a_cross_sq * 1.0 / (1 + c)
  425. return _R
  426.  
  427.  
  428. def interpolated_ray_dir(_fov, _y, _x, _width, _height, view_dir):
  429. y_clipped = -(_y / _height - 0.5)
  430. x_clipped = (_x / _width - 0.5) * aspect_ratio
  431.  
  432. D = 1.0 / math.tan(_fov / 2.0)
  433. uv = (np.array((x_clipped, y_clipped, 0)))
  434.  
  435. return normalise(np.add(uv, D * view_dir))
  436.  
  437.  
  438. def opening_corner(_n, _d, _L, _dist):
  439. _gamma = math.pi * 0.5 - abs(np.inner(_n, _d))
  440. _delta = math.atan(math.sin(_gamma) / (_dist / _L - math.cos(_gamma)))
  441. return (1.0 - _delta / (math.pi) * 2)
  442.  
  443.  
  444. def intersect(_ray, _scene):
  445. closest = math.inf
  446. _nearest_object = None
  447. for c in _scene:
  448. distance_to_c = c.intersect(_ray)
  449. if distance_to_c < closest:
  450. if distance_to_c > 0.001:
  451. closest = distance_to_c
  452. _nearest_object = c
  453. return [_nearest_object, closest]
  454.  
  455.  
  456. def diffuse_cos_weighted_direction(_spec, _reflection_vector, _normal):
  457. m = alpha ** (_spec)
  458. _u = random.random()
  459. _v = random.random()
  460.  
  461. sinT = math.sqrt(1.0 - ((1.0 - _u) ** (1.0 / (1 + m)) ** 2))
  462. phi = 2 * math.pi * _v
  463.  
  464. _X = sinT * math.cos(phi)
  465. _Y = sinT * math.sin(phi)
  466. _Z = _u
  467.  
  468. random_vector = np.array((_X, _Y, _Z))
  469. # rotate so it is on the normal plane
  470. _rotation_mat = make_rot_matrix_from_normals(np.array((0, 0, 1.0)), _normal)
  471. _random_rotated_vector = rotate_vector(random_vector, _rotation_mat).reshape(_reflection_vector.shape)
  472.  
  473. # weigh it with the _reflectionvector
  474. weighted = normalise(_spec * _reflection_vector + (1 - _spec) * _random_rotated_vector)
  475. return weighted
  476.  
  477.  
  478. def trace(_ray, _scene, _depth):
  479. col = np.array((0.0, 0.0, 0.0))
  480. if _depth <= MAX_DEPTH:
  481. [intersect_object, distance] = intersect(_ray, _scene)
  482. if intersect_object is not None:
  483.  
  484. if intersect_object.type == 'light':
  485. return intersect_object.color * intersect_object.emissivity
  486.  
  487. intersection_point = _ray.point_at_distance(distance)
  488. surf_norm = intersect_object.normal_at_point(intersection_point)
  489.  
  490. # direct lighting
  491. direct_col = np.array((0.0, 0.0, 0.0))
  492. for s in surface_lights:
  493. for o in range(0, DIFFUSE_RAYS):
  494. pt_to_light_vec0 = normalise(s.center - intersection_point)
  495. random_direction0 = diffuse_cos_weighted_direction(random_light_spread, pt_to_light_vec0,
  496. pt_to_light_vec0)
  497. pt_to_light_ray0 = Ray(random_direction0, intersection_point)
  498.  
  499. [towards_light_intersect0, distance_pt_to_light0] = intersect(pt_to_light_ray0, _scene)
  500. if towards_light_intersect0 is not None:
  501. if towards_light_intersect0.type == 'light':
  502. n_dot_pt_l = np.inner(surf_norm, pt_to_light_vec0) * intersect_object.lambert
  503. if n_dot_pt_l > 0:
  504. distance_fall_off = 4 * math.pi * distance_pt_to_light0 ** 2
  505. direct_col += intersect_object.color * trace(pt_to_light_ray0, _scene,
  506. MAX_DEPTH) * n_dot_pt_l / distance_fall_off
  507. if DIFFUSE_RAYS != 0:
  508. direct_col /= DIFFUSE_RAYS
  509. col += direct_col
  510. # amb
  511.  
  512. # lambertion point light
  513. for li in lights:
  514. if li.intensity > 0:
  515. pt_to_light_dist = np.linalg.norm(light1.origin - intersection_point)
  516. pt_to_light_vec = normalise(light1.origin - intersection_point)
  517. pt_to_light_ray = Ray(pt_to_light_vec, intersection_point)
  518.  
  519. [towards_light_intersect, distance_pt_to_light] = intersect(pt_to_light_ray, _scene)
  520.  
  521. if distance_pt_to_light is math.inf: # it sees the light
  522. lamb_int = np.inner(surf_norm, pt_to_light_vec)
  523. if lamb_int > 0:
  524. col += intersect_object.color * light1.intensity * light1.color / (
  525. 4.0 * math.pi * pt_to_light_dist ** 2) * intersect_object.lambert * lamb_int
  526.  
  527. # spec
  528. reflected_ray = Ray(normalise(_ray.reflect(surf_norm)), intersection_point)
  529. dice = random.random()
  530. if dice < intersect_object.spec:
  531. random_dir = diffuse_cos_weighted_direction(intersect_object.spec, reflected_ray.ray_direction,
  532. reflected_ray.ray_direction)
  533. col += trace(Ray(random_dir, reflected_ray.ray_origin),
  534. _scene, _depth + 1) * intersect_object.color / intersect_object.spec * np.inner(
  535. random_dir, surf_norm)
  536. else:
  537. # random ray
  538. if DIFFUSE_RAYS != 0:
  539. diffuse_color = np.array((0.0, 0.0, 0.0))
  540. for i in range(0, DIFFUSE_RAYS):
  541. random_direction = diffuse_cos_weighted_direction(0.0,
  542. reflected_ray.ray_direction,
  543. surf_norm)
  544. diffuse_color += intersect_object.color * trace(Ray(random_direction, intersection_point),
  545. _scene,
  546. _depth + 1 + DIFFUSE_DEPTH_OFFSET) / (
  547. 1 - intersect_object.spec) * np.inner(random_direction, surf_norm)
  548.  
  549. col += diffuse_color / float(DIFFUSE_RAYS)
  550.  
  551. # refraction
  552. if intersect_object.alpha != 1.0:
  553. new_ior = 1.0
  554. if _ray.refraction_index == 1.0:
  555. new_ior = intersect_object.refraction_index
  556. else:
  557. surf_norm *= -1
  558. refracted_ray = Ray(normalise(_ray.refract(new_ior, surf_norm)),
  559. intersection_point + bias * _ray.ray_direction, new_ior)
  560. col += trace(refracted_ray, _scene, _depth + 1)
  561.  
  562. return col
  563. else:
  564. return col
  565. else:
  566. return col
  567.  
  568.  
  569. view_direction = normalise(view_direction)
  570.  
  571.  
  572. def render_pixel(_fov, _x, _y, _width, _height, _view_direction, _viewpoint, _scene):
  573. return trace(Ray(interpolated_ray_dir(fov, _x, _y, _width, _height, _view_direction), _viewpoint), _scene, 0)
  574.  
  575.  
  576. class Render_thread(threading.Thread):
  577. x_start = 0
  578. x_end = height
  579. y_start = 0
  580. y_end = width
  581. m_scene = []
  582.  
  583. render_data = np.zeros((x_end, y_end, 3))
  584.  
  585. def __init__(self, threadID, name, x_s=None, x_e=None, y_s=None, y_e=None, _scene=None):
  586. threading.Thread.__init__(self)
  587. self.threadID = threadID
  588. self.name = name
  589. self.x_start = x_s
  590. self.x_end = x_e
  591. self.y_end = y_e
  592. self.y_start = y_s
  593. self.m_scene = _scene
  594. self.render_data = np.zeros((x_e - x_s, y_e - y_s, 3))
  595.  
  596. print('making a thread with hor from %.f to %.f and height from %.f to %.f' % (
  597. self.y_start, self.y_end, self.x_start, self.x_end))
  598.  
  599. def run(self):
  600. for _i in range(self.x_start, self.x_end):
  601. for _k in range(self.y_start, self.y_end):
  602. self.render_data[_i - self.x_start, _k - self.y_start,] = render_pixel(fov, _i, _k, width, height,
  603. view_direction, camera_point,
  604. self.m_scene)
  605. self.render_data **= (1 / G)
  606.  
  607.  
  608. # threads = []
  609. # num_of_threads = vert_division * hor_division
  610. # delta_x = math.floor(height / vert_division)
  611. # delta_y = math.floor(width / hor_division)
  612. # for k in range(0, vert_division):
  613. # for j in range(0, hor_division):
  614. # h_st = delta_x * k
  615. # w_st = delta_y * j
  616. # h_end = h_st + delta_x
  617. # w_end = w_st + delta_y
  618. # thread_name = 'Thread-' + str(k + j)
  619. # threads.append(Render_thread(k + j, thread_name, h_st, h_end, w_st, w_end, scene))
  620. #
  621. # t_start = time.time()
  622. # for idx in range(len(threads)):
  623. # threads[idx].start()
  624. # for idx in range(len(threads)):
  625. # threads[idx].join()
  626. # t_end = time.time()
  627. # print('image rendered with %d threads in %f s with width = %d and height = %d' % (
  628. # num_of_threads, (t_end - t_start), width, height))
  629. #
  630. # stitched_data = np.zeros((height, width, 3))
  631. #
  632. #
  633. # def stitch_buffers(_threads):
  634. # for thr in _threads:
  635. # x_starts = thr.x_start
  636. # y_starts = thr.y_start
  637. # x_ends = thr.x_end
  638. # y_ends = thr.y_end
  639. # for _i in range(x_starts, x_ends):
  640. # for _j in range(y_starts, y_ends):
  641. # stitched_data[_i, _j,] = thr.render_data[_i-x_starts, _j-y_starts,]
  642. #
  643. #
  644. # stitch_buffers(threads)
  645. # stitched_data *= 255 / np.amax(stitched_data)
  646. # img = Image.fromarray(stitched_data.astype(np.uint8))
  647. # img.show()
  648.  
  649. print('Rendering')
  650. t_start = time.time()
  651. for x in range(0, height):
  652. for y in range(0, width):
  653. data[x, y,] = render_pixel(fov, x, y, width, height, view_direction, camera_point, scene)
  654. t_end = time.time()
  655.  
  656. print('image rendered in %f s with width = %d and height = %d' % ((t_end - t_start), width, height))
  657.  
  658. # gamma correct
  659.  
  660.  
  661. data /= np.amax(data)
  662. data *= EV
  663. data = data * (1.0 + data / EV) / (data + 1.0)
  664. data = np.clip(data, 0, 1)
  665. data **= (1 / G)
  666. data *= 255
  667. img = Image.fromarray(data.astype(np.uint8))
  668. print('upscaling')
  669. t_start = time.time()
  670. img2 = img.resize([upscale_factor * width, upscale_factor * height], Image.LANCZOS)
  671. t_end = time.time()
  672. print('image upscaled in %f s with factor %d' % ((t_end - t_start), upscale_factor))
  673. img2.show()
  674. img2.save('image.png')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement