Skydimo 스크립트 개발의 세계에 오신 것을 환영합니다! 이 가이드는 초보자든 숙련된 사용자든 Lua 스크립트를 사용해 나만의 RGB 조명 효과를 만드는 방법을 배우는 데 도움을 줍니다. 이 기능은 Skydimo 베타 버전에서 제공됩니다.
목차
기능 개요
- 창작의 자유: Lua 코드로 독창적인 조명 효과를 작성합니다
- AI 어시스턴트: 한 문장으로 맞춤 효과를 생성하며, AI가 코드 작성과 최적화를 도와줍니다
- 오디오 반응: 음악에 맞춰 조명이 움직이며, 실시간 FFT 스펙트럼 분석을 지원합니다
- 다중 탭 관리: 여러 스크립트를 동시에 편집하고 손쉽게 전환 및 정리할 수 있습니다
- 핫 리로드: 변경 사항이 즉시 적용되며, 소프트웨어를 재시작할 필요가 없습니다
- 가져오기/내보내기: 나만의 결과물을 공유하거나 커뮤니티 스크립트를 사용할 수 있습니다
- 완전한 제어: 속도, 밝기, 색온도, 색조를 모두 자유롭게 조정할 수 있습니다
빠른 시작
첫 번째 스크립트: 레인보우 그라디언트
Skydimo의 “스크립트” 페이지에서 새 스크립트를 만들고 다음을 입력합니다.
function get_color(x, y, width, height, env)
-- 위치와 시간을 기반으로 레인보우 색상 생성
local hue = (x / width * 360 + env.time * 60) % 360
return hsv(hue, 255, 255)
end
단계:
- 우측 상단의 “모드 등록” 버튼을 클릭합니다(우측 상단 버튼은 왼쪽부터 순서대로 등록/업데이트 모드, 복원, 등록 해제, 내보내기, 가져오기입니다)
- 모드 목록에서 방금 등록한 스크립트를 찾습니다
- 클릭하여 활성화하면 기기에 흐르는 레인보우 그라디언트 효과가 표시됩니다
코드 설명:
get_color: 각 픽셀마다 호출되는 함수x / width: 0–1 범위의 위치 비율을 생성합니다env.time: 계속 증가하는 시간 값으로, 색상이 흐르도록 만듭니다hsv(): 색조, 채도, 밝기를 RGB 색상으로 변환합니다
Lua 스크립트 기초
Lua란 무엇인가요?
Lua는 가볍고 배우기 쉬운 프로그래밍 언어입니다. Skydimo는 Lua 5.4를 사용합니다.
기본 문법 빠른 참조
-- 한 줄 주석
--[[
여러 줄 주석
여러 줄로 작성할 수 있습니다
]]
-- 변수 정의(타입 선언 불필요)
local speed = 100
local name = "Rainbow"
local enabled = true
-- 수학 연산
local result = (10 + 5) * 2 / 3
-- 조건문
if x > 10 then
-- 코드 실행
elseif x == 5 then
-- 다른 경우
else
-- 기본 경우
end
-- 반복문
for i = 1, 10 do
-- 10번 반복
end
-- 함수 정의
local function calculate(a, b)
return a + b
end
핵심 API 사양
필수 함수: get_color(x, y, width, height, env)
용도: 각 LED의 색상 값을 계산합니다(프레임마다 여러 번 호출됨)
매개변수:
x,y: 현재 픽셀 좌표(0부터 시작)width,height: 기기의 전체 너비/높이env: 환경 변수 객체
반환값: 32비트 정수, 형식은 0x00BBGGRR(Blue-Green-Red 순서, 각 채널 0–255)
예제:
function get_color(x, y, width, height, env)
return rgb(255, 0, 0) -- 순수한 빨간색
end
선택 함수: begin_frame(env)
용도: 매 프레임 시작 시 한 번 실행되며, 사전 계산이나 프레임 단위 변수 초기화에 사용됩니다.
-- 전역 변수에 사전 계산 결과를 저장
local wave_offset = 0
function begin_frame(env)
-- 프레임마다 한 번씩 웨이브 오프셋 계산
wave_offset = math.sin(env.time) * 50
end
function get_color(x, y, width, height, env)
-- 사전 계산된 값을 직접 사용
local hue = (x / width * 360 + wave_offset) % 360
return hsv(hue, 255, 255)
end
환경 변수
env 환경 객체에서 자주 사용되는 필드:
env.time: 시작 이후 누적된 시간(초, 실수)env.dt: 이전 프레임에서 현재 프레임까지의 시간 간격(초)env.fps: 현재 프레임 레이트(초당 프레임 수)env.random: 0–1 범위의 랜덤 시드(프레임마다 변경됨)env.bpm: 분당 비트 수(BPM), 리듬 기반 효과에 사용(선택 사항)env.audio: 오디오 데이터 객체(선택 사항)env.audio.level: 전체 볼륨 엔벨로프, 0–1env.audio.fft: 저음에서 고음 순으로 정렬된 스펙트럼 배열env.audio.sampleRate: 오디오 샘플링 레이트env.audio.enabled: 오디오 입력이 활성화되어 있는지 여부
내장 함수 라이브러리
색상 구성 및 변환:
rgb(r, g, b): 32비트 색상을 반환합니다hsv(h, s, v): HSV를 RGB로 변환합니다. h: 0–360, s/v: 0–255saturate(v): 값을 0–1 범위로 제한합니다clamp(v, min, max): 범위를 잘라냅니다mix(a, b, t)/lerp(a, b, t): 선형 혼합smoothstep(edge0, edge1, x): 스무스 스텝map(x, inMin, inMax, outMin, outMax): 범위 매핑
노이즈 및 랜덤:
random(): 0–1 랜덤 값noise1(x)/noise2(x, y): 매끄러운 노이즈
오디오 시각화
스펙트럼 시각화 예제:
local spectrum = {}
function begin_frame(env)
if env.audio and env.audio.fft then
spectrum = env.audio.fft
end
end
function get_color(x, y, width, height, env)
if not spectrum or #spectrum == 0 then
return rgb(10, 10, 10)
end
local band = math.max(1, math.floor((x / width) * #spectrum))
local amp = spectrum[band] or 0
local h = (band / #spectrum) * 360
local v = math.floor(math.min(255, amp * 255 * 1.5))
return hsv(h, 255, v)
end
실행 메커니즘
렌더링 루프 순서:
- 프레임 시작 시
begin_frame(env)를 호출합니다(구현된 경우) - 이후 각 픽셀마다
get_color(x, y, width, height, env)를 호출합니다 - 해당 프레임의 색상 버퍼를 기기로 전송합니다
성능 팁:
- 복잡한 계산은
begin_frame에서 수행하고 결과를 캐싱합니다 - 임시 테이블을 많이 생성하지 않도록 합니다
- 가능하면 사전 계산된 조회 테이블을 사용합니다
AI 지원 개발
스크립트 에디터에 원하는 효과를 설명하면(예: “저음이 웜 컬러 바를 구동하고, 비트 펄스가 밝기를 강화한다”), AI가 초기 코드를 생성합니다. 이후 계속해서 수정 제안을 통해 빠르게 반복 개선할 수 있습니다.
실전 예제
1) 스펙트럼 바 차트(가로형)
local smoothed = {}
function begin_frame(env)
if not (env.audio and env.audio.fft) then return end
local fft = env.audio.fft
for i = 1, #fft do
local v = fft[i]
smoothed[i] = smoothed[i] and (smoothed[i] * 0.6 + v * 0.4) or v
end
end
function get_color(x, y, width, height, env)
if not smoothed or #smoothed == 0 then return rgb(0,0,0) end
local band = math.max(1, math.floor((x / width) * #smoothed))
local level = smoothed[band] or 0
local barH = math.floor(level * height)
if (height - 1 - y) <= barH then
local hue = (band / #smoothed) * 360
return hsv(hue, 255, 255)
else
return rgb(0, 0, 0)
end
end
모범 사례
- 무거운 계산과 데이터 전처리는
begin_frame에서 우선 처리합니다 - 자주 접근하는 전역 객체는 로컬 변수로 캐싱합니다
- 임시 테이블 생성에 주의하고, 루프 내에서
table.insert로 인한 확장 오버헤드를 피합니다 - 매개변수와 반환값에 경계값 검사를 적용해 보호합니다
- 색상과 밝기 범위를 0–255로 일관되게 유지하고, 초과 시 클리핑합니다
FAQ
Q1: get_color의 반환 형식은 무엇인가요?
A: 32비트 정수를 반환하며, 형식은 0x00BBGGRR입니다.
Q2: 오디오 시각화가 반응하지 않는 이유는 무엇인가요?
A: env.audio.enabled와 입력 기기를 확인하세요. 또한 실행 환경에서 마이크 권한이 허용되었는지 확인하세요.
Q3: 프레임 레이트를 높이려면 어떻게 해야 하나요?
A: get_color 내부의 복잡한 계산을 줄이세요. 재사용 가능한 값은 begin_frame에 두세요. 임시 테이블 생성을 피하세요.
Q4: 여러 스크립트를 동시에 실행할 수 있나요?
A: 호스트 구현에 따라 다릅니다. 디버깅과 성능 보장을 위해 기기당 하나의 스크립트만 활성화하는 것을 권장합니다.