최적화된 오렌-네이어 쉐이더 코드

김포프 2011-11-16


이번에 KGC 2011에서 강연하면서 기존에 있던 것보다 빠른 오렌-네이어 쉐이더 코드를 공개했었습니다. 강연자료를 다 보기 귀찮으신 분들을 위해 그 코드만 빼서 여기에 올립니다. 저희가 이전에 쓰던 오렌-네이어 코드는 Wolfgang Engel 아저씨의 위키책에서 빌려왔던 거라 강의전에 Wolfgang아저씨에게 이런 코드를 만들었다고 귀뜸해주니 좋아하시더군요.

이 근사치(approximation)를 구하는 코드의 장점은 텍스처 룩업을 하지 않는 다는 것이죠. 스페이스마린에서는 텍스처 룩업이 보틀넥이었거든요. 일단 이 코드는 수학적으로 100% 맞는건 아니지만 저희 겜에서는 아무 문제 없이 썼습니다. (강연중에도 말씀드렸듯이... '수학적인 검증은 중요치 않다. 아티스트들 보기에만 맞으면 된다.')


half ComputeOrenNayarLighting_Fakey( half3 N, half3 L, half3 V, half roughness )
{
  // Through brute force iteration I found this approximation. Time to test it out.
  half LdotN = dot( L, N );
  half VdotN = dot( V, N );
  half result = saturate(LdotN);
  half soft_rim = saturate(1-VdotN/2); //soft view dependant rim
  half fakey = pow(1-result*soft_rim,2);//modulate lambertian by rim lighting
  half fakey_magic = 0.62;
  //(1-fakey)*fakey_magic to invert and scale down the lighting
  fakey = fakey_magic - fakey*fakey_magic;
  return lerp( result, fakey, roughness );
}