문제는 파이썬 코드가 각 pi3d.Shape에 대해 한 번에 하나씩 행렬 곱셈을 수행한다는 것입니다. 이것은 numpy를 사용하여 이루어 지지만 가능한 한 빠르지 만 여전히 느립니다.
당신은 프레임 당 만 1 무 필요합니다 하나 pi3d.MergeShape()로 구를 모두 만들 수 있으며, 매우 빠른 것입니다 ... 그러나
귀하의 구체 객체는 기본값을 사용 12면 × 12 조각으로 288면과 864 개의 정점을 제공하므로 MergeShape에 864,000 개의 꼭지점이 생겨 GPU의 속도가 느려지 게됩니다.
번들 셰이더는 전체 셰이프에 대해 하나의 재료 RGB 값을 사용하기 때문에 해킹 된 셰이더가 필요한 각 영역마다 다른 색을 지정해야합니다 (셰이더 해킹에 익숙하다면 쉽게 할 수 있음). 버퍼 배열의 텍스처 좌표 필드에 RGB 값을 지정하십시오.
는
당신이 기본이 각 영역에 대한 부드러운 3D 효과를 줄 것이다 mat_light됩니다 사용하고있는 쉐이더하지만 (데모 SpriteBalls 참조) 포인트를 관리 할 수있는 경우 표시되지 않습니다 코드는 당신이 할 수 수천 개의 구가 빠르게 실행됩니다 ...하지만 각 버텍스의 확산 색상을 변경하려면 쉐이더를 수정해야합니다.
또는 텍스처를 절반 파란색으로, 검정색으로 만들고 각 프레임의 다양한 영역의 텍스처 좌표를 조정할 수 있습니다. 모든 구체를 하나의 모양으로 병합했다고 가정하면 매우 빠르고 (x, y, z 중첩 루프의 효과를 재현 할 수있는 늠름없는 수식을 포함하지만)
앞으로 며칠 동안 이 옵션을하고 난 그냥 변수 색상 '빌보드'포인트를 사용하는 Starfield.py 데모를 기억 https://github.com/pi3d/pi3d_demos
편집에 추가하는 방법을 보여주는 데모를 고안한다. 이것은 매 프레임마다 수천 개의 포인트를 렌더링 할 수 있지만 비교적 단순한 구조를 모호하게 만드는 모든 종류의 복잡성을 가지고 있습니다. 위에서 언급했듯이 센터에서 유클리드 거리를 사용하여 색상 변경을 통해 10x10x10 어레이를 데모하는 간단한 버전을 만들 것입니다. 여기
2 편집 pi3d_demos/shaders/star_point
import pi3d
import numpy as np
DIM = 10
half_d = DIM/2.0
arr_len = DIM ** 3
disp = pi3d.Display.create()
shader = pi3d.Shader('shaders/star_point')
cam = pi3d.Camera()
spheres = pi3d.Points(camera=cam, point_size=400.0, z=15.0,
vertices=[[x - half_d, y - half_d, z - half_d] for x in range(DIM) for y in range(DIM) for z in range(DIM)],
normals=np.zeros((arr_len, 3)), tex_coords=np.full((arr_len, 2), 1.0))
spheres.set_shader(shader)
arr_buf = spheres.buf[0].array_buffer # shortcut to numpy array shape (1000,8) [[vx,vy,vz,nx,ny,nz,u,v]]
# the star_point shader uses nx,ny,nz as RGB values, only the B value is being
# changed here i.e. arr_buff[:,5]
i = 0
while disp.loop_running():
spheres.draw()
ix = np.where(np.sum((arr_buf[:,:3] - [half_d, half_d, half_d]) ** 2, axis=1) <= i * DIM)[0]
arr_buf[:,5] = 0.1 # set all to midnight blue first
arr_buf[ix,5] = 1.0 # set ones within (i * DIM) ** 0.5 to blue
spheres.re_init() # have to update buffer
i += 0.1
if i > 4.0:
i = 0.0
를 사용 빌보드 또는 스프라이트 버전 여기 MergeShape 후 자외선을 조정 사용 버전 I 발견
import pi3d
import numpy as np
DIM = 10
half_d = DIM/2.0
arr_len = DIM ** 3
disp = pi3d.Display.create()
shader = pi3d.Shader('uv_light')
cam = pi3d.Camera()
tex_array = np.zeros((16,16,3), dtype=np.uint8)
tex_array[:8,:8] = [0, 0, 25] # top left midnight blue
tex_array[8:, 8:] = [0, 0, 255] # bottom right bright blue
tex = pi3d.Texture(tex_array, mipmap=False)
spheres = pi3d.MergeShape(camera=cam, z=15.0)
spheres.merge([[pi3d.Sphere(radius=0.1, sides=6, slices=6), x - half_d, y - half_d, z - half_d, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0]
for x in range(DIM) for y in range(DIM) for z in range(DIM)])
spheres.set_draw_details(shader, [tex])
arr_buf = spheres.buf[0].array_buffer # shortcut to numpy array shape (1000,8) [[vx,vy,vz,nx,ny,nz,u,v]]
arr_buf[:,6:8] *= 0.5 # scale uv to just use top left part of texture
base_tex_c = arr_buf[:,6:8].copy()
i = 0
while disp.loop_running():
spheres.draw()
ix = np.where(np.sum((arr_buf[:,:3] - [half_d, half_d, half_d]) ** 2, axis=1) <= i * DIM)[0]
arr_buf[:,6:8] = base_tex_C# set uv to base (top left)
arr_buf[ix,6:8] += 0.5 # set index ix to bottome right
spheres.re_init() # have to update buffer
i += 0.1
if i > 4.0:
i = 0.0
좌표 그 배열 버퍼의 크기 기본 Sphere에서 너무 커져서 6x6 버전으로 축소되었습니다. 희망이 누군가가 어떤 단계에서 도움이됩니다.
당신이 사용하고있는 3D 패키지를 설명하기 위해 답을 수정하십시오 – Soviut
@Soviut 이미 나열되어 있습니다 ... [pi3d] (http://pi3d.github.io/html/index.html) – Aaron