TECHARTNOMAD | MAZELINE.TECH

TECH.ART.FLOW.IO

[공유] DreamShader 프레임워크 for UnrealEngine

jplee 2026. 7. 6. 23:19

중국 개발자가 만든 셰이더 언어 프레임워크

 

GitHub - TypeDreamMoon/DreamShader: Unreal Engine Material DSL. Use Dream Shader Lang Write Unreal Material. Simple · Fast · F

Unreal Engine Material DSL. Use Dream Shader Lang Write Unreal Material. Simple · Fast · Full syntax · HLSL GLSL Lang Support - TypeDreamMoon/DreamShader

github.com

 

GLM-5.2 요약본↓

텍스트로 언리얼 머티리얼을 그리다 — DreamShader 설계 철학과 워크플로

언리얼 엔진에서 머티리얼이라면 떠오르는 화면은 거대한 노드 그래프입니다. 직관적이긴 하지만, 노드가 수백 개를 넘어가면 "이 그래프가 무엇을 하는지" 한눈에 읽기 어렵고, 코드 리뷰·버전 관리·재사용은 더더욱 요원해집니다. DreamShader는 이 지점에서 출발합니다. .dsm, .dsf, .dsh라는 텍스트 소스로 UMaterial·UMaterialFunction·Material Layer 자산을 생성하는, "텍스트 퍼스트(text-first)" 머티리얼 제작 프레임워크입니다.

설계 철학

1. 소스가 진실의 원천(Source of truth)이다.
DreamShader의 가장 강력한 전제는 "생성된 에셋은 언제나 소스에서 다시 지을 수 있다"는 것입니다. .dsm/.dsf/.dsh 파일을 버전 관리하고, 에셋은 그 결과물로 취급합니다. 따라서 머지 충돌도 텍스트 단위로 해결되고, 코드 리뷰도 노드 스크린샷이 아닌 diff로 가능해집니다.

2. 언어를 목적별로 세 층으로 나눈다.
DreamShaderLang은 범용 프로그래밍 언어가 아니라, 각자의 역할이 명확한 세 계층을 갖습니다.

  • Graph — 노드 지향 DSL. 변수·할당·UE.* 노드·함수 호출·기본 if/else로 머티리얼 노드를 생성합니다.
  • Function — HLSL 스타일 재사용 헬퍼. 루프·복잡한 계산·로직은 Custom 노드 안으로 들어갑니다.
  • Namespace — 헬퍼를 Texture::Sample2DRGB(...)처럼 그룹화하는 조직 도구.

"그래프로 표현하기 어려운 흐름 제어는 Function으로 내려보내라"는 명시적 가이드가 언어 경계 자체에 새겨져 있는 셈입니다(for/whileGraph에서 금지하는 제약도 같은 맥락입니다).

3. 선언적으로, 리플렉션으로.
머티리얼 구조는 Properties·Settings·Inputs·Outputs·Graph 같은 section으로 나뉘고, 각 선언 뒤에 붙는 [ Group="..."; SortPriority=10; ] 블록은 곧바로 언리얼 MaterialExpression의 UPROPERTY로 내려쓰입니다. 에디터의 수많은 체크박스를 외우지 않아도 텍스트 한 줄로 제어할 수 있습니다.

4. 재사용을 일급 시민으로.

  • .dsh — 공유 헬퍼 헤더
  • .dsf — 재사용 가능한 ShaderFunction/ShaderLayer 자산
  • Packageimport "@scope/package/Library/Noise.dsh" 형태의 설치형 공유 라이브러리
  • VirtualFunction — 이미 존재하는 UMaterialFunction의 시그니처만 선언해 Graph에서 값 호출 (에셋을 생성·덮어쓰지 않음)

이 네 가지 축으로 "코드 복붙" 없이 자산을 조립할 수 있습니다.

5. 에디터 경험과 증분 빌드.
저장 시 자동 컴파일, source hash 캐싱, import graph 기반의 증분 재생성(.dsh/.dsf 변경 시 의존하는 .dsm/.dsf만 다시 빌드)을 기본으로 제공합니다. VSCode 확장과 Rider 플러그인은 하이라이팅·완성·Go to Definition·진단을 지원하고, 에러는 source map으로 실제 소스 줄/열로 매핑됩니다. 기존 에셋을 .dsm/.dsf로 끌어내는 디컴파일러도 마이그레이션 헬퍼로 제공됩니다.

워크플로

전형적인 작업 흐름은 다음처럼 정리됩니다.

MyProject/
├─ DShader/
│  ├─ Shared/Common.dsh      # 공유 Function / Namespace
│  ├─ Functions/F_Tint.dsf    # 재사용 ShaderFunction
│  ├─ Materials/M_UI.dsm      # Shader (머티리얼 본체)
│  └─ Packages/@scope/...     # 외부 공유 라이브러리
└─ Plugins/DreamShader/
  1. DShader/ 아래에 소스를 배치합니다. 머티리얼 본체는 .dsm, 재사용 자산은 .dsf, 공통 로직은 .dsh에.
  2. .dsh에 헬퍼를 작성합니다. Namespace(Name="Color") { Function ApplyTint(...) {...} } 형태로 HLSL 스타일 함수를 정의.
  3. import로 의존성을 연결합니다. .dsm에서 import "Shared/Common.dsh";로 헤더를, import "Functions/F_Tint.dsf";로 함수 자산을, import "@scope/pkg/....dsh";로 패키지를 끌어옵니다.
  4. Shader 블록에서 머티리얼을 조립합니다. Properties로 파라미터를, Settings로 셰이딩 모델·블렌드 모드를, Outputs로 출력 바인딩을, Graph로 노드 로직을 선언적으로 기술.
  5. 파일을 저장하면 끝입니다. 에디터가 소스를 파싱해 대상 에셋을 생성·갱신합니다. 의존성이 걸린 파일만 선별적으로 재빌드됩니다.
  6. 기존 프로젝트 마이그레이션이 필요하면 Content Browser에서 DreamShader > Export DSM/DSF로 디컴파일한 뒤, 프로젝트 네이밍 컨벤션에 맞춰 다듬으면 됩니다.

왜 의미가 있는가

DreamShader는 단순한 노드-투-텍스트 변환 도구가 아닙니다. 머티리얼 제작을 소프트웨어 엔지니어링의 관행으로 끌어들이는 프레임워크입니다 — 버전 관리, 코드 리뷰, 모듈화, 패키지 의존성, 에디터 통합, 증분 빌드라는 코드 작업의 당연한 이점들을 머티리얼에도 가져옵니다. 동시에 언리얼의 네이티브 자산(UMaterial, Material Layer, Substrate, Material Parameter Collection)과는 느슨하게 연결되어, VirtualFunction으로 기존 자산을 그대로 끌어다 쓰거나 디컴파일러로 점진적 도입도 가능합니다.

노드 그래프가 주는 시각적 즐거움을 포기하기 아쉽다면, 디컴파일러부터 시작해 보세요. 어느 순간 "이 로직, 텍스트로 쓰는 게 더 빠르겠네?" 싶은 순간이 찾아올 텐데, 그게 바로 DreamShader가 진가를 발휘하는 지점입니다.