쉐이더에서 뭔가 요구하는 대로 안되어서 여러가지 명세서를 읽다가 이제 알아챘다.
First Pass에서 G-buffer를 입력하고, Second Pass에서
Lighting Calculation을 계산하는 쉐이더에서
다음과 같은 코드가 있었다.
if(MyBool.a == 1.0) { // Light Map Material Calculation } else { // Color Material Calculation }
이렇게 했을 때, 오브젝트가 그려지지 않은 background pixel이 light map material calculation할 때, directional light의 색깔을 따라 갔다.
위의 코드에는 두 개의 문제점이 있는데 일단
가장 첫 번째는 floating point value의 comparison을 수행할 때 단순히 저렇게 하는 것은 precision으로 인해 올바른 비교가 되지 않을 가능성이 높다.
만약 다음의 세 가지 코드를 각각 사용했을 때
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
세 번째 파라미터는 internal format인데, shader에서 쓰이는 값의 format을 말한다.
첫 번째 것은 값들을 0 ~ 1로 clamp 시켜버린다.
두 번째 것은 값들을 어떤 범위 제한 없이 사용할 수 있다. 다만 floating point value가 16 bit precisino에서 표현된다.
세 번째 것은 값들을 어떤 범위 제한 없이 사용할 수 있다. 다만 floating point value가 32bit precision에서 표현된다.
첫 번째 파라미터의 RGBA는 unsigned normalized 형식으로 바꾼다고 한다.
두 번째 파라미터는 그대로 쓰는데 16bit precision으로 표현된다, 그리고 명세서에 의하면 8번째 파라미터가 gl_float인데, 값들이 gl_half_float로 내부적으로 바뀐다고 한다.
세 번째 파라미터는 그대로 쓴느데 32bit precision으로 표현된다.
그래서, 어쨋든 이 bit precision에 주의해서 비교를해야 한다.
만약 내가 MyBool.a 값을 0.5, 0.25, 0.125, 0.0625 이런식으로 2진수로 표현하기에 딱 떨어지는 수로 한다면, == 을 썼을 때 내가 원하는대로 작동할 확률이 높다.
GL_RGBA32F는 거의 대부분 == 에 대해서 성공하고
GL_RGBA16F는 저기 위에서 언급한 2진수로 딱 떨어지는 수가 좋다.
GL_RGBA도 0 ~ 1 사이의 2진수로 딱 떨어지는 수로 하여야 한다.
두 번째
두 번째는 내가 명세서를 찾아도 거의 나오지 않는 것들인데, first pass에서 g-buffer에 오브젝트를 그리지 않은 곳에서 MyBool을 texture 함수를 통해 값을 얻으려할 때,
(0, 0, 0, 1)
의 값이 들어가게 된다. 그래서 if (MyBool.a == 1) 일 때 background pixel value가 directional lights에 따라서 바뀌게 된 것이다.
그래서, 이걸 주의해서 MyBool 값을 설정해주면 문제가 없어진다.
왜 저 값이 있는지에 대한 것은
https://stackoverflow.com/questions/34497195/difference-between-format-and-internalformat#comment56736641_34497470
이 스택오버플로우 대화에서 볼 수 있는데,
https://gamedev.stackexchange.com/questions/66613/blank-texture-in-frame-buffer-object-in-deferred-rendering
https://www.opengl.org/discussion_boards/showthread.php/185819-How-to-render-few-objects-with-texture-and-other-without-%28Simple-deferred-shading%29
이 내용도 더 봐보자.
=================================================
알아버렸다. glClearColor(r, g, b, a) 시에
해당 framebuffer에 연결된 color buffer들은 해당 rgba 값으로 변경된다.
그래서 위에서 오브젝트가 그려지지 않은 곳의 텍스쳐 값은 모두 다 0, 0, 0, 1인 이유가
glClearColor(0, 0, 0, 1)로 했기 때문이다. 이로서 고민 해결 끝.
https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glClearColor.xhtml
명세에서도, color buffer를 해당 값으로 clear하므로, deferred rendering에서
오브젝트가 그려지지 않는 background pixel을 참조할 시에 glClearColor 값들이
들어오게 될 것이다.
댓글 없음:
댓글 쓰기