[GPU프로그래밍] 6. Lighting and Shading

jungizz_·2024년 4월 16일
0

GPU Programming

목록 보기
6/15
post-thumbnail

◾ Shading with multiple positional lights

  • point lights
  • 조명이 여러개 일때 vertex shader에서의 계산
    • 각 조명들을 계산하고 합하여 총 intensity를 알아내기
  • 여러개의 조명 정보(위치, 밝기)를 쉐이더 코드에 저장하기 위해 Uniform Arrays 사용
    • 라이트 정보는 구조체로 이뤄짐 -> 구조체로 이뤄진 배열
  • 5개의 조명으로 5번의 Phong model 계산한 결과를 전부 합쳐서 최종 컬러 내보냄

Unifrom Structure

  • Uniform형태의 구조체에 값을 넘겨주기 위해서는 구조체의 멤버변수 따로따로 해주면 됨
    (위의 예시에서는 구조체배열[5]이므로, 아래 과정을 5번 더 해주면 된다..)

◾ Shading with a directional light source

  • Directional light: 아주 멀리 있는 빛이라 모든 버텍스에서 동일한 light vector를 가진다 (차이 거의X)
    • 위치가 지정되는 point light와의 비교
    • 표면의 모든 위치에서 light vector를 계산해줄 필요X
      -> 계산 간단, 속도 증가
  • 한 쉐이더 코드 안에서 Directional light와 Position Light를 조건문으로 나누어 계산
    • LightPosition의 w가 0이면 위치가 아닌 벡터를 의미(homogeneous) -> directional light(머.. light 종류 매개변수를 Uniform으로 받아오든지 여러가지 방법이 있긴하죠)

◾ Phong Shading (per-fragment shading)

  • 라이팅을 vertex shader가 아닌 fragment shader에서 계산
    • (per-vertex) Gouraud shading: vertex shader에서 라이팅 계산하여 얻은 버텍스 컬러들을 fragment shader에서 interpolation
    • (per-fragment) Phong shading: vertex shader에서 normal과 position을 interpolation하고 fragment shader에서 그 값들로 셰이딩 계산
  • per-vertex의 문제점
    • 버텍스 컬러의 interpolation으로 칠해지기 때문에, Polygon안쪽에 specular term이 생겨 vertex가 영향을 못받는 경우에 specular가 잘 표현되지 못하고 어두워질 수 있음
      -> 버텍스만으로 계산하기 때문에 Polygon이 넓으면 polygon 내부 라이트 표현이 잘 안될 수 있다
    • Polygon 경계가 드러나기도 함
      -> 셰이딩 퀄리티가 낮다
  • 그래서 요즘은 거의 전부 per-fragment 셰이딩

◾ Phong Shading

  • vertex shader에서는 light 계산에 필요한 Position, normal을 변환한 뒤 fragment shader로 넘겨줘야함
    • Position과 normal은 camera coord로 변환
    • gl-Position은 projection까지 하여 screen coord로 변환
  • fragment shader에서 라이팅(phong model) 계산
    • vertex shader에서 normal의 normalize를 해주긴 했지만, fragment shader로 넘어오는 interpolation과정에서 변화기 생겼을 수 있으므로 한번 더 normalize!

◾ Blinn-Phong reflection model

  • phong model의 reflected vectorr보다 계산량이 적은 Halfway vector h를 사용하여 계산
  • phong model의 specular term식의 rh로 대체하면 됨
    • f: specualr의 퍼짐 정도 (클수록 좁고 밝음)
  • 성능상의 이점을 가질 뿐만 아니라, 더욱 현실적으로 묘사

◾ Simulating a spotlight

  • spotLight: 조명의 방향을 중심으로 일정 각도 안에만 조명 적용 (cone)
    • 추가되는 조명 정보: 방향벡터d, 각도c
  • Fragment shader에서 spotScale을 계산해주기
    • 해당 position에서 spotLight까지의 벡터(뒤집어야 함)와 light방향벡터d를 활용해서 각도를 구한다
    • 각도가 light범위를 벗어나는지 확인하고, 벗어나지 않는 경우에 cos정도에 따라 spotScale을 지정해준다
      • angle이 0에 가까울수록(= light방향벡터가 향하는 곳과 해당 버텍스가 가까울 때) cosAng이 1이고, 1인 cosAng에 exponetial해봤자 1이라서 spotScale은 1
      • 반대로, angle이 90도에 가까워질수록 cosAng은 0에 가까워져 급격하게 어두워짐!
  • 나머지는 Blinn-Phong 계산으로 동일

◾ Toon Shading (Cel Shading)

  • 같은 구간에 있는 애들을 전부 같은 색으로 칠해주기 (quantization)
    • 조건문 사용해서 밝기값으로 범위를 나누거나
    • 조건문 없이 각도를 계산하여 범위를 나누거나 (아래 코드)
  • 몇 구간으로 나눌건지에 대한 level을 설정
  • sDotN에 level을 곱하고 내림 계산해서 구간을 만든다
    • 0~0.9 -> 0 / 1~1.9 -> 1 / 2~2.9 -> 2 / 3 -> 3
  • 그리고 다시 level으로 나누어서 [0, 1]이 되도록 한다
    • 0 / 0.333... / 0.666... / 1
    • 이대로 Color값으로 사용

◾ Simulating Fog

  • fragment 색 + (constant) fog 색
    • fog색은 멀수록 많이
    • 카메라 기준으로 멀수록 안보이니까 (이걸 계산)
  • 원하는 렌더링 효과에 따라 Linear하게하거나 non-Linear하게 하거나..~

◾ Linear relationship Fog

  • dmaxd_{max}: 안개 효과가 최대로 적용되는 거리
  • dmind_{min}: 안개 효과가 최소로 적용되는 거리 (안개 효과X)
  • zz: 카메라로부터의 거리
  • ff: fag factor
    • ff=0 -> zz=dmaxd_{max} (100% 안개)
    • ff=1 -> zz=dmind_{min} (안개X)
  • fog factor를 사용해 fog color와 shade color를 mix

◾ Non-linear relationship Fog

  • 좀만 떨어져도 잘 안보이게 (거리 비례X)

distance from camera

  • fog뿐만 아니라 카메라로부터의 거리를 고려한 효과를 적용하는 경우
  • 정확한 거리(in camera coordinate)
    • z가 아닌, length()함수를 사용하여 vertex position과 camera position(원점)의 거리를 계산
  • 위처럼 하면 정확하지만, length()함수는 sqaure root 연산을 포함하므로 계산이 큰 편
  • 그래서 대략적인 거리인 depthz를 사용하기도 한다 (결과가 별 차이 없으면 z쓰는게 좋음)

◾ Physically-Based Rendering

  • Phong과 Blinn-Phong refelction model는 경험적 모델로 계산이 간단해서 자주 사용되지만, 물체가 많아지고 다양한 material을 고려하려면 조절할 매개변수가 너무 많아진다
    -> physically-based refelection model을 사용
  • 얘도 경험적 모델이지만, 물리법칙에 기반하기 때문에 더욱 정확하고, 일관성있게 파라미터 조절 가능

◾ reflection equation

  • 빛이 표면에서 어떻게 분산되는가
  • 반구 범위의 적분은, 반구로 들어오는 모든 방향의 빛을 고려하기 위해 하는 것
    • Lo(v)L_o(v): 반구로 들어오는 모든 방향의 입사광의 반사광 중 v방향으로 들어오는 빛의 양
  • Li(l)L_i(l): 직접광만 고려할 수도 있고, 간접광도 같이 고려할 수 있는데 계산이 복잡해질 수 있다~
  • 이때, cosine factor(n•l)로 weight를 주며 적분 (노멀과 같은 방향으로 빛이 들어올 때 빛을 가장 많이 받으므로, cosine factor가 1일 때 가장 큰 weight를 준다) -> geometry of situation
  • f(l,v)f(l, v): BRDF는 아래에서 자세히 살펴보자~

◾ BRDF (Bidirectional Reflectance Distribution Function)

  • f(l, v): l방향에서 들어온 빛이 v방향으로 얼만큼 반사되는가 (반사율)
    • 입사하는 빛에 따른 반사하는 빛의 비율에 대한 함수
    • 0~1범위의 (R, G, B)로 표현
    • 수평, 수직 각도로 표현할 수 있기 때문에 방향만 고려했을 때 4d function으로 정의 (?)
  • 몇가지 특이한 reflection model...~
    • 1번과 6번 그림: 모든 방향으로 균일하게 반사 -> surface가 diffuse
  • 물질에 따라 BRDF가 다르므로, diffuse와 specular로 나뉜다

Diffuse BRDF

  • diffuse한 surface는 난반사의 표현으로, 일부 빛은 표면으로 흡수되고 다시 표면을 나와 diffuse reflectance를 형성
  • 모든 방향으로 균일하게 반사(방향성x) -> fdf_d는 상수값을 가진다
  • 물질마다 다른 값을 가짐
  • 물체의 색을 결정 -> diffuse color cdiffc_{diff}

Microfacet theory

  • 미세 표면 분포도에 따라 반사도 조절
  • 표면은 아주 작은 거울 조각(small facets)들로 구성되어있고 다양한 방향을 바라보고 있다
    • 표면이 매끄러우면 노멀 방향의 변화가 크지 않아서 반사광 방향이 거의 일정 -> 뚜렷
    • 표면이 거칠면 노멀 방향의 변화가 커서 반사광 방향이 각각 다른 방향으로 분산 -> 흐릿
  • 흐릿한 이유를 자세히 설명하자면, 특정 지점을 향한 입사광의 반사광이 분산돼서 일부가 눈에 들어오는데, 다른 지점을 향한 입사광의 반사광도 분산돼서 일부가 눈에 들어감 -> 여러 빛이 섞여 보여서 흐릿
  • 실제로 버텍스를 조정하여 울퉁불퉁함을 구현하지 않고(평평하게 렌더링), 얼마나 울퉁불퉁한지 확률적으로 나타내서 계산하는 것 -> GG, DD

Specular BRDF

  • 표면에 흡수되지 않고 바로 반사되는 빛 (glossy reflectance)
  • Microfacet theory에 기반한 모델
  1. Fresnel reflection F(l, h)
    • 평평한 표면(mirror)임을 가정한 물질마다의 반사 정도 -> 물질에 따라
    • 노멀과 입사광 사이 각도에 따라 결정 (보는 각도에 따라 반사광이 다르게 보이기 때문)
      • spcular는 눈으로 들어오는 방향 vv만 고려해야하니까, 반사광의 방향이 vv와 동일한 빛만 고려한다
        -> 즉, vvllhalfway vector hh와 노멀이 동일한 미세표면에 입사하는 빛의 비율을 따지면 반사 정도를 나타낼 수 있다! (반사광이 vv와 같아서 눈으로 들어올테니까~)
    • Schlink approximation
      • F0F_0: specular refletance의 특징 (상수값)
        • F0F_0인 이유는 노멀과 입사광 사이 각도가 0도일 때를 나타내고, 이때의 F0F_0specular color로 사용
          (금속은 diffuse fdf_d가 없어 specular fsf_s로만 컬러가 결정됨)
        • 물질마다 F0F_0의 경향성을 가진다 ( 금속은 F0F_0이 크고, 비금속은 F0F_0이 작음(0.05이하))
        • RGB로 표현
    • Metalness workflow (color)
      • 금속: diffuse color가 없으므로 Cdiff=(0,0,0)C_{diff}=(0, 0, 0)으로 설정하고, spcular color F0F_0을 컬러로 사용한다
      • 비금속: specular color F0F_0을 작은 값으로 설정하고 (ex.(0.04, 0.04, 0.04)), diffuse color CdiffC_{diff}를 컬러로 사용한다
  2. Geometry function G(l, v, h)
    • micro surface에서 얼마나 가려지는지 -> 거칠기(microfacet)에 따라
    • 가려지면 어두워짐 (occlusion)
    • 거칠기 파라미터 rr로 상수 KK를 계산하여 함수에 활용
  3. Microgeometry normal distribution function D(h)
    (microfacet distribution function)
    • micro surface에서 normal vector가 얼마나 분산되어있는지 -> 거칠기(microfacet)에 따라
    • 표면이 얼마나 울퉁불퉁할지를 확률적으로 나타낸 분포함수
      • 넓을수록 거칠고, 좁을수록 매끈함
      • 반사광의 방향이 vv인 노멀의 방향이 hh이라고 했고, 이 hh 주변으로 normal이 많이 몰려있으면(분포함수가 좁고뾰족) 매끈
    • specular highlight의 크기와 모양에 큰 영향
    • GGX distribution
      • α=r2α=r^2
      • 사용자가 조절하는 거칠기 파라미터 rr를 바로 사용하지 않고, 제곱하여 αα로 사용하는 이유는:
        • 사용자가 조절하기 쉽도록 (조금 바꿨을 때 확 바뀌면 조절이 힘드니까)
        • rr을 그대로 사용하면 rough 범위가 좁아 활용 범위가 적음 (αα는 real world와 비슷한 정도의 rough범위를 가짐)(위-α, 아래-r)

◾ Reflectance Equation (re)

  • reflectance equation 식을 간단화하기 위해 들어오는 빛을 point light들로만 생각
    • 적분할 필요 없이 point light source들의 합으로 나타내면 된다 -> multiple lights
    • 조명의 세기는 거리 제곱에 반비례하므로.. 아래 식까지 적용해주면 더 정확하다

◾ material parameters

  • non-physical-based shading보다 상대적으로 적고 직관적인 매개변수!!!!
  1. 금속/비금속 결정 (Boolean)
  2. roughnessr [0, 1]
  3. color (금속이면 F0F_0, 비금속이면 CdiffC_{diff})

📃 Code

👀 위 결과 이미지의 Specular color를 살펴보면, 금속은 고유의 색을 가지고, 비금속은 하얀색으로만 나타남!
profile
( •̀ .̫ •́ )✧

0개의 댓글