엔진으로 내보내기

내보내기 창

내보내기(Ctrl+E)는 창 헤더에서 가져오기 바로 뒤에 있으며, 가져오기와 같은 모양의 창을 엽니다(D51):

  1. 에셋 파이프라인: 처음에는 헤더의 에셋 선택에 보이는 것입니다. 무엇을 쓸지는 에셋 그래프에서 설계합니다.
  2. 내보내기 폴더: 경로를 입력하거나 선택…으로 고르세요. 프로젝트가 기억합니다.
  3. 지금 내보내기: 저장 여부와 상관없이 열려 있는 그대로의 프로젝트. 내보내기는 프로젝트를 저장하지 않으며, 제목 없는 프로젝트도 그대로 내보냅니다.

내보내기 창: 에셋 파이프라인, 폴더, 쓸 파일, 내보내기 버튼

내보내기를 누르기 전에 창에는 내보내기가 쓸 모든 파일이 pxr names와 같은 이름으로 나열됩니다. 각 파일의 폴더 내 경로와 종류(스프라이트 시트, JSON, GIF…)가 표시되고, 폴더에 이미 있는 파일에는 덮어씀이 붙습니다. 에셋 파이프라인, 폴더, 프로젝트를 바꾸면 목록을 다시 찾습니다. 작은 로딩 표시만 나올 뿐 창을 멈추게 하지 않습니다. 그대로는 내보낼 수 없는 파이프라인(예: 출력 두 개가 한 파일에 씀)은 거기에 이유를 알려 주며, 고칠 때까지 내보내기가 기다립니다.

누르면 같은 행들이 제자리에서 그대로 내보내기가 됩니다. 각 행은 쓰기가 끝날 때까지 로딩 표시가 돌다가, 체크 표시, 크기, 열기(시스템이 그 파일을 여는 프로그램으로), 폴더 보기가 나타납니다. 잘못된 점은 멈춘 파일에 표시됩니다. 정지는 내보내기를 중간에 끝냅니다. 이미 쓴 것은 남고, 쓰던 파일은 지워집니다. 실행 중에 창을 닫아도 되며, 내보내기를 누르면 다시 열립니다.

명령줄이 실행하는 것을 그대로 실행합니다: pxr render PROJECT --pipeline NAME -o FOLDER를 별도 프로세스에서 실행하므로 Pixor는 계속 반응합니다. 열려 있는 그대로의 프로젝트 스냅숏을 생성된 폴더에 쓰고(파일 경로는 절대 경로로 바꿈) 내보내기가 끝나면 지웁니다. 파일 이름은 pxr render가 그 프로젝트에 붙이는 이름과 같습니다. 프로젝트 이름을 따르고, 제목 없는 프로젝트는 모델 이름을 따릅니다. 모든 파일은 파이프라인에서 새로 씁니다. 에셋 그래프 노드가 생성한 것을 복사하지 않습니다.

모든 파일은 폴더 안에 들어갑니다. 시트의 파일 이름은 프로젝트의 PNG 노드에서 가져옵니다(out/hero.png는 FOLDER/hero.png로 씁니다). 경로가 시트 폴더 아래에 있는 파일은 FOLDER 아래에서 같은 위치를 유지하고, 그 밖의 경로(아카이브, 애니메이션, 다른 곳을 지정한 아이콘)는 마지막 부분만 남깁니다.

내보내기가 쓰는 것

모든 내보내기는 시트를 씁니다. 액션과 방향마다 한 행, 프레임마다 한 열이며, 모든 칸의 크기가 같고 피벗이 칸마다 같은 픽셀에 있습니다. 에셋 그래프에서 시트에 File 노드를 추가하면(또는 명령줄에서 --export를 쓰면) 같은 이름의 파일이 옆에 생깁니다. 각각 시트에서 연결된 노드이며 자체 설정이 있습니다. --export all은 아래의 모든 형식을 쓰지만 p8와 video는 이름을 지정할 때만 씁니다. 카트리지는 그 용도로 만든 시트에만 맞고, 모든 클립과 방향의 무압축 동영상은 수 기가바이트가 될 수 있기 때문입니다. 두 형식이 같은 파일을 쓰는 일은 없습니다. 그런 프로젝트는 pxr names가 거부합니다.

형식 파일 용도
png name.png 인덱스 PNG 시트(인덱스 0이 투명)
json name.json 칸 사각형, 프레임 지속 시간, 액션과 방향마다 태그 하나, 피벗. Aseprite의 “array” 레이아웃이라 Aseprite용 임포터가 읽을 수 있습니다
aseprite name.aseprite 인덱스 Aseprite 파일: final, lines, flat 레이어와 스타일 그래프의 추가 출력마다 레이어 하나, 액션과 방향마다 태그 하나, 프레임별 지속 시간, pivot 슬라이스
노멀 name_normal.png 2D 조명용, 같은 레이아웃의 노멀 맵
깊이 name_depth.png 같은 레이아웃의 깊이: 가장 가까운 곳이 흰색, 가장 먼 곳이 어둡고, 시트 전체가 한 배율(meta.pixor.depth가 둘 다 미터로 제공). 아무것도 없는 곳은 투명. 정렬, 안개, 2.5D 조명용
발광 name_emission.png 빛나는 각 픽셀을 자기 색으로, 빛나는 만큼 밝게(발광 재질 또는 모델의 이미시브 맵). 나머지는 투명. 발광과 블룸용
레이어 name_lines.png, name_flat.png, 그리고 스타일 그래프의 추가 출력마다 name_LAYER.png 선과 평면 색 레이어를 시트로, 그리고 스타일 그래프가 지정한 곳에서는 노드의 이미지
팔레트 name.hex, name.gpl 팔레트(Lospec과 GIMP 형식)
godot name.tres Godot 4 SpriteFrames 리소스
gif name_walk_Southeast.gif, … 액션과 방향마다 애니메이션 GIF 하나. 홀드는 프레임 지연으로. 공유와 미리보기용
apng name_walk_Southeast.apng, … 애니메이션 PNG로 같은 것, 정확한 밀리초 지연 포함
동영상 name_walk_Southeast.avi, … 액션과 방향마다 동영상 하나: 모든 픽셀을 그대로 담은 무압축 AVI. 트레일러나 스토어 페이지용
light-kit name_ramps.png, name_normal.png, name_light.png, 셰이더 엔진에서 팔레트에 맞는 조명(아래 참고)
보고서 name_report.png 모든 검사의 발견 항목을 표시한 시트(아래 참고)
p8 name.p8 PICO-8 카트리지(콘솔 모드 참고)
zip 노드의 경로 에셋 그래프의 ZIP 압축 파일 노드: 거기에 연결된 파일, 또는 내보내기가 쓴 모든 것

행 이름은 액션과 방향을 따릅니다: walk_Southeast.

시트가 어떤 프레임을 가져가고, 어떻게 배치하고, 렌더 한 번에 파일을 몇 개 쓸지는 에셋 그래프가 정합니다. 연결을 바꾸기 전까지는 Sheet 노드 하나와 그 File 노드들입니다.

프레임의 이름과 정체

시트의 모든 프레임에는 이름과 id가 있으며, 둘은 서로 다른 질문에 답합니다.

이름은 템플릿입니다. 프로젝트 자체의 단어로 된 패턴이라, 기본값 그대로가 초보자에게 맞고, 스튜디오는 직접 고르지 않은 규칙도 따를 수 있습니다.

{project}_{action}_{side}_{index:2}.{ext}     hero_walk_East_00.png

쓸 수 있는 단어는 {project}, {object}, {action}, {side}, {layer}, {set}(Sprites 노드가 프레임을 그릴 때 쓴 파츠 세트), {size}, {index}, {ext}입니다. {index:3}은 숫자를 0으로 채워 세 자리로 만듭니다. {{와 }}는 중괄호를 씁니다. Pixor가 모르는 단어는 템플릿을 입력할 때 오류가 되며 hero_{genre}_00.png 같은 파일이 생기지 않습니다. 내용이 없는 단어는 앞의 구분자도 함께 빠지므로, 방향이 없는 스프라이트는 hero_Static_00.png가 됩니다.

파일 이름에 쓸 수 없는 값(/ \ : * ? " < > |)은 조용히 바꾸지 않고 거부하며, 공백은 _이 됩니다. 유일한 예외는 Pixor 자체의 단어입니다. lib:walk라는 라이브러리 클립은 이름에서 lib-walk가 됩니다. 그 콜론은 여러분이 아니라 Pixor의 것이기 때문입니다.

같은 이름이 될 두 프레임은 렌더링 전에 거부됩니다. 명령줄에서 --names로 정하거나 프로젝트에 보관하세요.

pxr project set hero.pixor --names '{object}/{action}-{side}-{index:3}.{ext}'
pxr names hero.pixor                  # what it will write, without rendering
pxr names hero.pixor --json           # the same, for a build script

ID는 프레임이 무엇인지를 말하며, 어디에 놓였는지는 말하지 않습니다. 오브젝트, 액션, 방향, 액션 안의 시간, 레이어의 해시로, JSON과 .aseprite 사용자 데이터의 모든 프레임 옆에 기록됩니다. 시트를 다시 패킹하거나, 클립을 추가하거나, 패딩을 바꾸면 사각형은 움직이지만 ID는 그대로이므로, 프레임을 ID로 참조하는 빌드는 패커가 돌 때마다 깨지지 않습니다. 클립을 다른 프레임 레이트로 다시 샘플링하면 ID가 바뀝니다. 다른 프레임이기 때문입니다.

더 작은 시트

에셋 그래프의 Arrange 노드에서(또는 명령줄에서):

  • 빈 공간 잘라내기(--trim)는 각 프레임을 픽셀이 있는 부분만 남기고 자릅니다. JSON은 전체 셀 안에서 각 프레임의 위치(spriteSourceSize, trimmed: true)를 주고, Godot 파일은 각 프레임의 margin을 설정하므로, 엔진은 여전히 모든 프레임을 피벗에 맞춰 놓습니다.
  • 반복 프레임을 한 번만 저장(--dedupe): 완전히 같은 프레임(홀드 포즈, 정지한 오브젝트의 방향들)은 한 자리를 공유합니다.
  • 최대 시트 너비(--max-width 4096)는 시트가 그보다 넓어지기 전에 새 행을 시작합니다. 텍스처 크기 제한이 있는 엔진과 GPU용입니다.
  • 최대 시트 높이(--max-height 2048)는 그보다 높은 시트를 클립 단위로 페이지에 나눕니다: hero_1.png, hero_2.png. 각각 자체 JSON과 다른 파일이 옆에 놓입니다.
  • 행당 프레임(--columns 8)은 한 행에 그만큼의 프레임을 놓고, 모든 클립을 앞 클립 뒤에 이어 배치합니다: 밀착 인화지, 또는 엔진 임포터가 요구하는 고정 격자.
  • 다른 방향에서 만든 방향(에셋 그래프의 Flip 노드): 좌우 대칭 모델은 왼쪽에서 본 모습이 오른쪽에서 본 모습을 뒤집은 것과 같으므로 서쪽은 아예 렌더링할 필요가 없습니다. 동쪽 카메라의 스프라이트를 서로 뒤집으면 시트에 walk_East에서 만든 walk_West가 생기고, 픽셀, 노멀, 상자, 루트 모션도 대칭으로 뒤집힙니다. 서로 다른 카메라만 렌더링하고 나머지는 뒤집으세요.
  • 모든 방향의 각도가 JSON에 있습니다: 각 프레임에(pixor.degrees), 그리고 전체는 meta.pixor.sides 아래에({"South": 0, "Southeast": 45, ...}). 정면 기준 각도로, 위에서 볼 때 반시계 방향이며 --sides가 받는 방식과 같습니다. 게임은 이 표로 각도를 행으로 바꿉니다.

그림자 레이어

그림자 레이어(--shadow contact 또는 --shadow drop)는 시트와 같은 배치로 name_shadow.png를 씁니다. 그림자가 지는 곳은 검정, 나머지는 투명입니다. Contact는 발밑에 모델의 발자국 크기로 생기는 얼룩이고, 드롭은 주광 반대쪽 바닥에 드리운 실루엣입니다. 원하는 불투명도로 스프라이트 아래에 그리거나 따로 정렬하세요. 에셋 그래프의 Layer 노드는 shadow를 지정할 수 있고, 오버레이로 시트 하나에서 스프라이트 아래에 깔 수 있습니다(에셋 그래프).

실행 중 색 순환

순환 재질이 있으면 JSON은 각각을 meta.pixor.cycles 아래에 나열하고("material"과 팔레트에서의 "indices", 순환 순서대로), Pixor는 시트를 팔레트 인덱스로 담은 name_index.png를 씁니다. 엔진은 프레임을 더 저장하는 대신 틱마다 그 팔레트 항목을 돌릴 수 있습니다. 같은 음영을 공유하는 다른 재질도 일반 팔레트 순환처럼 함께 순환하니, 따로 두려면 순환 재질에 고유한 색을 주세요.

여러 모델로 된 장면과 패럴랙스 배경

프로젝트에는 여러 개를 담을 수 있습니다. 바닥 평면 위에 배치한 모델들을 하나의 그림으로, 조명 하나와 서로 드리우는 그림자와 함께 렌더링합니다. 마을 한 모퉁이, 던전 방, 야영지, 무료 라이브러리로 만든 스토어 페이지 아트 같은 것이죠.

각각은 아이템입니다. 모델 하나와 그 위치, 바라보는 방향, 크기로, 장면 그래프의 Item 노드이며 체인 끝에 추가되고, 뒤에 오는 링이나 흩뿌리기가 이를 반복합니다. 명령줄에서는 --item 하나가 아이템 하나입니다:

pxr project new camp.pixor \
  --item tent.glb@-1.8,-1.6,25,1.2 \
  --item campfire.pixoritem@0,0 \
  --item barrel.glb@2,1,0,1,2 \
  --ground 7,5,#5d7a45 \
  --size 200
pxr render camp.pixor

@x,z[,yaw[,scale[,layer]]]는 아이템이 서는 위치입니다(미터 단위, x는 오른쪽, z는 카메라 쪽). --ground W,D[,#rrggbb]는 그 아래에 바닥 평면을 깝니다. :clip[,phase]를 붙이면 그 아이템은 옆의 아이템들이 가만히 있는 동안 자기 클립을 자기 시점부터 재생합니다. 경로는 프로젝트 기준 상대 경로입니다.

패럴랙스 레이어(패럴랙스 레이어 File 노드, 레이어 2~8개, 또는 --parallax N)는 스크롤 배경용으로 이미지를 깊이에 따라 레이어로 나눕니다. 각 레이어는 같은 무대와 팔레트에서 따로 렌더링되며, 먼 레이어일수록 거리감처럼 헤이즈 색(--haze) 쪽으로 더 어둡고 푸르게 바랩니다(먼 레이어 흐리게를 끄거나 --haze none을 쓰면 팔레트가 고정된 게임을 위해 모든 레이어를 팔레트 그대로 둡니다). 아이템의 layer는 그 아이템을 특정 레이어에 넣고(0이 가장 먼 레이어), 나머지는 깊이에 따라 나뉩니다. Pixor는 name_layer0.png, name_layer1.png, …, name_parallax.json(레이어마다 이미지와 권장 스크롤 속도, 가장 먼 레이어 0.25부터 가장 가까운 레이어 1까지), 그리고 레이어를 쌓은 name_parallax.png를 씁니다. 여러 모델로 된 장면만이 아니라 어떤 모델이든 나눌 수 있습니다. 에셋 그래프의 Layer 노드는 layer0, layer1, … 처럼 레이어 이름을 지정해 그 레이어만의 시트를 만들게 합니다(에셋 그래프). pxr project set --parallax N --haze #rrggbb|none은 프로젝트에 두 설정을 모두 지정합니다.

콘솔 모드

홈브루와 판타지 콘솔용으로는 스타일 아래에서 콘솔을 고르세요(또는 --console). 그러면 Pixor가 그 콘솔 고유의 색과 제한을 씁니다:

콘솔 색 스프라이트마다 메모
Game Boy 초록 음영 4가지 3 + 투명 밝기별 음영
NES 54색 마스터 팔레트 3 + 투명 8×8 타일 단위로도 검사
PICO-8 해당 16 모든 16 .p8 카트리지 내보내기(p8 체크. 시트가 128×128에 들어가야 하므로 최대 너비를 128로 설정)
TIC-80 16(Sweetie 16) 모든 16 TIC-80의 import sprites로 PNG를 가져오세요
C64 해당 16 3 + 투명 멀티컬러 스프라이트: 픽셀이 두 배 넓음. 너비는 짝수로 유지(C64 스프라이트는 24 px)

스프라이트에 세 가지 색만 쓸 수 있는 경우, Pixor는 그림자, 기본 색, 빛에서 모델을 가장 잘 덮는 콘솔 색 세 가지를 골라 모든 프레임과 방향이 같은 세 색을 쓰게 합니다. 스타일 섹션은 화면의 프레임이 맞는지 알려 주며, pxr console check sheet.png은 시트 전체(색, 프레임당·타일당 색, 두 배 너비 쌍, 크기)를 검사하고 시트 안의 레시피에서 콘솔을 읽습니다. 콘솔 모드의 모든 렌더는 자신이 쓴 시트에 같은 검사를 실행하고, 맞지 않으면 실패합니다(종료 코드 1, 문제 목록 출력). 직접 정한 팔레트는 콘솔 모드에서도 콘솔 팔레트로 바뀌지 않고 유지됩니다. 그래서 Game Boy에 16색 팔레트를 쓰면 조용히 초록 네 색으로 바뀌는 대신 분명하게 경고합니다. NES 색은 Pixor가 콘솔의 영상 신호에서 계산하고, 나머지는 각 콘솔의 공개된 값입니다.

엔진에서 팔레트를 지키는 조명

엔진은 노멀 맵으로 스프라이트를 부드러운 음영으로 밝히는데, 이 과정에서 팔레트에 없던 색이 생깁니다. 조명 키트(또는 --export light-kit)를 체크하면 스프라이트가 게임 속 조명에 반응하면서도, 빛을 받는 모든 픽셀이 Pixor의 명암 띠, 색조 이동, 하이라이트와 함께 자기 색 램프의 단계에 머무릅니다. Pixor는 시트 옆에 다음을 씁니다:

파일 무엇인가
name_ramps.png 각 픽셀의 색 램프(램프 번호 + 1을 빨강 채널에. 선처럼 빛이 닿지 않는 픽셀은 0)
name_normal.png 노멀, 뷰 공간: x 오른쪽, y 위, z 카메라 쪽
name_light.png 룩업: 램프마다 한 행, 빛 단계마다 한 열, 그다음 하이라이트 색, 그리고 색이 아닌 두 열. 그 램프 자체의 하이라이트 임곗값입니다. 광택이나 금속 재질은 무광 재질보다 하이라이트를 쉽게 받기 때문입니다
pixor_palette_light.gdshader, name_light.tres Godot 셰이더와 모든 텍스처가 설정된 재질: 재질을 Sprite2D나 AnimatedSprite2D에 넣으세요
PixorPaletteLight.shader Unity 셰이더: SpriteRenderer용 재질을 만들고 맵 세 개를 설정하세요
pixor_palette_light.fsh, .vsh GameMaker 셰이더. 주석에 맵을 연결하는 방법이 있습니다

셰이더는 주광 하나(light_dir, 노멀 공간에서 빛을 향하는 방향), 프리셋의 보조광, 그리고 램프마다 룩업 텍스처에서 임곗값을 가져오는 반사광과 림 하이라이트로 빛을 계산하며, Pixor 자체 방식과 같습니다. specular나 rim을 -1과 1 사이의 수로 설정하면 스프라이트 전체에 덮어쓰고, 1보다 크면 그 하이라이트를 끄며, -1 미만(기본값)이면 룩업 값을 씁니다. 하이라이트는 이웃한 네 픽셀 중 하나도 하이라이트를 받을 때만 그려지며, 이는 외톨이 밝은 픽셀을 막는 Pixor 자체 규칙입니다. min_highlight를 1로 하면 이를 끕니다. 스크립트로 조명을 옮기세요. 예를 들어 횃불 쪽으로: material.set_shader_parameter("light_dir", dir). 세 맵은 필터링, 압축, 밉맵 없이 가져오세요. 내보내기 전에 보려면 스프라이트 위에서 2D 조명 미리보기(L)를 켜고 Light as: the light kit를 고르세요. 빛이 포인터 쪽으로 돌고, 프레임은 셰이더와 같은 룩업과 같은 규칙(하이라이트는 다른 하이라이트 옆에만, 램프가 없는 픽셀은 그대로)으로 빛을 받습니다. 렌더의 빛으로 보면 프레임은 Pixor가 그린 그대로입니다(예외는 띠 경계의 몇 픽셀). 드리운 그림자, 디더링, 애니메이션 시트의 깜빡임 완화는 Pixor에만 있으므로, 엔진에서 빛을 줄 시트는 드리운 그림자를 끄세요. JSON은 meta.pixor.light_kit 아래에 파일과 조명을 나열합니다.

팔레트 변형

변형 추가(--variant NAME, 여러 번 사용 가능)는 같은 시트를 다른 색으로 내보냅니다. Pixor는 팔레트 인덱스로 그리므로 변형은 팔레트만 바꿉니다. 모든 픽셀, 선, 음영은 제자리에 그대로 있습니다.

  • 이펙트: hit-flash, frozen, poisoned, petrified, burning, silhouette, selected, 시간대 dawn, noon, dusk, night, 계절 autumn과 winter(초록이 주황으로, 또는 창백하고 눈 덮인 색으로 바뀝니다).
  • 팀 색상: team:blue(또는 red, green, yellow, purple, orange, teal, pink, white, black, 또는 team:#3050e0)는 팀 색상 — --team이나 재질 아래에서 표시한 재질 또는 색 — 만 다시 칠하고 피부, 강철, 금은 그대로 둡니다. 음영마다 밝기를 유지하므로 램프가 여전히 읽힙니다. 스프라이트 하나로 네 팀: --team cloth --variant team:red --variant team:blue --variant team:green --variant team:yellow. JSON은 아래의 룩업 텍스처로 런타임에 다시 칠하는 엔진을 위해 팀의 팔레트 인덱스를 meta.pixor.team 아래에 나열합니다.
  • 모든 색 돌리기: hue:120는 색이 있는 모든 음영을 120도 돌립니다. 회색은 회색으로 남습니다.
  • 다른 팔레트: palette:pixor-8나 palette:my-colours.hex는 모든 색을 그 팔레트에서 가장 가까운 색으로 옮기되, 밝은 색과 어두운 색은 구분해 둡니다.

변형마다 name_<variant>.png입니다. 변형이 하나라도 있으면 Pixor는 실행 중에 팔레트를 바꾸기 위한 파일 두 개도 써서, 시트 하나로 모든 등급과 팀을 처리합니다:

  • name_index.png: 각 픽셀의 팔레트 인덱스를 회색 값으로 담은 시트(0은(는) 투명);
  • name_lut.png: 너비 256픽셀의 룩업 텍스처로, 팔레트마다 한 행입니다(0행은 시트 자체, k행은 변형 k).

셰이더는 lut(index / 255, row)를 조회합니다. JSON은 변형과 그 행을 meta.pixor.variants 아래에 나열합니다.

모든 내보내기에 담긴 레시피

Pixor가 내보내는 모든 파일은 자신을 만든 프로젝트를 기억합니다: 시트, 레이어 시트와 맵(_lines, _flat, _normal, _depth, _emission, _shadow), 팔레트 변형과 인덱스 시트, .aseprite, 그리고 각 GIF(주석에)와 APNG. 그중 아무거나 Pixor에 놓으면(또는 프로젝트 열기에서 고르면) 프로젝트가 돌아옵니다. .pixor 파일이 아직 있으면 그 파일을, 없으면 레시피로 다시 만든 새 프로젝트를 엽니다. 경로는 내보낸 파일 기준 상대 경로로 저장되며, 상대 경로로 만들 수 없는 경로는 파일 이름만 남기므로 공유한 시트에 폴더 이름이 드러나지 않습니다. 빼려면 파일 속 레시피를 해제하세요(또는 --no-recipe를 주세요).

Godot 4

  1. name.png와 name.tres를 프로젝트의 같은 폴더에 복사하세요.
  2. .tres는 res://name.png에서 시트를 불러옵니다. 다른 곳에 두었다면 명령줄에서 내보낼 때 --godot-path res://path/name.png를 주거나, .tres 맨 위의 경로를 고치세요.
  3. AnimatedSprite2D를 만들고 Sprite Frames를 name.tres로 설정하세요. 모든 액션과 방향이 프레임 홀드를 갖춘 반복 애니메이션입니다.
  4. 선명한 픽셀을 원하면 Texture > Filter를 Nearest로 설정하세요.

Unity

  • Aseprite Importer 패키지가 있으면(2D Aseprite Importer): name.aseprite를 Assets에 넣으세요. 태그마다 애니메이션 클립이 됩니다. final 레이어를 쓰세요.
  • 없으면: name.png를 Sprite (Multiple), Filter Mode Point, Compression None으로 가져와 셀 크기로 자르세요(셀 크기는 name.json의 meta.pixor.cell에 있습니다). 피벗은 meta.pixor.pivot에 셀 왼쪽 위 기준 픽셀 단위로 있습니다.

GameMaker

name.png를 스프라이트 띠로 가져오세요. 애니메이션마다 Strip 배치로 내보내거나(--layout strip) 칸 크기로 격자를 자르세요. 원점은 name.json의 피벗으로 설정하세요.

Aseprite

name.aseprite를 열거나, Aseprite 파일 노드의 열기를 클릭하세요(Pixor는 PATH와 일반적인 Steam, itch 폴더에서 Aseprite를 찾고, 없으면 위치를 묻습니다). 태그는 모든 액션과 방향을 나열합니다. final 레이어가 보이며, lines와 flat은 손으로 다듬기 위한 숨은 보조 레이어이고, 스타일 그래프가 이름을 붙인 추가 출력도 final 위에 숨은 레이어로 있습니다. 파일은 Pixor의 팔레트를 쓰는 인덱스 모드입니다.

위에 그리고, 작업은 지키세요. 레이어를 추가해 그린 다음, Pixor에서 모델이나 룩을 바꾸고 다시 구우면 됩니다.

pxr rebake out/hero.aseprite

Pixor는 자기가 쓴 것만 관리합니다. 다시 구우면 프로젝트를 다시 렌더링하고 다음과 같이 합니다.

  • Pixor가 만든 레이어(final, lines, flat)의 픽셀을, 아무도 칠하지 않은 곳에서 교체합니다.
  • 내 레이어를 정확히 그대로 둡니다. 옮기거나 이름을 바꾸거나 순서나 색을 바꾸지 않으며, 칠한 각 셀은 칠한 프레임에 남습니다. 모든 프레임에는 그 내용(액션, 방향, 시간)으로 만든 ID가 있어서, 걷기 중간에 프레임이 셋 늘어도 칠한 눈은 새 포즈로 미끄러지지 않고 원래 포즈에 남습니다. 다시 굽기는 이를 프레임마다 알려 줍니다: moved your paint on frame 1 is on frame 2 now, 그리고 어느 프레임이 새것인지(--json의 moved와 new_at).
  • 칠한 모든 색을 그 인덱스에 유지하고 새 색은 팔레트 끝에 추가합니다. Aseprite에서 그레이스케일이나 RGB로 바꾼 시트라면 그에 맞춰 렌더를 회색이나 색으로 씁니다.
  • 슬라이스와 그 키를, 프레임이 어디로 갔든 원래 프레임에 유지합니다.
  • 모델이 칠한 부분 아래에서 벗어난 프레임에 태그(pxr check)를 달고, 칠은 그대로 둡니다.

혼자 정하지 않고 내가 정할 때까지 둘 다 남겨 두는 두 가지:

무슨 일이 있었나 다시 굽기가 하는 일
Pixor 자체 레이어 중 하나에 칠한 경우 Pixor의 레이어에는 새 렌더가 들어가고, 여러분의 편집은 바로 위의 자체 레이어 final edits로 옮겨지며, 그 프레임에는 pxr conflict 태그가 붙습니다
직접 그린 프레임이 새 렌더에 없음(클립이 짧아짐) 프레임은 칠한 것과 함께 끝에 남고 pxr removed 태그가 붙습니다

어느 쪽이든 잃는 것은 없습니다. 그러면 pxr rebake는 어느 쪽으로 할지 정할 때까지 코드 7로 종료합니다: --resolve keep는 편집한 내용을 여러분의 레이어로 유지하고, --resolve pixor는 Pixor의 렌더를 택하고 편집을 버립니다. --dry-run은 아무것도 쓰지 않고 다시 굽기가 무엇을 할지 알려 주며, --json은 도구를 위해 같은 내용을 출력합니다. 확장 기능은 같은 질문을 대화 상자로 묻습니다.

GIF와 APNG

액션과 방향마다 따로 반복 재생되는 파일이 됩니다(반복하지 않는 클립은 한 번 재생됩니다). 프레임은 스프라이트의 팔레트를 쓰며, 인덱스 0이 투명입니다. GIF나 APNG 노드의 Scale(--anim-scale K)은 1부터 16까지 정수 배로 확대하므로, 64 px 스프라이트를 모든 픽셀이 선명한 256 px GIF로 내보낼 수 있습니다.

GIF는 지연 시간을 100분의 1초 단위로 저장하므로 프레임마다 지연이 반올림되지만, 클립의 전체 길이는 유지됩니다. 브라우저는 20 ms 미만의 지연을 100 ms로 보여 주므로 GIF 프레임은 20 ms보다 짧을 수 없습니다. 50 fps를 넘으면 GIF는 그보다 짧게 표시될 프레임을 빼고, 클립과 같은 길이로 재생됩니다. APNG는 정확한 밀리초를 저장하며 JSON처럼 누적 합계에서 반올림하므로, 12 fps 클립의 프레임은 83 ms와 84 ms입니다. 사이트가 PNG만 받는다면 .apng 파일 이름을 .png로 바꾸세요. 에셋 그래프의 Layer 노드가 그린 클립은 시트에 보이는 그대로 그 레이어(선만, 평면 색만)를 애니메이션합니다. 노멀, 깊이, 발광 맵의 Layer는 스프라이트를 애니메이션합니다. GIF에는 팔레트 색만 담기 때문입니다.

동영상

클립마다 동영상은 각 액션과 방향을 name_walk_Southeast.avi로 씁니다. 24비트 색의 무압축 AVI로, 어느 편집기와 변환기든 열 수 있고 손실이 없어 코덱이 픽셀을 뭉개지 않습니다. 노드에는 설정이 세 가지 있습니다.

  • 배율(1~16, 처음은 4): 아트 픽셀 하나가 동영상 픽셀 몇 개인지.
  • 초당 프레임(1~100, 처음에는 30): 동영상은 한 가지 속도로 재생되므로 스프라이트 프레임은 지속 시간만큼 여러 번 쓰이고, 클립 길이는 동영상 프레임 하나 오차 안으로 유지됩니다.
  • 배경: 스프라이트 뒤에 있는 것. 동영상에는 투명도가 없습니다.

명령줄의 --export video는 기본값을 쓰거나 --video-scale K, --video-fps N, --video-background #RRGGBB를 받습니다. --export all은 동영상을 빼므로 따로 지정하세요.

압축하지 않으므로 큽니다. 64 px 스프라이트를 배율 4로 하면 프레임당 약 200 KB이며, 1기가바이트가 넘는 동영상은 쓰지 않고 거부합니다. 온라인에 올리려면 변환하세요: ffmpeg -i hero_walk_South.avi -crf 0 hero_walk_South.mp4.

일반 엔진과 직접 만든 코드

name.json을 읽으세요: frames[i].frame은 칸 사각형이고 frames[i].duration은 밀리초 단위 홀드입니다. meta.frameTags는 프레임을 애니메이션으로 묶으며, 반복하지 않고 한 번만 재생하는 태그에는 Aseprite가 쓰는 방식대로 "repeat": "1"가 붙습니다. frames[i].pixor는 프레임의 tag(프레임 태그 이름), 그 안의 index, action과 side, id, 그리고 pivot을 지정합니다. 피벗은 엔진이 스프라이트를 세우는 칸 안의 지점으로, Tag 노드가 클립에 따로 주지 않았다면 시트의 피벗입니다. meta.slices의 피벗 슬라이스에는 피벗이 바뀌는 곳마다 키가 있고, .aseprite 파일의 피벗 슬라이스에도 같은 키가 있습니다.

루트 모션

제자리로 내보낸 클립은 프레임마다 값이 두 개 더 있으며, 소수를 유지한 픽셀 단위입니다(x는 오른쪽, y는 아래).

  • frames[i].pixor.root: 클립 시작 때의 위치를 기준으로 잰, 모델 루트가 있을 위치.
  • frames[i].pixor.root_delta: 다음 프레임까지 루트가 움직이는 거리. 마지막 프레임은 클립 끝까지의 이동이므로, 반복되는 걷기가 같은 속도로 계속 나아갑니다.

클립처럼 캐릭터를 움직이려면 프레임이 끝날 때마다 스프라이트 위치에 root_delta를 더하세요.

인벤토리 아이콘

pxr icons(또는 에셋 그래프의 아이콘 노드로, 프로젝트를 내보낼 때 만들어짐)는 모델을 서로 어울리는 인벤토리 아이콘으로 바꿉니다. 모든 모델을 Studio 조명 리그 아래 같은 ¾ 각도에서 16, 24, 32, 48픽셀(또는 --sizes)로, 실루엣은 희귀도 색(--rarity common|uncommon|rare|epic|legendary)으로, --framed를 주면 인벤토리 칸 같은 테두리 타일 위에 그립니다. 아이콘은 각각 PNG이고, 크기마다 아틀라스 icons_N.png와 각 아이콘의 위치를 담은 icons_N.json이 생깁니다. 폴더를 지정하면 팩 전체를 아이콘 세트로 만듭니다. 앱에서는 폴더를 창에 놓고 스프라이트 대신 아이콘을 켜세요. 크기, 희귀도(직접 고르지 않으면 각 파일 이름에서), 테두리를 정할 수 있고, 레시피는 아이콘 옆에 icons.pixoricons로 저장됩니다.

pxr icons library/pickups --out icons --rarity epic --framed

--rarity from-name은 파일 이름의 단어에 따라 각 모델에 희귀도를 줍니다(potion_rare.glb, Sword-Epic.glb. 그런 단어가 없으면 common). JSON에 각 아이콘의 희귀도가 기록됩니다. 파일은 이름순으로 처리하므로 폴더가 어떤 순서로 나열하든 아틀라스는 같습니다.

레시피가 팩을 보관합니다: --save pack.pixoricons는 폴더와 설정(레시피 기준 상대 경로)을 쓰고, pxr icons pack.pixoricons는 팩을 바이트 하나까지 똑같이 다시 만듭니다. 폴더에 추가한 소품은 다음 실행에 포함되며, 레시피 뒤에 붙인 플래그는 그 실행에서만 설정 하나를 바꿉니다(pxr icons pack.pixoricons --sizes 64).

복셀과 스프라이트 스택

MagicaVoxel .vox도 다른 모델처럼 열립니다: 장면의 모든 모델이 장면 그래프가 놓은 자리에(MagicaVoxel에서 보이는 대로 회전·이동해서), 팔레트와 함께, 발광 재질의 복셀은 빛나는 채로 들어옵니다. 복셀 하나는 0.1미터, +Z가 위입니다.

pxr voxels MODEL -o hero.vox --height 32는 어떤 모델이든 높이 32의 복셀로 바꿉니다. 표면은 텍스처와 색에서 샘플링하고 속은 채우며, 모든 복셀은 룩 자체의 팔레트(--preset, --palette 등 룩 옵션)를 써서 스프라이트와 맞습니다. --stack을 붙이면 스프라이트 스택도 씁니다: 모델을 수평 슬라이스로 잘라 아래부터 나란히 놓고 각각 위에서 본 hero_stack.png, 그리고 슬라이스 크기와 개수가 담긴 hero_stack.json. 게임은 슬라이스 k를 슬라이스 k - 1보다 한 픽셀 위에 그리고 모두 함께 돌립니다. 이것이 스프라이트 스태킹이 3D를 흉내 내는 방식입니다.

pxr voxels knight.glb -o knight.vox --height 32 --stack --preset selout

모든 것이 맞는지 확인하기

pxr audit folder --style game.pixorkit은 폴더 안의 내보낸 PNG와 .aseprite 파일을 모두 읽고, 각 파일 안의 레시피로 키트와 대조합니다. 프리셋, 조명 리그, 뷰, 카메라 기울기, 주광, 명암 띠, 선, 팔레트, 미터당 픽셀, 그리고 쓰인 모든 색이 키트 팔레트에 있는지를 봅니다. 키트가 없으면 첫 파일이 기준이 됩니다. 차이마다 나열하며, 차이가 하나라도 있으면 종료 상태가 1이(가) 되므로 빌드를 지키는 데 쓸 수 있습니다.

앱에서 일관성 보드(사람 셋 모양 버튼, 일관성 보드: 모든 방향을 한 번에, 또는 B)는 현재 프레임을 모든 방향에서 한 지면선 위에 나란히 보여 주며, 실루엣마다 꼭대기를 표시하고 아래에 너비, 높이, 색 수를 적습니다. 버튼 아래에는:

  • 실루엣은 모든 방향을 한 가지 색의 형태만으로 그립니다. 실루엣으로 읽히지 않는 포즈는 게임 크기에서도 읽히지 않습니다.
  • 피벗은 각 방향이 딛고 서서 도는 픽셀을 표시합니다. 발이 피벗에서 벗어난 방향은 스프라이트가 돌 때 미끄러집니다.
  • 색 개수는 방향마다 색 수를 적습니다. 방향 사이에 높이가 1픽셀 넘게 다르거나(Heights differ … between sides), 한 방향이 다른 방향보다 색이 몇 개 더 많으면(대개 한 방향에서만 받는 빛 때문) 보드가 알려 줍니다.

위의 pxr audit는 폴더 전체를 보는 쪽입니다. 모든 시트를 키트 하나와 대조합니다.

검사에서 찾은 문제를 해당 픽셀 위에 표시

Pixor의 모든 검사(떠도는 픽셀, 1픽셀로 그린 선 모서리, 두꺼운 선, 팔레트에 없는 색, 콘솔 모드가 허용하는 것보다 색이 많은 타일이나 프레임)는 내보낼 때 텍스트 한 줄만 출력하는 대신 해당 픽셀을 표시합니다.

  • 앱에서: 스프라이트 위의 검사 버튼(경고 삼각형)이 프레임에 표시를 그리고, 스타일 단계와 에셋 단계의 보고서 섹션이 지금까지 렌더링한 모든 프레임의 발견 항목을 나열합니다. 하나를 클릭하면 Pixor가 표시를 켠 채 그 프레임과 방향으로 갑니다. 목록 아래에는 발견 항목 종류마다 어떤 설정이 결정하는지 나옵니다. 떠도는 픽셀은 정리, 들쭉날쭉한 모서리는 선, 색은 팔레트, 게임기 제약은 콘솔 모드, 내보내기의 대칭과 맞지 않는 뒤집힌 방향 등이며, 이동을 누르면 그 설정이 열립니다.
  • 대칭 방향: 에셋 그래프에 Flip 노드가 있으면 뒤집어 그릴 방향을 원본 방향과 비교해, 모델이 충분히 대칭이 아닌 곳에서 달라지는 픽셀을 표시합니다. 내보낼 때 경고만 하는 것이 아니라 아직 고르는 동안에 알려 줍니다.
  • 내보낼 때: report(또는 --export report)를 체크하면 Pixor가 시트 옆에 name_report.png를 씁니다. 모든 발견 항목을 표시한 시트입니다. 픽셀 하나는 채워서, 타일이나 프레임은 상자로 둘러 표시하므로 무엇에 관한 것인지 그대로 보입니다.
색 대상
청록 떠도는 픽셀(고아 픽셀)
노랑 한 픽셀에서 모서리를 꺾는 선
자홍 2×2 선 덩어리: 두꺼운 선
빨강 팔레트를 벗어난 픽셀
주황 콘솔이 허용하는 것보다 색이 많은 8×8 타일
진한 주황 콘솔이 허용하는 것보다 색이 많은 프레임
분홍 콘솔에 없는 색
보라 미러 원본 방향과 다른 픽셀
초록 상자 텍스처 파일이 없어 기본 색으로 그린 파츠: 파일을 모델 옆에 두세요

픽셀 이펙트

장면 그래프의 이펙트 노드(아웃라이너의 이펙트 아래에 나열)는 3D 파티클로 그린 이펙트를 추가합니다: Explosion, Hit-spark, Slash, Magic-burst, Heal, Portal, Smoke-puff, Dust, Fire-loop, Rain, Snow, Fireflies, Falling-leaves. 각각 자체 액션(fx-explosion, …)이며 모델과 같은 파이프라인으로 렌더링되므로, 스프라이트의 팔레트, 픽셀 크기, 빛, 선을 따라 같은 게임에 속한 것처럼 보입니다. 프레임, 크기, 에너지, 위치, 시드(같은 시드는 언제나 같은 픽셀)를 정하고, 본을 따라가게 하거나(손에서 나오는 베기, 총구의 섬광) 클립 위에서 재생하세요(베기 아래의 휘두르기, 또는 Pixor에서 키를 준 클립). 이펙트만에 체크하면 모델 없이 캐릭터 시트에 맞춘 별도 레이어로 그립니다. 타격 프레임은 타격이 들어가는 프레임을 표시하며, JSON은 이를 meta.pixor.hits 아래에 나열합니다. 명령줄에서는 --effect fireflies:12 --effect-clip shatter --effect-hit 6이며, 클립은 Pixor에서 만든 것도 됩니다 — 반짝임 아래로 날아가도록 키를 준 파편. 빈 프로젝트 화면에서 가져오기…, 무료 모델 둘러보기 옆의 이펙트 만들기(또는 pxr effect explosion -o fx.png)는 모델 없이 이펙트만 만듭니다.

히트박스, 허트박스, 소켓

인스펙터에서 파츠의 상자(또는 --hitbox, --hurtbox)는 그 파츠를 히트박스(타격을 주는 것: 검)나 허트박스(맞을 수 있는 것: 몸)로 만들고, 본의 JSON의 소켓(또는 --socket)은 본을 소켓(손, 총구)으로 만듭니다. 그러면 모든 프레임의 JSON에 pixor.boxes(part, kind, x, y, w, h, 각 파츠가 실제로 덮는 픽셀에서 구한 셀 픽셀 단위)와 pixor.sockets(셀 픽셀 단위의 각 본 위치)이 담기므로, 게임 코드는 추측하지 않고 타격을 판정하고 효과를 붙일 수 있습니다. 모델 파일에서도 파츠를 표시할 수 있습니다(pxr.box).

페이퍼 돌 레이어

소품을 붙이면 페이퍼 돌 레이어(--paper-doll)는 소품을 뺀 모델을 같은 캔버스에 담은 name_base.png와, 소품마다 보이는 픽셀과 그 둘레 선을 담은 레이어 하나(name_sword.png)도 씁니다. 바탕부터 쌓으면 전체 시트가 되고, 소품 레이어를 바꾸면 장비가 바뀝니다. name_stacked.png는 엔진이 쌓을 방식대로 쌓은 것으로, 서로 맞는지 보여 주는 미리보기입니다. 모든 조각의 픽셀은 시트 자체의 것입니다. 바탕은 조각 없이 그린 몸이므로 시트와 다른 곳은 조각 가장자리 몇 픽셀 안쪽과 조각이 몸에 그림자를 드리우는 곳뿐입니다. 정확히 겹쳐지는 레이어가 필요하면 드리운 그림자를 끄세요(--no-shadow). Sprites 노드가 파츠 세트로 그리는 행은 레이어가 아니라 그 노드의 시트에 속합니다. (앱은 저장된 프로젝트에서 pxr로 레이어를 만들며, 프로젝트가 바뀌었으면 먼저 저장하므로 레이어는 화면에 보이는 그대로입니다.)

모델의 일부인 장비(소품으로 붙이지 않고 캐릭터와 함께 모델링한 투구, 방패, 망토)는 피스입니다:

pxr render knight.glb --clip all --paper-doll --piece helmet:Knight_Helmet --piece gear:Round_Shield,1H_Sword
pxr project set knight.pixor --paper-doll --piece helmet:Knight_Helmet

조각마다 자신을 이루는 파츠의 이름을 (아웃라이너에 나열된 대로) 적으며, 소품처럼 name_helmet.png라는 자체 레이어가 됩니다(앱에서는 파츠의 자체 페이퍼 돌 레이어가 그 파츠 이름으로 레이어를 만듭니다). 보이는 픽셀만 들어가므로, 몸 뒤의 방패는 몸에 가려진 부분이 숨겨집니다. 기본 레이어는 모든 조각과 소품 없이 렌더링되므로, 투구가 가리던 것(그 아래의 머리)이 그려집니다. --no-pieces는 프로젝트에서 조각을 지웁니다. 에셋 그래프의 Layer 노드는 base 또는 조각이나 소품의 이름을 레이어로 지정해 원하는 대로 레이어를 배치합니다(에셋 그래프).

이 페이지에서 설명하는 내용을 내 모델로, 브라우저에서 무료로 체험해 보세요.

브라우저에서 체험 Pixor 구매