은하의 우주1
은하의 우주1
Galaxy of Universes & Spiral Nebula
해당 글은 AI로 대부분의 코드가 작성됨을 알림.
사람의 손을 썼으나, 수학적 표현 및 코드 대부분 AI가 작성함
재귀 구면반전 프랙탈과 다중 옥타브 확률장을 결합한 순수 WebGL/GLSL 우주 시각화
샘플 선 적분, 차등 나선 위상, value noise, FBM과 선형광 합성의 수학적 구조
1. 개요 (Overview)
이 프로젝트는 서로 다른 생성 원리를 가진 세 개의 실시간 셰이더를 제공한다.
모드 | 핵심 모델 | 시각적 역할 |
|---|---|---|
Hybrid Universe | 8회 Kali 구면반전 + FBM 나선 가스 + 먼지 감쇠 | 정동우의 독자 설계로 두 밀도장을 하나의 선형광 장면에 결합한 기본 화면 |
Galaxy of Universes | pseudo-3D sample-line 적분 + 재귀 구면반전 + 반지름 의존 차등 위상 | 미세 별빛 궤도와 중심 프랙탈 코어 |
Spiral Nebula | 2D value noise + 5-octave FBM + 극좌표 나선 warp | 유기적인 발광 가스와 맥동 코어 |
- 모드
Hybrid Universe
- 핵심 모델
8회 Kali 구면반전 + FBM 나선 가스 + 먼지 감쇠
- 시각적 역할
정동우의 독자 설계로 두 밀도장을 하나의 선형광 장면에 결합한 기본 화면
- 모드
Galaxy of Universes
- 핵심 모델
pseudo-3D sample-line 적분 + 재귀 구면반전 + 반지름 의존 차등 위상
- 시각적 역할
미세 별빛 궤도와 중심 프랙탈 코어
- 모드
Spiral Nebula
- 핵심 모델
2D value noise + 5-octave FBM + 극좌표 나선 warp
- 시각적 역할
유기적인 발광 가스와 맥동 코어
세 모드는 같은 Speed, Intensity, Field Zoom, Manual Rotation과 drag 좌표계를 공유하지만, 같은 물리 현상을 세 가지 방식으로 근사한 것이 아니다. Galaxy는 반복함수의 궤도 에너지를, Nebula는 확률장의 공간 상관을, Hybrid는 두 결과의 결합을 연구한다.
1.1 저작 관계와 모델 차이
Hybrid Univers는 제작자가 직접 설계하고 구현한 커스텀 셰이더다.
Dave Hoskins의 Galaxy of Universes와 Kali 계열 구면반전은 프랙탈 branch의 알고리즘 계보이고, value noise와 FBM은 성운 branch의 수학적 재료.
두 원본 화면을 응용해서 두 장을 같은 좌표·시간·노출 체계 안에서 결합하는 방법 자체가 Hybrid의 독자 구현이다.
비교 항목 | Galaxy of Universes | Spiral Nebula | Hybrid Universe |
|---|---|---|---|
기본 장 | 재귀 구면반전의 궤도 에너지 | 나선 warp된 확률 밀도장 | 궤도 에너지와 가스 밀도의 결합장 |
공간 계산 | pseudo-3D sample-line 적분 | 2D FBM field | sample-line branch와 FBM branch가 같은 공유 |
결합 방식 | 단일 프랙탈 출력 | 단일 가스 출력 | 프랙탈 광도에 반응하는 비선형 선형광 결합 |
가림/감쇠 | radial window | 지수 반경 감쇠 | FBM 기반 먼지 mask가 합성광을 선택적으로 감쇠 |
출력 변환 | power contrast + clamp | exponential exposure | 두 branch 합성 후 exponential exposure 한 번 |
색의 소유자 | 궤도 누적기 | 가스 좌표 | 두 팔레트의 상호 변조와 dust attenuation |
- 비교 항목
기본 장
- Galaxy of Universes
재귀 구면반전의 궤도 에너지
- Spiral Nebula
나선 warp된 확률 밀도장
- Hybrid Universe
궤도 에너지와 가스 밀도의 결합장
- 비교 항목
공간 계산
- Galaxy of Universes
pseudo-3D sample-line 적분
- Spiral Nebula
2D FBM field
- Hybrid Universe
sample-line branch와 FBM branch가 같은 공유
- 비교 항목
결합 방식
- Galaxy of Universes
단일 프랙탈 출력
- Spiral Nebula
단일 가스 출력
- Hybrid Universe
프랙탈 광도에 반응하는 비선형 선형광 결합
- 비교 항목
가림/감쇠
- Galaxy of Universes
radial window
- Spiral Nebula
지수 반경 감쇠
- Hybrid Universe
FBM 기반 먼지 mask가 합성광을 선택적으로 감쇠
- 비교 항목
출력 변환
- Galaxy of Universes
power contrast + clamp
- Spiral Nebula
exponential exposure
- Hybrid Universe
두 branch 합성 후 exponential exposure 한 번
- 비교 항목
색의 소유자
- Galaxy of Universes
궤도 누적기
- Spiral Nebula
가스 좌표
- Hybrid Universe
두 팔레트의 상호 변조와 dust attenuation
Hybrid의 핵심 차이는 다음 결합식
단순 가산 과 달리, 프랙탈 filament가 이미 밝은 곳에서는 성운 방출도 함께 강화되는데,
반대로 FBM에서 얻은 dust field는 일부 영역을 감쇠한다.
따라서 Hybrid의 형태는 Galaxy와 Nebula 결과를 따로 렌더한 뒤 투명도로 겹쳐서는 재현되지 않는다. 두 branch가 노출 이전의 선형광에서 서로 영향을 주는 결합 규칙을 재현하는 것이 중요했다.
2. 공통 화면 좌표
2.1 종횡비 보정
픽셀 좌표 와 해상도 에 대해
로 정규화한다. 두 축을 각각 로 나누는 방식은 화면 비율에 따라 원형 구조를 타원으로 늘리므로 사용하지 않는다. Nebula는 같은 목적의 정규화를 사용한다.
2.2 줌, 회전, drag
는 Field Zoom, 은 Manual Rotation, 은 보간된 drag 위치다. Hybrid는 drag 이동량을 로 조금 더 크게 사용한다.
3. Galaxy of Universes
“Galaxy of Universes” — ShaderToy, Dave Hoskins 작품을 분석.
galaxy.frag의 구조는 엄밀한 중력 N-body 또는 일반상대론 시뮬레이션이 아니다. 화면의 각 픽셀에서 하나의 pseudo-3D 샘플 선을 전진시키고, 매 위치에 재귀 구면반전을 적용해 얻은 궤도 에너지를 누적하는 절차적 프랙탈이다.
3.1 반지름 의존 차등 나선 위상
중심 거리 에 따라 회전 위상을 다르게 준다.
중심에 가까울수록 항이 커지므로 내부 궤도가 더 많이 감기고 바깥은 완만하게 회전한다. 이 식은 시각적 differential swirl이며 Kerr metric이나 실제 frame dragging의 해가 아니다.
3.2 샘플 선과 시작점 jitter
를 누적 거리라 하면 샘플 위치는
로 만든다. 최대 120 step 중 UI의 Fractal Iterations만큼 실행하며 기본값은 90이다. Galaxy의 step 길이는 , Hybrid는 이다.
고정된 시작점에서 일정 간격으로 적분하면 등고선 형태의 march band가 생긴다. 이를 미세 노이즈로 분산하기 위해 첫 위치를 픽셀 hash로 흔든다.
3.3 8회 재귀 구면반전
각 샘플은 다음 변환을 정확히 8회 수행한다.
이 변환은 세 연산을 결합한다.
: 모든 옥탄트를 양의 영역으로 fold한다.
: 단위구 기준의 spherical inversion을 수행한다.
: 궤도를 다시 반전 중심에서 이동시킨다.
반복 중 가 작은 영역은 크게 확대되고 큰 영역은 압축된다. 그 결과 초기 조건의 작은 차이가 서로 다른 궤도 길이와 미세 필라멘트로 증폭된다.
3.4 세 에너지 누적기
한 샘플의 궤도 에너지를 세 채널에 서로 다른 방식으로 누적한다.
Wave Modulation이 켜지면 첫 파동은
이고 두 번째 파동은 더 높은 공간 주파수와 시간 속도를 사용한다.
이는 펄사 광도곡선이 아니라 중심에서 바깥으로 이동하는 절차적 밀도 파동이다.
3.5 유한 지지 반경
프랙탈 에너지가 화면 전체를 균일하게 채우지 않도록 서로 다른 radial window를 곱한다.
세 반경의 차이가 중심 코어, 내부 발광, 바깥 filament를 분리한다.
3.6 색과 출력 변환
Galaxy는 를 비대칭 RGB 조합으로 배치한다. 마지막 출력은
이며 가 UI의 Intensity다. 물리적 radiance 보존형 톤매핑이 아니라 프랙탈 에너지의 대비를 조절하는 예술적 출력 변환이다.
3.7 galaxy.frag 수식–코드 대응
아래 식은 설명용 일반식이 아니라 현재 GLSL의 상수와 연산 순서를 그대로 옮긴 정준식이다.
GLSL 기호 | 수학 기호 | 정의 |
|---|---|---|
| 종횡비 보정·zoom·rotation·drag가 적용된 화면 좌표 | |
| 반지름 의존 차등 회전 위상 | |
| pseudo-3D sample-line 거리 | |
| 번째 sample의 번째 구면반전 상태 | |
| 궤도 에너지 누적기 |
- GLSL 기호
uv- 수학 기호
- 정의
종횡비 보정·zoom·rotation·drag가 적용된 화면 좌표
- GLSL 기호
t- 수학 기호
- 정의
반지름 의존 차등 회전 위상
- GLSL 기호
s- 수학 기호
- 정의
pseudo-3D sample-line 거리
- GLSL 기호
p- 수학 기호
- 정의
번째 sample의 번째 구면반전 상태
- GLSL 기호
v1,v2,v3- 수학 기호
- 정의
궤도 에너지 누적기
구현 — shaders/galaxy.frag, main()
float t = iTime * 0.1 * uSpeed
+ ((0.25 + 0.05 * sin(iTime * 0.1 * uSpeed))
/ (length(uv) + 0.07)) * 2.2;p = s * vec3(uv, 0.0);
p.xy *= ma;
p += vec3(0.22, 0.3, s - 1.5 - sin(iTime * 0.13 * uSpeed) * 0.1);for (int j = 0; j < 8; j++) {
p = abs(p) / dot(p, p) - 0.659;
}최종 RGB 조합도 코드와 동일하다.
vec3 col = vec3(
v3 * (1.5 + sin(iTime * 0.2 * uSpeed) * 0.4),
(v1 + v3) * 0.3,
v2
) + smoothstep(0.2, 0.0, len) * 0.85
+ smoothstep(0.0, 0.6, v3) * 0.3;col = min(pow(abs(col), vec3(uIntensity)), vec3(1.0));여기서 는 uSpeed, 는 uIntensity다.
실제 구현과 GLSL을 1:1 대응 시켜두었다.
4. Spiral Nebula
nebula.frag는 재귀 프랙탈이 아니라 공간적으로 연속인 확률장을 여러 크기로 합성한다.
4.1 2D value noise
좌표 를 정수 cell 과 cell 내부 좌표 로 나눈다. 네 꼭짓점의 hash 값을
로 만들고 cubic Hermite 곡선
을 사용해 bilinear interpolation한다. 선형 보간만 사용할 때 생기는 cell 경계의 기울기 불연속을 줄이는 목적이다.
4.2 5-octave FBM
각 octave는 주파수를 두 배, 진폭을 절반으로 만든다. 저주파 octave는 큰 가스 덩어리를, 고주파 octave는 가장자리의 작은 요동을 담당한다.
4.3 극좌표 나선 warp
직교 좌표의 noise를 이 나선 좌표에서 샘플링함으로써 원형 cloud가 감긴 팔 구조를 갖는다.
4.4 세 공간 주파수의 가스장
서로 반대 방향으로 이동하는 가 팔의 전단을 만들고, 화면 좌표에서 직접 샘플한 가 나선에 종속되지 않는 미세 난류를 더한다.
최종 밀도는
이다. smoothstep은 희박한 noise floor를 제거하고, 지수 감쇠는 가스가 화면 끝까지 같은 밀도로 이어지는 것을 막는다.
4.5 색 공간
보라색 , 자주색, 청색 을 두 단계로 보간한다.
내부와 외부의 색 변화는 별도의 후처리 gradient가 아니라 가스 밀도 계산과 같은 좌표에서 결정된다.
4.6 중심 코어와 노출
코어를 더한 뒤 전체 색에 지수 노출을 적용한다.
는 Intensity / Glow다. 이 변환은 음수가 없고 큰 발광값을 점근적으로 1에 압축하므로 단순 clamp보다 중심부의 색을 오래 유지한다.
4.7 nebula.frag 수식–코드 대응
GLSL 기호 | 수학 기호 | 정의 |
|---|---|---|
| ||
| ||
| 극좌표 나선 warp 위치 | |
| 서로 다른 좌표와 속도의 FBM field | |
| threshold와 반경 감쇠가 적용된 가스 밀도 |
- GLSL 기호
r- 수학 기호
- 정의
- GLSL 기호
a- 수학 기호
- 정의
- GLSL 기호
spiralCoord- 수학 기호
- 정의
극좌표 나선 warp 위치
- GLSL 기호
n1,n2,n3- 수학 기호
- 정의
서로 다른 좌표와 속도의 FBM field
- GLSL 기호
nebula- 수학 기호
- 정의
threshold와 반경 감쇠가 적용된 가스 밀도
구현 — shaders/nebula.frag, main()
float spiral = a + r * 4.0 - time * 0.5;
vec2 spiralCoord = vec2(cos(spiral), sin(spiral)) * r;float n1 = fbm(spiralCoord * 3.0 + time * 0.1);
float n2 = fbm(spiralCoord * 5.0 - time * 0.15);
float n3 = fbm(uv * 8.0 + vec2(time * 0.05, 0.0));float nebula = n1 * 0.5 + n2 * 0.3 + n3 * 0.2;
nebula = smoothstep(0.2, 0.8, nebula) * exp(-r * 0.8);최종 색은 코드 순서대로
vec3 finalColor = mix(color1, color2, n1);
finalColor = mix(finalColor, color3, smoothstep(0.3, 0.7, r))
* nebula * 2.0;
float core = exp(-r * 3.0) * (1.0 + 0.3 * sin(time * 3.0));
finalColor += vec3(1.0, 0.95, 0.9) * core * 2.0;
finalColor *= 1.0 - r * 0.3;
finalColor = 1.0 - exp(-finalColor * uIntensity);
finalColor = pow(finalColor, vec3(0.85));로 대응한다.
5. Hybrid Universe
hybrid.frag는 내가 설계한 독자적인 결합 모델이다. Galaxy와 Nebula를 화면 완성본끼리 alpha blend하지 않고, 같은 와 에서 두 밀도장을 계산한 뒤 노출 이전의 선형광에서 상호 변조한다.
5.1 Galaxy branch
최대 120 sample, 기본 90 sample
sample당 8회 spherical inversion
의 비대칭 RGB 조합
중심 core와 바깥 filament radial window
5.2 Nebula branch
Hybrid는 더 조밀한 세 FBM field를 사용한다.
5.3 선형광 결합
이미 밝은 프랙탈 filament 주변에서 성운 방출이 더 강하게 반응한다. 두 branch를 각각 tone map한 뒤 더하지 않으므로 중심 광도와 색 혼합 순서가 보존된다.
5.4 먼지 감쇠
고주파 가스가 일정 임계값을 넘은 내부 영역을 부분적으로 어둡게 해 모든 구조가 가산 발광만 하는 플라스틱 표면처럼 보이는 것을 막는다.
5.5 최종 노출
Hybrid에서 Intensity는 선형광 합성 이후 단 한 번만 적용된다.
5.6 hybrid.frag 정준 수식–코드 대응
Hybrid의 독자성은 두 branch의 존재 자체보다 어떤 순서와 함수로 결합하는가에 있다. 아래는 현재 구현의 전체 합성 순서다.
Galaxy branch
구현 — shaders/hybrid.frag, main()
vec3 galaxyCol = vec3(
v3 * (1.6 + sin(time * 0.2) * 0.4) + v1 * 0.2,
(v1 + v3) * 0.38 + v2 * 0.15,
v2 * 1.1 + v1 * 0.25
);
galaxyCol += smoothstep(0.2, 0.0, len) * 0.95;
galaxyCol += smoothstep(0.0, 0.6, v3) * 0.35;Nebula branch
float nebulaGas = n1 * 0.5 + n2 * 0.35 + n3 * 0.15;
nebulaGas = smoothstep(0.2, 0.78, nebulaGas) * exp(-len * 0.9);
vec3 nebulaCol = mix(nebColor1, nebColor2, n1);
nebulaCol = mix(nebulaCol, nebColor3, smoothstep(0.3, 0.8, len))
* nebulaGas * 1.6;상호 변조
vec3 col = galaxyCol + nebulaCol * (0.6 + galaxyCol * 0.8);곱셈과 덧셈은 RGB component별 연산이다. 즉 밝은 청색 프랙탈 영역은 성운의 청색 성분을, 밝은 적색 영역은 성운의 적색 성분을 서로 다르게 증폭한다.
코어와 먼지
float core = exp(-len * 3.5) * (1.0 + 0.25 * sin(time * 3.0));
col += vec3(1.0, 0.96, 0.92) * core * 1.8;float dust = smoothstep(0.4, 0.7, n2)
* (1.0 - smoothstep(0.05, 0.6, len));
col *= 1.0 - dust * 0.25;단일 출력 변환
col = 1.0 - exp(-col * uIntensity * 1.15);
col = pow(col, vec3(0.85));이 boxed 식이 모든 결합·코어·먼지 계산 이후 정확히 한 번만 실행된다.
6. 구현하면서 AI에 도움 받은 수정된 수학적 오류
6.1 종횡비 왜곡
기존 좌표는 와이드 화면에서 방사 대칭 구조를 가로로 늘렸다. 현재는 또는로 두 축을 함께 나눠 원형 거리 의 의미를 보존한다.
6.2 색 보간 no-op
과거 Hybrid에는 다음 형태가 있었다.
mix(nebColor3, nebColor3, weight)양쪽 인자가 같아 보간이 아무 효과가 없었고, 앞줄에서 계산한 두 색의 혼합까지 덮어썼다. 현재는
mix(mix(nebColor1, nebColor2, n1), nebColor3, radialWeight)처럼 세 색이 실제 출력에 도달한다.
6.3 고정 step 밴딩
모든 픽셀이 에서 시작하던 sample-line 적분은 일정한 원형 band를 만들었다. 현재는 픽셀별 hash jitter를 첫 step에 적용한다.
6.4 누락 hash 소유자
galaxy.frag가 시작점 jitter를 호출하면서 hash()를 정의하지 않던 컴파일 오류를 제거했다. 각 fragment shader는 자신이 사용하는 hash/noise 함수를 직접 소유한다.
7. 파라미터와 수학적 영향
UI | uniform | 영향 |
|---|---|---|
Speed |
| 위상 시간 , 나선 이동, density wave 속도 |
Intensity / Glow |
| Galaxy power contrast 또는 Nebula/Hybrid 지수 노출 |
Field Zoom |
| 정규화 좌표 의 배율 |
Fractal Iterations |
| Galaxy/Hybrid sample-line step 수, 최대 120 |
Manual Rotation |
| 입력 좌표의 2D 회전행렬 |
Auto Rotation | JavaScript state |
|
Wave Modulation |
| Galaxy/Hybrid의 방사형 밀도 파동 적용 여부 |
- UI
Speed
- uniform
uSpeed- 영향
위상 시간 , 나선 이동, density wave 속도
- UI
Intensity / Glow
- uniform
uIntensity- 영향
Galaxy power contrast 또는 Nebula/Hybrid 지수 노출
- UI
Field Zoom
- uniform
uZoom- 영향
정규화 좌표 의 배율
- UI
Fractal Iterations
- uniform
uIterations- 영향
Galaxy/Hybrid sample-line step 수, 최대 120
- UI
Manual Rotation
- uniform
uRotation- 영향
입력 좌표의 2D 회전행렬
- UI
Auto Rotation
- uniform
JavaScript state
- 영향
uRotation을 프레임마다 천천히 증가
- UI
Wave Modulation
- uniform
uPulseEffect- 영향
Galaxy/Hybrid의 방사형 밀도 파동 적용 여부
Fractal Iterations는 구면반전 내부 반복 8회를 바꾸지 않는다. 광선을 따라 평가하는 바깥 sample 수만 바꾼다. 프랙탈 정의 자체와 적분 품질의 경계가 사라진다.
8. 런타임과 구현 구조
galaxy-of-universes/
├── index.html # 세 모드와 파라미터 UI
├── style.css # fullscreen canvas와 off-canvas studio
├── README.md # 수학·렌더링 문서
├── js/
│ ├── shaders.js # 명시적 GLSL URL과 preset registry
│ ├── renderer.js # WebGL compile/link, uniforms, animation loop
│ ├── controls.js # drag/zoom/mode 전환과 접근성 상태
│ └── main.js # 초기화와 오류 경계
└── shaders/
├── vertex.vert # fullscreen triangle pair
├── hybrid.frag # Galaxy + Nebula 선형광 결합
├── galaxy.frag # 재귀 구면반전 sample-line field
└── nebula.frag # spiral-warped FBM fieldGLSL 의존 파일은 정적 프로젝트 수집기와 브라우저가 모두 해석할 수 있도록 명시한다.
const SHADER_URLS = {
vertex: new URL('../shaders/vertex.vert', import.meta.url),
hybrid: new URL('../shaders/hybrid.frag', import.meta.url),
galaxy: new URL('../shaders/galaxy.frag', import.meta.url),
nebula: new URL('../shaders/nebula.frag', import.meta.url)
};모든 GLSL은 병렬 fetch한 뒤 시작 시 엄격하게 컴파일한다. 파일 누락, shader compile 실패, program link 실패를 다른 모드로 조용히 대체하지 않는다.
9. 검증 기준
다음을 검증 기준 삼아 작업하였다.
화면 비율을 바꿔도 중심 코어와 radial window가 원형을 유지한다.
Fractal Iterations를 낮추면 sample 밀도만 줄고 구면반전의 8회 구조는 유지된다.Wave Modulation을 끄면 방사형 파동만 멈추고 프랙탈 궤도와 FBM 가스는 남는다.Galaxy의 시작점 band가 고정 원형 띠가 아니라 미세한 dithering으로 보인다.
Nebula의 세 noise field가 서로 다른 속도와 좌표에서 이동한다.
Hybrid의 청색·보라색·자홍색 세 팔레트가 모두 화면에 도달한다.
모드 전환 시 각 GLSL source viewer가 실제 활성 fragment source를 표시한다.
누락 파일이나 GLSL 오류는 초기화 오류로 명확히 드러난다.
10. 조작
입력 | 동작 |
|---|---|
마우스 드래그 | 좌표장 이동 |
마우스 휠 | zoom (–) |
| 자동 회전 정지/재개 |
| 타이틀과 FPS HUD 표시/숨김 |
| 컨트롤·GLSL 패널 열기/닫기 |
| 열린 패널 닫기 |
- 입력
마우스 드래그
- 동작
좌표장 이동
- 입력
마우스 휠
- 동작
zoom (–)
- 입력
Space- 동작
자동 회전 정지/재개
- 입력
H- 동작
타이틀과 FPS HUD 표시/숨김
- 입력
Tab- 동작
컨트롤·GLSL 패널 열기/닫기
- 입력
Esc- 동작
열린 패널 닫기
11. 해석상의 한계
구면반전 장은 실제 은하의 질량 분포나 별 궤도를 적분한 결과가 아니다.
차등 위상은 나선 구조를 만드는 절차적 warp이며 일반상대론의 frame-dragging 해가 아니다.
Spiral Nebula는 2D 확률장을 극좌표로 감은 모델이며 복사유체역학 시뮬레이션이 아니다.
RGB 팔레트는 분광 관측값에서 직접 유도하지 않았다.
Intensity는 노출/대비 제어이며 에너지 단위가 아니다.hash와 value noise는 결정론적 의사난수이며 물리적 난류의 통계 전체를 재현하지 않는다.
12. 출처와 알고리즘 계보
AI 함께 구현
Hybrid Universe : 프랙탈·성운 branch의 공통 좌표 설계,광도 반응형 선형광 결합, FBM dust 감쇠, 단일 노출 파이프라인과 최종 색 설계
알고리즘 계보와 참고 자료
“Galaxy of Universes” — ShaderToy, Dave Hoskins —
Galaxy of Universes 프랙탈 branch의 기반
Kali — ShaderToy — spherical-inversion 반복함수의 계보
Inigo Quilez — value noise, FBM, SDF와 raymarching 수학 참고