Community이미지github.com

코드 화실

이미지 모델을 부르지 않고 코드로 정지 화면을 그립니다. 패스 트레이싱, 수채, 만화, 판화, 타이포 포스터까지.

코드 화실란 무엇인가요?

코드로 그림을 완성하는 화실입니다. 화풍을 고르고 짧은 장면을 쓴 뒤 PNG를 직접 렌더합니다. 인물, 풍경, 글자, 픽셀 아트, 생성적 추상을 다룹니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Wexop/atelier/tree/HEAD

Installed? Explore more 이미지 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

atelier — 짧은 파이썬 스크립트로 구동되는 이미지 스튜디오

설치 (Python ≥ 3.11): pip install git+https://github.com/Wexop/atelier (업데이트: pip install -U git+...) 확인: atelier palette · atelier brushes · atelier fx (시그니처).

루프 (항상)

  1. 스타일 가이드(아래 스타일 참조)를 선택하고 읽습니다. 맞는 것이 없으면 → styles/new-style.md.
  2. scene.py 작성 (30–80줄, from atelier import *, Canvas c를 만들고, c.save(__file__[:-3] + ".png")로 끝냄).
  3. atelier render scene.py --preview → scene_prev.jpg (512px, 실제 저해상도 렌더, 저장 생략). 이미지를 읽습니다.
  4. atelier inspect scene.py → scene_sheet.jpg: 보기, 5-value 연구 + 3등분/초점, 클립 맵, 히스토그램, 팔레트, 4개의 자동 확대(앨리어싱, 밴딩, 노이즈, 하이라이트)에 --crop x,y,w,h로 레이블, 메트릭 + 빨간 플래그. 읽습니다. 확대: atelier render scene.py --crop x,y,w,h.
  5. ≥3번의 보고 수정 라운드(atelier compare old.png new.png로 A/B 비교), 그런 다음 atelier render scene.py (최종; --scale 2, --seed N → SEED). 오류는 한 줄 scene.py:LINE: Type: message로 출력 (--debug는 역추적).

규칙

  • 그리기 좌표 = 캔버스 픽셀 (y 아래 방향). 필드는 정규화된 x, y ∈ [0,1]을 사용합니다. 색상: "#hex", CSS 이름, (r,g,b) 0–1 또는 0–255.
  • 페인트 소스 (fill=, color=, stroke=) = 색상 | 필드 | f(x,y) | 배열 H×W×3/4. 마스크 = 필드 | 도형 | 배열 | f(x,y).
  • 모든 랜덤은 seed=를 사용합니다. 미리보기는 저해상도로 렌더링됩니다. 그림은 동일하며 최종에서만 더 선명합니다.

캔버스 및 레이어 (핵심)

c = Canvas(w, h, bg=None, pixel=False)      # pixel=True: 안티앨리어싱 없음, 고정 스케일, 최근접 이웃 내보내기
L = c.layer(blend="normal", opacity=1, mask=None)   # 새 레이어, 현재 레이어가 됨; c.use(L)로 다시 전환
블렌드: normal multiply screen overlay soft_light hard_light add subtract color_dodge color_burn darken lighten difference hue saturation color luminosity
c.fill(src, mask=None) · c.erase(mask) · c.place(img|path, x=None, y=None, scale=None(cover), rot=0, fit="cover"|"contain", blend, opacity) -> layer
c.apply(*fx, mask=None)   # 모든 레이어를 병합한 다음 효과(최종 그레이딩); L.apply(*fx, mask=None) = 하나의 레이어
c.save(path, quality=92, scale=1, smooth=None) · c.preview(path, width=512) · c.crop_preview(path, x, y, w, h)
c.flatten() -> H×W×4 float · L.rgba (get/set) · c.w c.h (논리적) c.W c.H c.s (래스터 스케일)

필드 (field) — 지연, 합성 가능: + - * * * * > <, np.sin(f), f.ramp() f.warp() f.scale() f.rotate() f.move() f.remap(lo,hi) f.clip() f.within(shape|(x0,y0,x1,y1))

X Y radial(cx,cy) angle(cx,cy) · Field(lambda x, y: ...)
perlin/simplex/value(scale=4, seed) · fbm(scale=4, octaves=5, lacunarity=2, gain=.5, seed, base="perlin")
ridged(scale=3, ...) · turbulence(scale=4, ...) · worley(scale=6, mode="F1"|"F2"|"F2-F1"|"id", seed)
domain_warp(f, strength=.1, scale=2, seed) · aastep(f, edge=.5) · smoothstep(e0, e1, v) · mix(a, b, t)
패턴 [0,1]: wood(rings=14, angle) marble() clouds(scale, cover=.5, sharp) terrain_height() water_ripples() fabric(scale=60) paper() stars(density=60, size)
gradient(stops, angle=90 (위→아래; 0 = 왼→오른), kind="linear"|"radial"|"conic", center, radius)
ramp(f, stops) / f.ramp("sunset") · stops = 팔레트 이름 | ["#..", ...] | [(pos, col), ...]   (OKLab 보간)
palette("name") 이름: sunset night ocean forest desert earth fire ice pastel neon vapor viridis wood marble mono retro16 green4
cosine_palette(a, b, c, d, n=8) · rgb2hsv hsv2rgb rgb2oklab oklab2rgb
shade(height, light=(azimuth, elevation), strength=1, color=None, ambient=.25, spec=0)   # 색상 없음 → 회색, flat=0.5 (오버레이 레이어에서 사용)
마스크: top(f) bottom(f) left(f) right(f) band(y0, y1) zone(x0, y0, x1, y1) disc(cx, cy, r)  (모두 soft=)
곡선: f.ridge_line(y=.6, amp=.15) / curve(lambda x: y) → c.fill_below(curve, src) / fill_above · curve.below()

벡터 및 텍스트 (vector) — Shape = skia 경로, 필드 마스크 역할도 함; 부울 연산 | & - ^

rect(x, y, w, h, r=0) ellipse(cx, cy, rx, ry) circle(cx, cy, r) polygon(pts) line(x1,y1,x2,y2 | pts) regular(cx,cy,r,n)
star(cx, cy, r, r2, n=5) arc(cx, cy, r, start, sweep) spline(pts, closed) svg("M .. C .. A .. Z") union(*shapes)
shape.move/rotate(deg)/scale/outline(width, dash)/soft(feather)/points(n)/bounds/length
c.draw(shape, fill="black", stroke=None, width=2, cap="round", join="round", dash=(on, off), feather=0, opacity=1)
c.rect/ellipse/circle/polygon/line/spline/path(d)(..., **동일 스타일)
c.text(txt, x, y, size=32, fill, font="sans"|"mono"|"serif"|family|path.ttf, weight="regular"|"semibold"|"bold"|int,
       align="left"|"center"|"right", valign="baseline"|"top"|"middle"|"bottom", spacing=em, line_height=1.2, italic, fit=width_px, kern=True)
text_shape(...) → Shape · text_size(txt, size) → (width, cap_height) · c.text_on_path(txt, shape|points, size, align, lift, fit, fill)
c.text_box(txt, x, y, w, h=None, size=18, align="left"|"justify"|"center", line_height=1.4, fit=True)   # **b** *i* [#c33]색상[/]
c.title(txt, x, y, size=96, style="shadow"|"extrude"|"outline"|"inline"|"neon", fill, color2)

브러시 (brush)

c.stroke(points|Shape, brush="round", size=12, color, pressure=[...]|f(t)|float, opacity, jitter, spacing, taper=(a, b), seed, **params)
브러시: round round_soft airbrush ink(speed) chalk(tooth) bristle(n, var, gaps) oil(impasto, pickup) watercolor(edge, granulation, bleed)
c.paint_like(ref, brush="oil", sizes=(48,24,12), tol=.08, angle=0, seed)   # 참조 이미지(Canvas/Field/image)를 스트로크로 다시 그림
c.scatter(what, n, region=mask, size=(a, b), color=col|list|palette|Field, color_jitter, rot=(a, b), seed)
   what: dot soft star grass leaf petal square person | Shape (단위 크기, 0,0)
c.hatch(region, angle=45, spacing=8, width=1.2, color, tone=Field (0=어두움 → 두꺼움), cross=False, wobble)
km_mix(a, b, t) 안료 혼합(파랑+노랑 = 초록) · L.relief = 1.0 (오일 임파스토 조명 강도)

효과 (fx) — c.apply(...) / L.apply(...); 크기는 캔버스 픽셀 단위

blur(r) motion_blur(len, angle) sharpen(amt) bloom(threshold=.75, radius=12, strength=.8, tint) glow(r, strength, color)
drop_shadow(dx, dy, r, color, opacity) inner_shadow(...) vignette(amount=.35, softness=.6) grain(amount=.04, size=1, seed)
chromatic_aberration(px) lens_distortion(k) exposure(stops) contrast(amt) levels(black, white, gamma) curves([(in, out), ...], channel)
hue_sat(hue_deg, sat_mult, light) saturation(x) color_balance(shadows=(r,g,b), mids, highlights) gradient_map(stops) invert()
tone_map("agx"|"filmic"|"reinhard", exposure, look="punchy") displace(field, strength) posterize(levels)
pixelate(size, palette=name|list, colors=N, dither=None|"bayer"|"fs", strength=.6) halftone(size, angle, ink, paper, cmyk=False)
god_rays(x, y, rays=14, length=.9, strength=.45, color, threshold=.7, occlude=True) lens_flare(x, y, strength=.6, color, ghosts=6, streak=.5)
depth_of_field(depth, focus, aperture=8)   # r = c.render(scene)에서 깊이 가져옴
match_palette("ref.jpg", amount) transfer_tone(ref, amount)   # 참조 이미지에서 색상/톤 전송

스타일화 (stylize) — 3D → 일러스트레이션 + 회화적 필터 (c.apply / L.apply를 위한 효과)

r = c.render(s, alpha=True); c.cur.apply(toon(r, bands=3, shadow=.45, colors={id: col}), shadow_dots(r, size=5, lo=.3), outlines(r, width=2.5, inner=1))
engraving: L.fill(PAPER, mask=r.alpha); L.apply(render_hatch(r, s, spacing=4.5, layers=3), outlines(r, width=2))  # 해칭이 3D 표면을 따름
kuwahara(radius=6) oil · xdog(sigma=1, eps=.9, ink, paper) 잉크 라인 · pencil() · linocut(lines=7, angle) · edge_smooth(4)
watercolorize(bleed=2, edge=1, granulation=.4, ink=0..1) · stained_glass(cell=26, lead=3) · mosaic(tile=10) · shading(r) → (H,W) light

3D (sdf) — y 위쪽, 단위 ≈ 미터, 프리미티브는 원점 중심

sphere(r) box(w, h, d) round_box(w, h, d, r) cylinder(r, h) capsule(a, b, r) torus(R, r) cone(r1, h, r2) plane(y, normal)
ellipsoid(rx, ry, rz) lathe([(radius, y), ...] 아래→위, thickness=None|shell) extrude([(x, y), ...], depth)
연산: a | b, a & b, a - b, a.union(b, k=smooth) .inter .sub · .move(x,y,z) .rotate(x,y,z deg) .scale(k|(kx,ky,kz))
     .onion(t) .round(r) .twist(k) .bend(k) .repeat(period, count) .mirror("x") .elongate() .displace(noise3(scale, octaves, seed), amount)
Mat(color | 2D Field (proj="tri"|"xz"|"xy"|"zy", tex_scale) | f(p, n)->(N,3), rough=.5|Field|f(p,n), metal=0, glass=0, ior=1.45,
    sss=0, sss_color, emit=None, power=1, bump=.3, bump_scale=60, local=True (텍스처가 객체를 따름), sheen=.6,
    wear=[smudges(.5), scratches(.5, density=40), dust(.3), edge_wear(.5, width=.01, color)])
s = Scene(); id = s.add(sdf, Mat(...)); s.camera(pos, target, fov=40)
s.sun(dir_toward_sun, color, power=3, soft=.04) · s.point(pos, color, power, radius) · s.area(pos, size=(w,h), normal, color, power, pattern="window"|"softbox", visible)
s.studio(key, target, size, power=45, window=True, fill=.2, bg) · s.sky(zenith, horizon, ground, power) · s.fog(color, density)
r = c.render(s, aa=1|2, exposure=0, look=None|"punchy", alpha=False)          # 빠른 레이마처 (직접 광 + AO + 1 반사)
r = c.pathtrace(s, spp=16, bounces=4, denoise=True, aperture=0, focus=None|dist|(x,y), seed=SEED)  # 포토리얼리스틱: GI, 다중 굴절 유리, 적응형 AA
r.depth r.normal r.id r.mask(id) r.focus_at(x, y, c.s) r.linear r.spp r.time · denoise(img, albedo, normal, depth)

자연 (nature, terrain)

h = terrain(384, kind="alpine"|"hills"|"mesa"|"island"|"dunes", seed, erosion=1, flow=False)   # 침식된 고도 맵 [0,1]; erode() thermal()
c.terrain_map(h, style="relief"|"topo"|"shaded", water=.2)
v = c.landscape(h, cam=(x, alt, z), yaw, fov, horizon=.58, sun_elev=10, sun_az=30, haze=1, clouds=.35, water=.1, waves=.02, snow=.7, seed)
    v.depth v.water v.project(x, y, z) -> (px, py, px_per_m) v.ground(x, z)   # 3D 지형에 2D 나무 배치
c.sky(sun_elev=8, sun_az=0, horizon=.6, clouds=.3, haze=1) · c.sea(sun_elev=6, waves=.12, wave_len=60, foam=.5, clouds=.25)
c.tree(x, y, height_px, kind="oak"|"pine"|"birch"|"palm"|"bush"|"dead", season="summer"|"spring"|"autumn"|"winter", haze=0..1, seed)
c.grass(x, y, w, h, n) c.flower(x, y, size, kind="daisy"|"poppy"|"tulip"|"bell") c.fern(x, y, size) · tree3d("oak", 4, seed) → (trunk, leaves) SDFs
scene_sky(s, sun_elev, sun_az)   # 3D Scene의 물리적 하늘
c.anime_cloud(x, y, w, h=.55w, palette="day"|"sunset"|"dusk"|"storm"|(shadow,mid,light,rim), light=(az, elev), bands=3, rim=.7, wisps, edge, bottom, seed)  # 셀 음영 적운, 평평한 바닥
c.anime_tree(x, y, height, kind="round"|"tall"|"umbrella", palette="summer"|"spring"|"autumn"|"sakura"|"dusk"|(sh,mid,lt,rim,trunk), light, width, leafy=.6, seed)  # 셀 음영 나무
c.anime_mountains(y_foot, height, peaks=4, x0, x1, palette="day"|"dusk"|"autumn"|(sh,mid,lt,snow,snow_sh,haze), light, snow=.35, haze=.6, sharp=1, depth=.35, bands=3, seed)  # 침식된 지형, 정면, 셀 톤
c.sparkles(n, region=mask, size=(6, 16), color, rays=4, glow=.6, seed)   # 별 반짝임 (물, 눈)

인물 (figure) — 발 위치 (x, y), 키 = 서 있는 픽셀 (동물: 어깨높이)

c.figure(x, y, h, pose="stand", style="flat"|"line"|"silhouette"|"stick"|"ink"|"chalk", kind="human"|"cat"|"dog"|"horse"|"bird", seed)
   포즈: stand idle walk run sit wave point cheer jump dance think hips phone reach · phase=0-1 (걷기 사이클) view="front"|"3q"|"side"|"back"
   body=adult|teen|child|elder build=slim|heavy outfit="tee pants|coat skirt|dress" hair=short|bob|long|bun|curly skin=SKIN name colors={...}
figure_shape(...) → Shape · figure_joints(...) → {"hand_r": (x, y), ...} (소품 부착) · figure_sdf(pose, height=1.75, style="mannequin")
c.crowd(n, box=(x0, y0, x1, y1), horizon=y, height=near_px, tint=(haze, .5), dogs=.1, seed)   # 원근 조정된 군중

검사 (inspect) — 축소된 보기만이 아닌 숫자로 판단

m = metrics(c|path|arr)   # noise (<1 청정, >4 입자) aliasing (% 하드 스텝, >35 톱니) banding clip_shadows/highlights flags[...]
contact_sheet(c, "sheet.jpg") · compare(a, b, "ab.jpg") · guides(c) / composition(c) → 초점, 균형, 기울기 · analyze_reference("ref.jpg")

스타일 — 장면을 작성하기 전에 일치하는 가이드를 읽으십시오

가이드는 이 파일 옆의 styles/ 디렉토리에 있습니다 (없는 경우: https://raw.githubusercontent.com/Wexop/atelier/main/styles/<name>.md). 각 가이드는 레시피, 규칙, 함정 및 예제 스크립트를 제공합니다. 여러 스타일을 혼합할 수 있습니다 (예: anime + flat).

  • anime.md — 채색된 애니메이션 풍경: 셀 구름, 나무, 산, 림 라이트, 갓 레이, 반짝임
  • oil.md — 오일 (paint_like) 및 수채화 워시
  • photoreal.md — 경로 추적 정물/제품, 지형 풍경, 바다와 하늘
  • comic.md — ligne claire / 3D에서 툰, 조각, 잉크 필터
  • flat.md — 평면 벡터, 포스터, 타이포그래피, 사람, 실루엣 장면
  • pixel.md — 팔레트 및 디더링을 사용한 픽셀 아트
  • abstract.md — 왜곡된 필드에서 생성된 추상
  • new-style.md — 맞는 가이드 없음: 룩을 연구하고, 프리미티브에 매핑하고, 페인트한 다음 새 styles/<name>.md 저장

함정

  • c.layer()는 현재 대상을 변경합니다: 이후 c.text/...는 해당 레이어로 이동합니다 (multiply인 경우 문제). c.layer() 또는 c.use(L)을 호출하세요.
  • c.apply()는 모든 레이어를 병합합니다. 레이어를 유지하려면 L.apply()를 사용하세요.
  • shade(strength)는 필드 주파수에 따라 다릅니다: 큰 형태에는 ≈1, 미세한 질감(직물)에는 ≈.05.
  • 2D 아트에 tone_map을 적용하면 순수 흰색이 회색이 됩니다. HDR/3D용입니다; 일러스트레이션에는 curves/levels를 사용하세요.
  • 하드 임계값은 앨리어싱을 유발합니다: 가시적인 가장자리에는 f > .5 대신 aastep/smoothstep을 사용하세요.
  • 노이즈 scale = 캔버스 높이당 특징 수. 도형 좌표 = 캔버스 픽셀; 필드 좌표 = 0–1.
  • 비용: pathtrace ≈ 30–60 µs/경로 (1200×800 @ 8 spp ≈ 2코어에서 5분, 미리보기는 4배 적은 spp) — c.render로 초안 작성; 낮은 spp에서 광택 금속/유리에 반짝임 (spp 증가). aa=2 ≈ 4배. 많은 SDF 부품(인물, tree3d, displace)은 추적 속도가 느립니다.
  • 유리: rough=0은 투명 (기본 rough .5는 젖빛). c.render에서 유리는 한 번 구부러짐; 실제 굴절에는 pathtrace 사용

…

[번역을 위해 잘림]

관련 스킬