231005 Shading

aliceshard·2023년 11월 23일
0
  • 셰이딩이란 무엇인가
    물체를 비추는 빛을 연산해 최종 화면에 색으로써 반영 시키는 방법.

  • 퐁 모델 (Phong model)

    분산(diffuse), 반사(specular), 엠비언트(ambient)의 3가지 속성으로 이루어져 있다. 계산에 사용되는 벡터는 광원(light source), 관찰자(viewer), 법선(normal), 정반사(perfect reflector)로 이루어져 있다.

  • 무광(matte) 물체는 난반사되는 물체(diffuse object)와 동의어다. 이런 물체를 램버트 반사체(Lambertian)이라 부른다. 이런 물체는 사용자가 보는 방향과 전혀 상관없이 같은 색으로 보이는데, 모든 방향으로 반사되기 때문이다.

  • 이런 램버트 반사체는 램버트 법칙(Lambert's Law)를 따르며, 이는 앞서 설명한 분산(diffuse)에 대응된다. 램버트 법칙은 표면의 법선 벡터(nn)와 광원 벡터(ll) 간의 코사인 크기에 색이 비례한다는 법칙이다. 다시 말해서, θ\theta가 크게 입사되면 빛이 비추는 면적도 넓어져 점점 어두워진다는 것이다.

    ccosθc \propto cos{\theta}
  • 종래에는 이 분산된 빛의 강도로 기술되는데, 수식은 다음과 같다. II^{*}은 광원의 빛의 강도, II은 반사된 빛의 강도이며, Kd[0,1]K_d \in [0,1]는 분산(diffuse)-반사(reflect) 계수이다. ll은 광원의 방향이다. 분산된 빛은 반사된 빛이 모든 방향으로 똑같은 강도를 가진다고 가정한다.

I=KdI(cosθ)=KdI(nl)I = K_{d} I^* (cos\theta) =K_d I^* (nl)


  • 반사(specular)는 부드러운 물체(smooth object)에서의 빛 연산을 설명한다. 부드러움의 정도는 빛나는(shiny)와 무딘(dull) 물체로 나뉘며, 반사 경향도 달라진다. 또한 광원으로부터 온 빛(ll)은 법선 벡터(nn)에 대해서 완전히 같은 각도(θ\theta)로 반사(rr) 된다고 가정한다.

  • 하지만 결과적으로는 사용자 눈에 들어오는 빛(vv)가 어떤 강도(IsI_s)를 갖고 있는가가 중요하다. 이는 완벽한 반사 벡터(rr)에 대해서 얼마나 각도 차이(ϕ\phi)가 발생하는지에 따라 달라진다. 램버트 법칙과 비슷하게 이 각도를 사용해 cosϕcos\phi로부터 IsI_s를 근사해낸다. 여기에 추가로, 물체의 빛나는 정도로 IsI_s를 계산해낼 수 있다. 여기도 Ks[0,1]K_s \in [0,1] 의 계수가 존재한다.

    Is=KsI(cosϕ)shiness=KsI(vr)shinessI_s = K_s I (cos\phi)^{shiness} = K_s I (v\cdot r)^{shiness}
  • 다 좋아보이지만, 한가지 문제가 있는데 rr을 계산하는게 비싸다는 점이다.

    r=2n(nl)lr = 2n (n\cdot l) - l

  • Jim Blinn이 다른 아이디어를 제시했는데, vrv \cdot r을 계산하는 대신 다른 벡터를 계산하는 방법을 제안했다. 하프웨이 벡터(halfway vector) hh를 새로 계산해서, 이 벡터와 법선 벡터 nn 사이의 각도를 vrv \cdot r 대신 사용하는 것이다.

    Is=KsI(nh)shinessI_s = K_s I (n \cdot h)^{shiness}
  • 이 방법이 왜 더 좋냐면, 대개 관찰자가 매우 멀어지면 vvll은 사실상 변하지 않는다고 봐도 무방하다. 멀리서 바라보는 물체와 멀리서 조사되는 태양빛은 우리가 조금 움직인다고 해서 방향이 상대적으로 급격하게 변하지 않는다. 반면, rrll의 방향이 바뀌거나 물체의 생김새에 의한 법선 벡터 nn에 의해 방향이 변해버리기 때문에 그렇게 계산하기 좋은 값은 아니다.

  • 엠비언트 빛(Ambient light)은 공간 내 물체에 의해 빛의 반사/간섭들에 의해 생기는 빛의 특성이다. 단순히 KaIaK_a I_a 로만 표현되는데, 이건 다 따라가면 너무 복잡하기 때문.

  • 최종적으로 3개의 특성을 다 합쳐서 다음과 같은 공식이 나오게 된다.

    I=KdId(ln)+KsIs(vr)shininess+KaIaI = K_d I_d (l \cdot n) + K_s I_s (v \cdot r)^{shininess} + K_a I_a
  • II에 R, G, B를 각각 대응 시키고, NN개의 추가 광원을 고려한 식은 다음과 같이 일반화 된다. 또한 특정 광원이 보이는지 안 보이는지를 고려해서 visibility term Si0,1S_i\in {0, 1}를 추가로 고려한다.

I=KaIa+i=1NSi(KdIdimax(0,nli)+KsIsimax(0,vri)shininessI = K_a I_a + \sum_{i=1}^N S_i(K_d I_{d_i} {max}(0, n \cdot l_i) + K_s I_{s_i} {max}(0, v \cdot r_i)^{shininess}
  • 조명(Illumination): 사실 지금까지 살펴본 것은 조명이다. 이제, 이 조명이 평면(surface)에 닿았을 때 어떻게 처리될 지를 결정지어야 한다.

  • Flat shading

    각 삼각형 하나에 같은 II 값을 사용한다. 연산이 단순하지만 색의 연속성은 사라진다.

  • Gouraud shading

    먼저 각 꼭지점에 대해서 법선 벡터를 근사한 뒤, 꼭지점에 대한 II를 계산해낸다. 이후 linear interpolation을 통해 평면 내 색을 근사한다. 현재 업계 표준이지만, 꼭지점에 빛이 더 강하게 떨어지고, 이것들이 표현되어야 할 때 표현하지 못한다는 단점이 존재한다.

  • Phong shading

    먼저 Gouraud shading처럼 각 꼭지점의 법선 벡터를 근사하는데, 여기서 linear interpolation을 할 때는 II 대신 법선 벡터 nn을 interpolation 한다. 이 결과를 바탕으로 II를 각 픽셀마다 계산한다.
    무진장 비싼 방법이지만 특정 꼭지점(모서리)에 하이라이트가 가해질 때 이를 올바르게 표현해낼 수 있다. 현재까지는 OpenGL에서도 지원하지 않는다.

profile
안녕하세요.

0개의 댓글