Top.Mail.Ru
Ответы

Как можно оптимизировать эту функцию?

У меня есть функция с декоратором numba.cuda.jit, Она нужна для рендера. У неё есть 2 проблемы. Во-первых, возникают артефакты в виде белых точек или полосок. Во-вторых она медленная, когда проекция грани занимает много места на экране. То есть нужно оптимизировать часть с 2 циклами

функция довольно большая и не помещается в вопросе, поэтому я оставлю 2 частями


123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
 @cuda.jit 
def _render_FbF_kernel(surfarray, vertices, normals, tex_coords, faces, camera_fov, z_buffer): 
 
    face_index = cuda.grid(1) 
    if face_index < faces.shape[0]: 
 
        inv_camera_fov = 1 / camera_fov 
        max_surfarray_side = max(surfarray.shape[:2]) 
        surf_offsetx, surf_offsety = (max_surfarray_side - surfarray.shape[0]) / 2, (max_surfarray_side - surfarray.shape[1]) / 2 
        face = faces[face_index] 
        normal_az, normal_bz, normal_cz = normals[face[2], 2], normals[face[5], 2], normals[face[8], 2] 
 
        if normal_az != 0 and normal_bz != 0 and normal_cz != 0: 
 
            vertex_ax, vertex_ay, vertex_az = vertices[face[0]] 
            vertex_bx, vertex_by, vertex_bz = vertices[face[3]] 
            vertex_cx, vertex_cy, vertex_cz = vertices[face[6]] 
 
            if vertex_az > 0 and vertex_bz > 0 and vertex_cz > 0: 
 
                inv_az, inv_bz, inv_cz = 1 / vertex_az, 1 / vertex_bz, 1 / vertex_cz 
 
                proj_ax = (vertex_ax * inv_az * inv_camera_fov + 0.5) * max_surfarray_side - surf_offsetx 
                proj_ay = (vertex_ay * inv_az * inv_camera_fov + 0.5) * max_surfarray_side - surf_offsety 
                proj_bx = (vertex_bx * inv_bz * inv_camera_fov + 0.5) * max_surfarray_side - surf_offsetx 
                proj_by = (vertex_by * inv_bz * inv_camera_fov + 0.5) * max_surfarray_side - surf_offsety 
                proj_cx = (vertex_cx * inv_cz * inv_camera_fov + 0.5) * max_surfarray_side - surf_offsetx 
                proj_cy = (vertex_cy * inv_cz * inv_camera_fov + 0.5) * max_surfarray_side - surf_offsety 
 
                proj_x1 = max(int(min(proj_ax, proj_bx, proj_cx) - 1), 0) 
                proj_x2 = min(ceil(max(proj_ax, proj_bx, proj_cx) + 1), surfarray.shape[0]) 
                proj_y1 = max(int(min(proj_ay, proj_by, proj_cy) - 1), 0) 
                proj_y2 = min(ceil(max(proj_ay, proj_by, proj_cy) + 1), surfarray.shape[1]) 
 
                for pixel_x in range(proj_x1, proj_x2): 
                    for pixel_y in range(proj_y1, proj_y2): 
 
                        v0x, v0y = proj_cx - proj_ax, proj_cy - proj_ay 
                        v1x, v1y = proj_bx - proj_ax, proj_by - proj_ay 
                        v2x, v2y = pixel_x - proj_ax, pixel_y - proj_ay 
 
                        dot00 = v0x * v0x + v0y * v0y 
                        dot01 = v0x * v1x + v0y * v1y 
                        dot02 = v0x * v2x + v0y * v2y 
                        dot11 = v1x * v1x + v1y * v1y 
                        dot12 = v1x * v2x + v1y * v2y 
 
                        denom = dot00 * dot11 - dot01 * dot01 
                        proj_v = (dot11 * dot02 - dot01 * dot12) / denom 
                        proj_w = (dot00 * dot12 - dot01 * dot02) / denom 
                        proj_u = 1 - proj_v - proj_w 
Дополнен

if proj_u >= 0 and proj_v >= 0 and proj_w >= 0:

res_a, res_b, res_c = proj_u * inv_az, proj_w * inv_bz, proj_v * inv_cz
res_sum = res_a + res_b + res_c
point_u, point_v, point_w = res_a / res_sum, res_b / res_sum, res_c / res_sum
point_z = point_u * vertex_az + point_v * vertex_bz + point_w * vertex_cz
prev_z = z_buffer[pixel_x, pixel_y]

if prev_z > point_z or prev_z == 0:

z_buffer[pixel_x, pixel_y] = point_z

colour = 255 * abs(normal_az + normal_bz + normal_cz) / 3
surfarray[pixel_x, pixel_y] = colour, colour, colour

По дате
По рейтингу
Аватар пользователя
Мудрец
10мес

нет тут таких уникумов, спроси у гпт

Аватар пользователя
Мыслитель
10мес

Мозг себе оптимизируй