TL;DR
- Godot 4.7 셰이더로 만드는 절차적 패턴 튜토리얼의 여덟 번째 편에서 Value Noise의 미분을 계산해 표면 노멀을 조정하고 정점 변위를 구현함.
- 패턴 샘플의 값과 함께 x·y·z 방향 미분을 보간하며, 덧셈·뺄셈·곱셈에 미분 규칙을 적용함.
- 선형 보간과
smoothstep보간을 비교한 뒤, 격자 경계의 주름을 줄이는 smootherstep을 추가함. - Step·Linear·Smooth·Smoother 네 가지 부드러움 옵션을 셰이더에서 선택할 수 있게 구성함.
- 옥타브 주파수에 맞춰 미분을 스케일링하고 노멀 및 선택적 정점 변위에 적용해, 애니메이션되는 부드러운 Value Noise 표면을 만듦.
노멀 벡터 조정
- 이 튜토리얼은 Godot Engine 4.7을 사용해 GPU 셰이더로 절차적 패턴을 만드는 시리즈의 여덟 번째 편이며, Value Noise에 미분 함수를 추가함.
- 해시 노이즈의 각 블록은 값이 일정해 미분이 항상 0이지만, Value Noise는 연속적이고 매끄러운 패턴을 만들므로 사인파처럼 미분을 계산해 울퉁불퉁한 표면을 표현할 수 있음.
sine_waves.gdshader의 일부 코드를value_noise.gdshader로 옮겨, 우선 정점 변위 없이 프래그먼트 노멀 벡터만 계산함.- 범프 강도와 변위 균일 변수를 추가하고 패턴의 x·y 미분에 적용해
fragment()에서 뷰 공간 노멀 벡터를 만듦. - 평면 크기에 맞게 노멀 벡터가 정렬되도록 범프 강도를 0.5로 설정함.
패턴 샘플 보간
- 최종 패턴 샘플에 미분값을 설정하지 않은 상태에서는 미분이 0이므로 노멀도 변하지 않음. 해시값을 보간해 Value Noise를 계산하는 과정에 미분을 포함해야 함.
- 블록의 네 격자점 샘플을
mix()로 보간하는 동시에 샘플 값과 미분도 함께 보간하도록,pattern_sample.gdshader에PatternSample을 인자로 받는blend()함수를 추가함. 처음에는 샘플 값만 보간하고 미분은 0으로 둠. value_sample()함수는 주어진 해셔와 시간으로animated_hash_to_float()를 호출하고, 결과를 패턴 샘플에 저장함.sample_value_noise()에서 네 격자점 값을 패턴 샘플로 만들고 보간자도 패턴 샘플로 구성한 뒤, 기존mix()대신blend()를 사용함.- 사인파와 마찬가지로 옥타브 주파수에 맞춰 마지막에 x·y 미분을 스케일링함.
선형 보간
- 우선 보간자의 스무딩을 제거해 노이즈를 선형 보간으로 되돌리고, 보간자의 미분을 해당 축에서 1로 설정함.
mix(a, b, t)를a + (b - a)t로 표현해 미분을 직접 계산함. 기존add()에 더해 패턴 샘플의 값과 미분을 각각 빼는subtract()를 추가함.- 두 패턴 샘플의 곱에는 곱의 미분 법칙을 적용함. 즉, 각 축의 미분은 다른 샘플의 값과 해당 축 미분을 곱한 항 두 개의 합임.
blend()를add(a, multiply(subtract(b, a), t))로 구현해 샘플 값뿐 아니라 미분도 계산함.- 미분을 명확히 확인하기 위해 패턴 미분을 일시적으로 빨강·초록 색상 채널에 직접 사용하며, 이때 양수 미분만 표시함.
부드러운 보간
- 매끄러운 패턴을 위해 미분을 고려하는
smooth01()을pattern_sample.gdshaderinc에 추가하고, 처음에는 값만 스무딩하며 미분을 0으로 둠. sample_value_noise()에서 x·y 보간자를smooth01()로 처리함.smoothstep(t)의 도함수는6t - 6t²이며, 곱셈을 줄인 형태는(6 - 6t)t임.- 입력 샘플의 미분까지 반영하기 위해 연쇄 법칙을 적용함. 최종 미분은
smoothstep의 도함수에 각 입력 방향의 원래 미분을 곱한 값임. - 보간자 미분은 해당 축에서 1이고 다른 축에서는 0이므로 연쇄 법칙으로 올바른 방향의 미분만 반영함. 옥타브 주파수로 미분을 스케일링할 때도 같은 법칙을 적용함.
더 부드러운 보간
smoothstep보간은 올바른 노멀을 만들지만 격자 경계를 따라 날카로운 주름이 남음. 대칭적인 샘플에서는 문제가 덜 드러나지만, 격자값이 0–1–0.5처럼 비대칭이면 경계에 주름이 생기고, 0–0.5–1에서는 계단형 패턴과 더 뚜렷한 주름이 나타남.- 원인은
smoothstep의 두 번째 도함수가 격자 경계에서 0이 아니기 때문임. 첫 번째와 두 번째 도함수가 모두 경계에서 0이 되도록smootherstep을 사용함. smootherstep(t)는t³(t(6t - 15) + 10)이며, 첫 번째 도함수는t²(t(30t - 60) + 30), 두 번째 도함수는t(t(120t - 180) + 60)임.- 대칭·비대칭·계단형 샘플을 비교했을 때 smootherstep은 두 번째 도함수의 연속성을 유지해 주름을 제거함. 다만 계단형 패턴 자체는 매끄러운 보간의 본질적 특성이므로 없어지지 않음.
pattern_sample.gdshaderinc에smoother01()을 추가하고,sample_value_noise()의 보간자에 적용함.
설정 가능한 부드러움
- 노멀 벡터 조정에는 smoother 보간이 필요하지만, 색상에만 패턴을 사용할 때는 smooth 보간으로 충분하며 예술적 선택에 따라 선형 보간도 사용할 수 있음.
- 부드러움 유형을 받는
smooth01()변형을 추가함. 1은 Linear, 2는 Smooth, 3은 Smoother이며 1은 원래 샘플을 그대로 반환함. - 네 번째 선택지로 중간 지점에서 0에서 1로 전환하는 이진 Step 옵션을 추가함. 기본값이며 0이나 정의되지 않은 값에도 적용됨.
value_noise.gdshader에 Step·Linear·Smooth·Smoother 레이블이 표시되는 열거형 정수 변수를 추가하고 기본값을 Smoother로 설정함.sample_value_noise()에서 설정 가능한smooth01()을 사용함. Step 옵션은 보간을 사실상 제거해 Value Noise를 Hash Noise로 바꿈.
정점 변위
- 사인파 튜토리얼과 마찬가지로 정점 변위를 추가하고, 기본 활성화된 토글 변수를 둠.
vertex()에서 토글이 켜져 있으면 표준 프랙털 패턴 설정으로 패턴을 샘플링하고, 패턴 값과 변위값의 곱을 노멀 방향으로VERTEX에 더함.- 더 부드러운 표면을 위해 평면의 세분화 수준을 63으로 설정함.
- Step·Linear·Smooth·Smoother 유형별 정점 변위를 비교하며, 마지막 예시에서는 세 옥타브의 Smoother Value Noise에 애니메이션 변위를 적용함.
- 이후에도 노이즈 패턴을 계속 개선할 예정임.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요