티스토리 뷰

LOL.

on gray scale.

디버거 상에서는 이상하게 정상적으로 넘어온 normal 값, normal 과 light 의 dot 등에서

xy를 제외한 z 에서 값이 한박자 늦게 update 되었다.

0.1, 0.1, 0.1 0.15, 0.15, 0.1 0.2, 0.2, 0.2

output merge 이후의 값이 아니라 pixel shader에서 값이 저렇게 나온단다.

이런식이다. 이 때문에 normal 이 미쳤나 싶어서 다른 코드 등에서 시간을 보냈다.

만약 다른 이유가 없고 R11G11B10 을 사용하고 있다면,

R11G11B10 이 원인이 될 수 있다.

자세한 설명은 아래에 존재한다.

https://bartwronski.com/2017/04/02/small-float-formats-r11g11b10f-precision/

R11G11B10 을 쓸 땐 좋다고만 생각하고 저 블로그는 왜 저럴까 했는데

막상 내가 겪으니 임팩트가 크다.

red value 만 남겨나도 약간 덜하지만 저런식으로 보인다.

문제가 된 hlsl 코드는 아래와 같다.

output.color.rgb = max( 0, dot( output.normalWS, -LightDirection ) * 0.5;

0.5 부분이 상수인데, 더 낮아질수록 오류는 커진다.

당연히 R11G11B10 으로 할당한 render target 이 있을 거고,

 g_SceneColorBuffer.Create( L"Main Color Buffer", bufferWidth, bufferHeight, 1, DXGI_FORMAT_R11G11B10_FLOAT, esram );

낡은 그래픽 카드에서 UAV는 rgb 로 못만드는 현상 때문에 unpack/pack 이 있다.

uint Pack_R11G11B10_FLOAT( float3 rgb )

float3 Unpack_R11G11B10_FLOAT( uint rgb )
{
    float r = f16tof32((rgb << 4 ) & 0x7FF0);
    float g = f16tof32((rgb >> 7 ) & 0x7FF0);
    float b = f16tof32((rgb >> 17) & 0x7FE0);
    return float3(r, g, b);
}

R16G16B16A16 이나 R8G8B8 등으로 바꾸면 아래와 같이 깨끗하게 나온다. packing 부분도 빼야하지. (normal 값 정밀도 땜시 약간은 보인다)

위에 소개한 블로그에서는 2가지 방법을 제시하였다. 댓글 까지 합치면 3개다.

  1. Gamma 적용해서 unpack 및 곱셈과정에서의 에러 줄이기
  2. 다른 color space (color 가 rgb 인게 문제)
  3. dithering 디더링
  4. rgb 모두 같은 크기 사용

제작하고 있는 프로그램에서는 문제는 dot 값이라 gamma 적용과 관계가 없어 보이지만,

diffuse 등의 texture에는 gamma가 적용되고 거기에 곱해지고 다시 non-linear로 되기에 아래와 같이 효과가 있다.

대신,

이랬던 tone이

이렇게

tone mapping 까지 키면,

미쿠 색이 바뀌네

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크