MohmedAnik commited on
Commit
8bd6b15
·
verified ·
1 Parent(s): 7cc5fe7

Update render/core.py

Browse files
Files changed (1) hide show
  1. render/core.py +8 -56
render/core.py CHANGED
@@ -8,7 +8,6 @@ from .canvas import Canvas
8
  from . import speedup
9
 
10
 
11
- # 2D part
12
 
13
 
14
  class Vec2d:
@@ -124,14 +123,13 @@ def draw_triangle(v1, v2, v3, canvas, color, wireframe=False):
124
  fill_top_flat_triangle(v2, v4, v3)
125
 
126
 
127
- # 3D part
128
 
129
 
130
  class Vec3d:
131
  __slots__ = "x", "y", "z", "arr"
132
 
133
  def __init__(self, *args):
134
- # for Vec4d cast
135
  if len(args) == 1 and isinstance(args[0], Vec4d):
136
  vec4 = args[0]
137
  arr_value = (vec4.x, vec4.y, vec4.z)
@@ -183,7 +181,7 @@ class Vec4d(Mat4d):
183
  self.arr = self.value.reshape((1, 4))
184
 
185
 
186
- # Math util
187
  def normalize(v: Vec3d):
188
  return Vec3d(*speedup.normalize(*v.arr))
189
 
@@ -210,16 +208,7 @@ def get_light_intensity(face) -> float:
210
 
211
 
212
  def look_at(eye: Vec3d, target: Vec3d, up: Vec3d = Vec3d(0, -1, 0)) -> Mat4d:
213
- """
214
- http://www.songho.ca/opengl/gl_camera.html#lookat
215
-
216
- Args:
217
- eye: 摄像机的世界坐标位置
218
- target: 观察点的位置
219
- up: 就是你想让摄像机立在哪个方向
220
- https://stackoverflow.com/questions/10635947/what-exactly-is-the-up-vector-in-opengls-lookat-function
221
- 这里默认使用了 0, -1, 0, 因为 blender 导出来的模型数据似乎有问题,导致y轴总是反的,于是把摄像机的up也翻一下得了。
222
- """
223
  f = normalize(eye - target)
224
  l = normalize(cross_product(up, f)) # noqa: E741
225
  u = cross_product(f, l)
@@ -235,35 +224,7 @@ def look_at(eye: Vec3d, target: Vec3d, up: Vec3d = Vec3d(0, -1, 0)) -> Mat4d:
235
 
236
 
237
  def perspective_project(r, t, n, f, b=None, l=None): # noqa: E741
238
- """
239
- 目的:
240
- 把相机坐标转换成投影在视网膜的范围在(-1, 1)的笛卡尔坐标
241
-
242
- 原理:
243
- 对于x,y坐标,相似三角形可以算出投影点的x,y
244
- 对于z坐标,是假设了near是-1,far是1,然后带进去算的
245
- http://www.songho.ca/opengl/gl_projectionmatrix.html
246
- https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix
247
-
248
- 推导出来的矩阵:
249
- [
250
- 2n/(r-l) 0 (r+l/r-l) 0
251
- 0 2n/(t-b) (t+b)/(t-b) 0
252
- 0 0 -(f+n)/f-n (-2*f*n)/(f-n)
253
- 0 0 -1 0
254
- ]
255
-
256
- 实际上由于我们用的视网膜(near pane)是个关于远点对称的矩形,所以矩阵简化为:
257
- [
258
- n/r 0 0 0
259
- 0 n/t 0 0
260
- 0 0 -(f+n)/f-n (-2*f*n)/(f-n)
261
- 0 0 -1 0
262
- ]
263
-
264
- Args:
265
- r: right, t: top, n: near, f: far, b: bottom, l: left
266
- """
267
  return Mat4d(
268
  [
269
  [n / r, 0, 0, 0],
@@ -291,8 +252,7 @@ def draw(screen_vertices, world_vertices, model, canvas, wireframe=True):
291
 
292
 
293
  def draw_with_z_buffer(screen_vertices, world_vertices, model, canvas):
294
- """ z-buffer algorithm
295
- """
296
  intensities = []
297
  triangles = []
298
  for i, triangle_indices in enumerate(model.indices):
@@ -319,13 +279,7 @@ def draw_with_z_buffer(screen_vertices, world_vertices, model, canvas):
319
 
320
 
321
  def render(model, height, width, filename, cam_loc, wireframe=False):
322
- """
323
- Args:
324
- model: the Model object
325
- height: cavas height
326
- width: cavas width
327
- picname: picture file name
328
- """
329
  model_matrix = Mat4d([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
330
  # TODO: camera configration
331
  view_matrix = look_at(Vec3d(cam_loc[0], cam_loc[1], cam_loc[2]), Vec3d(0, 0, 0))
@@ -339,9 +293,7 @@ def render(model, height, width, filename, cam_loc, wireframe=False):
339
  return projection_matrix * view_matrix * world_vertex
340
 
341
  def ndc(v):
342
- """
343
- 各个坐标同时除以 w,得到 NDC 坐标
344
- """
345
  v = v.value
346
  w = v[3, 0]
347
  x, y, z = v[0, 0] / w, v[1, 0] / w, v[2, 0] / w
@@ -357,7 +309,7 @@ def render(model, height, width, filename, cam_loc, wireframe=False):
357
  0.5 * (f - n) * v.value[2, 0] + 0.5 * (f + n),
358
  )
359
 
360
- # the render pipeline
361
  screen_vertices = [viewport(ndc(mvp(v))) for v in model.vertices]
362
 
363
  with Canvas(filename, height, width) as canvas:
 
8
  from . import speedup
9
 
10
 
 
11
 
12
 
13
  class Vec2d:
 
123
  fill_top_flat_triangle(v2, v4, v3)
124
 
125
 
 
126
 
127
 
128
  class Vec3d:
129
  __slots__ = "x", "y", "z", "arr"
130
 
131
  def __init__(self, *args):
132
+
133
  if len(args) == 1 and isinstance(args[0], Vec4d):
134
  vec4 = args[0]
135
  arr_value = (vec4.x, vec4.y, vec4.z)
 
181
  self.arr = self.value.reshape((1, 4))
182
 
183
 
184
+
185
  def normalize(v: Vec3d):
186
  return Vec3d(*speedup.normalize(*v.arr))
187
 
 
208
 
209
 
210
  def look_at(eye: Vec3d, target: Vec3d, up: Vec3d = Vec3d(0, -1, 0)) -> Mat4d:
211
+
 
 
 
 
 
 
 
 
 
212
  f = normalize(eye - target)
213
  l = normalize(cross_product(up, f)) # noqa: E741
214
  u = cross_product(f, l)
 
224
 
225
 
226
  def perspective_project(r, t, n, f, b=None, l=None): # noqa: E741
227
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  return Mat4d(
229
  [
230
  [n / r, 0, 0, 0],
 
252
 
253
 
254
  def draw_with_z_buffer(screen_vertices, world_vertices, model, canvas):
255
+
 
256
  intensities = []
257
  triangles = []
258
  for i, triangle_indices in enumerate(model.indices):
 
279
 
280
 
281
  def render(model, height, width, filename, cam_loc, wireframe=False):
282
+
 
 
 
 
 
 
283
  model_matrix = Mat4d([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
284
  # TODO: camera configration
285
  view_matrix = look_at(Vec3d(cam_loc[0], cam_loc[1], cam_loc[2]), Vec3d(0, 0, 0))
 
293
  return projection_matrix * view_matrix * world_vertex
294
 
295
  def ndc(v):
296
+
 
 
297
  v = v.value
298
  w = v[3, 0]
299
  x, y, z = v[0, 0] / w, v[1, 0] / w, v[2, 0] / w
 
309
  0.5 * (f - n) * v.value[2, 0] + 0.5 * (f + n),
310
  )
311
 
312
+
313
  screen_vertices = [viewport(ndc(mvp(v))) for v in model.vertices]
314
 
315
  with Canvas(filename, height, width) as canvas: