[GPU프로그래밍] 13. Using Noise in Shaders

jungizz_·2024년 6월 13일
0

GPU Programming

목록 보기
13/15
post-thumbnail

Perlin Noise

  • 규칙성을 가지지 않는 랜덤한 값이지만, continous function이라서 흐름/구조는 유지
  • 같은 input에 같은 ouput 노이즈 생성 가능 -> repeatable
  • 차원 상관 없이 생성 가능 (1D, 2D, 3D, ...)

    shader에서 사용하기 위해서는 미리 계산된 노이즈 데이터를 texture로 저장

Noise texture (GLM)

  • GLM에서 2D, 3D, 4D perlin noise 지원 glm::perlin function
  • perlin noise 값을 그대로 사용하기 보단, octave마다 다른 노이즈 값을 sum해서 사용해서 새로운 노이즈 만드는 경우가 많다
  • octaves: 하나로 합치기 위해 사용되는 각각의 연속적인 노이즈 함수
    • 각 노이즈 함수가 이전의 것보다 2배의 주파수
    • Octave i의 주기(frequency) = 2^i
  • 여러 Octave의 값을 더하여 더 자글자글?한 노이즈를 얻는다
    • frequency는 증가시키고 amplitude는 감소시키면 기존 함수가 더 자글자글한 형태로 바뀜
    • frequency는 증가시키고 amplitude는 감소시켜가며 구한 octave를 더해나간다
  • 여러 노이즈 정보를 저장하기 위해 각 RGB채널에 저장
    • R: one octave
    • G: sum of two octaves
    • B: sum of three octaves
    • A: sum of four octaves

📃 Code

OpenGL Application

  • 텍스처에 저장할 노이즈 정보를 계산하여 버퍼(배열data)에 저장
  • frequency는 증가시키고, amplitude는 감소시키며 octave를 구하고, octave끼리 더할 때마다 buffer에 저장
  • 노이즈 데이터를 담은 버퍼를 사용해 텍스처 생성
    • 위에서는 GL-RGBA8로 8bit짜리 정보로 저장했는데, 노이즈는 float값이니까 GL-RGBA32F로 floating-point 텍스처로 저장하는게 더 좋을 수 있음

Seamless noise texture

  • 텍스처 크기가 제한되어있으므로, 반복적으로 사용하게 됨
  • 그때, 연결이 자연스럽게(연속적으로) 만들어주기 -> Seamless
  • 노이즈 값을 계산할 때, perlin 함수에 매개변수 하나를 더 추가 glm::vec2(freq)
👀아래는 noise를 활용한 효과 6가지

1. Cloud-like effect

  • 하늘 컬러와 구름 컬러를 mix할 때, 노이즈를 blend factor로 사용
    • higher octave noise를 사용하면 높은 빈도를 가지는.. 자글자글한 구름
    • lower octave noise를 사용하면 낮은 빈도로 전체적인 구조만 가진.. 두루뭉술한 구름

fragment shader

  • 노이즈 값을 그대로 사용하지 않고, Cosine 적용
    -> 좀 더 뚜렷한 구름 형태를 나타냄
  • 구름의 양을 줄이려면 노이즈의 값을 translate하고 범위에 맞춰 clmap

2. Wood-Grain Effect

  • y축을 중심으로 한 cylindrical 통나무 (log)
  • y축으로부터 거리가 정수인 부분을 나이테 색으로 지정
  • 통나무를 자른 2D 영역을 정의하기 위해, xy평면으로 자른 영역을 기준으로 transform
    • 변환된 좌표로 y축으로부터의 거리를 계산
    • scaling하면 패턴의 빈도가 달라지고
    • roating하면 패턴의 모양이 기울어지고..~
  • 나이테의 자글거림을 구현하기 위해 노이즈값 사용

fragment shader

  • 통나무를 자른 영역을 정의하기 위해 texture coordinate에 slice matrix를 곱해 변환
  • 변환된 texture coordinate를 사용해 y축까지의 거리를 계산하고, 거리에 노이즈를 적용해 자글자글해지도록 한다
  • 노이즈가 적용된 거리의 소수점 범위를 [2, 0] 범위로 바꾸고, smoothstep을 적용하여 거리가 0.2보다 작으면 0, 0.5보다 크면 1로 설정한다
    • 기본 나무와 나이테 색상 섞을 때, 경계가 부드럽게 연결되는 영역 설정
  • 기본 나무와 나이테 색상을 섞어 부드럽게 연결한다
    • 거리가 0.2보다 작은 부분은 기본 나무 색상 적용
    • 거리가 0.5보다 큰 부분은 나이테 색상 적용
    • 거리가 0.2~0.5 사이이면 블러 효과
  • 실제로 대칭성을 가지는 나이테가 존재하기도 함
    • texture coordinate가 0.5를 넘어가면 1에서 뺀 값을 사용해 대칭성을 만들어줄 수 있다

3. Disintegration effect

  • 노이즈 값의 thresholding에 따라 fragment discard

fragment shader

4. Paint-spatter effect

  • 노이즈 값의 thresholding에 따라 fragment의 paint/base color 지정
  • spatter 효과를 위해 high frequency 노이즈 사용
    • low 사용하면 spatter 크기가 커짐 (많이 퍼지는 효과)
    • 낮은 threshold는 많이 퍼지지 않은 상태로 크기를 키움
    • 너무 낮아지면 random성이 떨어짐

fragment shader

5. Rusted metal effect

  • 녹슨 효과를 주기 위해 노이즈 값의 thresholding에 따라 fragment의 녹슨 부분 지정
  • 녹슨 부분의 color는 노이즈 값을 blend factor로 하여 오브젝트 색상과 어두운 색vec3(0.01)을 mix해서 만듦

fragment shader

6. Night-vision effect

  • 야간 투시경으로 바라보았을 때의 자글자글한 노이즈 생성 -> high frequency noise
  • 야간 투시경의 특징을 살린 Binocular effect
  • 2pass로 구현
    • 1pass의 렌더링 결과를 FBO에 담고, 2pass에서 single quad위에 노이즈가 적용된 FBO의 텍스처와 Binocular effect를 적용

fragment shader

  • animation이라면.. 노이즈가 매 프레임마다 바뀔 것이다 -> 시간에 따라 texture coordinate를 바꾸거나~
profile
( •̀ .̫ •́ )✧

0개의 댓글