rendertarget에 많은 값을 렌더링하는 데 문제가 있습니다. 값은 내가 원하는 정확한 범위로 끝나지 않습니다. 기본적으로 전체 화면 쿼드 및 픽셀 셰이더를 사용하여 렌더 대상 텍스처에 렌더링 한 다음 셰이더에서 일부 계산의 기준으로 텍스처 좌표를 사용하려고합니다. 쿼드의 텍스처 좌표는 왼쪽 상단의 (0,0)에서 오른쪽 하단의 (1,1)까지입니다. 보간 후 이러한 값은 픽셀 쉐이더에 도달하지 않습니다. .
예 : 4x4 텍스처로 렌더링 하고이 경우 셰이더는 단순히 빨강 및 녹색 채널의 텍스처 좌표 (u, v)를 출력합니다.
return float4(texCoord.rg, 0, 1);
내가 꺼내고 싶은 것은 왼쪽 상단의 픽셀이 RGB (0,0,0)이므로 검은 색이므로 오른쪽 상단의 픽셀은 RGB (255,0,0)이므로 밝습니다. 빨간색이며 왼쪽 하단의 픽셀은 RGB (0,255,0)이며 밝은 녹색입니다.
그러나 대신 오른쪽에 이것을 얻습니다.
(직선 쿼드 렌더링, 보정 없음)
왼쪽 상단 픽셀은 검은 색이지만 다른 모서리에는 상대적으로 짙은 빨간색과 짙은 녹색 만 있습니다. RGB 값은 (191,0,0) 및 (0,191,0)입니다. 쿼드의 샘플링 위치와 관련이 있다고 생각합니다. 왼쪽 상단 픽셀은 쿼드의 왼쪽 상단을 올바르게 샘플링하고 UV 좌표로 (0,0)을 얻지 만 다른 코너 픽셀은 샘플링되지 않습니다. 쿼드의 다른 모서리. 왼쪽 이미지에서 쿼드를 나타내는 파란색 상자와 흰색 점이 상위 샘플링 좌표를 사용하여 이것을 설명했습니다.
이제 Direct3D9에서 화면 정렬 된 쿼드를 렌더링 할 때 좌표에 적용해야하는 절반 픽셀 오프셋에 대해 알고 있습니다. 내가 어떤 종류의 결과를 얻었는지 보자.
(DX9의 반 픽셀 오프셋으로 렌더링 된 쿼드)
빨강과 초록이 밝아졌지만 여전히 정확하지 않습니다. 빨강 또는 초록색 채널에서 얻을 수있는 최대 값은 223입니다. 그러나 이제는 더 이상 순수한 검은 색이 아니라 RGB (32,32,0)의 어두운 황색 회색입니다!
실제로 필요한 것은 이런 종류의 렌더링입니다.
(대상 렌더링, 축소 된 쿼드 크기)
첫 번째 그림과 비교하여 쿼드의 오른쪽과 아래쪽 테두리를 정확히 한 픽셀 위로 왼쪽으로 이동 해야하는 것처럼 보입니다. 그런 다음 오른쪽 열과 픽셀의 맨 아래 행은 모두 쿼드의 경계에서 UV 좌표를 올바르게 가져옵니다.
VertexPositionTexture[] quad = new VertexPositionTexture[]
{
new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 1f), new Vector2(0,0)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, 1.0f, 1f), new Vector2(1,0)),
new VertexPositionTexture(new Vector3(-1.0f, -1.0f + pixelSize.Y, 1f), new Vector2(0,1)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, -1.0f + pixelSize.Y, 1f), new Vector2(1,1)),
};
그러나 이것은 제대로 작동하지 않아 아래쪽 및 오른쪽 픽셀이 전혀 렌더링되지 않습니다. 이 픽셀의 중심이 더 이상 쿼드로 덮여 있지 않으므로 쉐이더로 처리되지 않는다고 가정합니다. 쿼드를 조금 더 크게 만들기 위해 픽셀 크기 계산을 약간 씩 변경하면 적어도 4x4 텍스처에서 작동합니다. 더 작은 텍스처에서는 작동하지 않으며 더 큰 텍스처에서도 uv 값의 균일 한 분포가 미묘하게 왜곡 될 것 같습니다.
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(작은 텍스처, 예를 들어 1D 룩업 테이블의 경우 pixelSize 계산을 0.001f로 수정했습니다. 작동하지 않으며 0.01f 이상으로 늘려야합니다)
물론 이것은 사소한 예이며 UV를 픽셀 센터에 매핑하는 것에 대해 걱정할 필요없이 CPU에서 훨씬 쉽게이 계산을 수행 할 수 있습니다. 그럼에도 불구하고 실제로 완전하고 완전한 [0, 1] rendertarget의 픽셀 범위!?