2010-04-16 5 views
3

위치에 따라 객체의 영역을 다르게 렌더링해야하는 코드가 있습니다. 이 영역을 정의하기 위해 컬러 맵을 사용하려고합니다.HLSL tex2d sampler가 겉으로보기에는 일관성없는 반올림을 사용하고 있습니다. 왜?

문제는 내 컬러 맵에서 샘플링 할 때 충돌이 발생합니다. 즉, 컬러 맵에서 다른 색상의 두 영역은 샘플러에서 반환 된 동일한 값을 얻습니다.

다양한 색상 맵을 시도했습니다. 나는 각 경우에 "5"가되도록 각 영역의 색을 설정합니다.

  • 인덱스 컬러
  • RGB, RGBA : RGB 영역 (1) 5 %, 5 %, 5 %의 것이다. 영역 2에는 RGB 10 %, 10 %, 10 % 등이 있습니다.
  • HSV 그레이 스케일 : 영역 1의 HSV는 0.5 %입니다. 영역 2는 HSV 0,0,10 % 등을 갖습니다.

(김프에서 선택된 값)

가 tex2D 샘플러가 값 [0..1]를 반환한다.

[지역에서 int 배열 색인을 파생하고자합니다. 그와 함께 할 수있는 코드는 그래서 "5 %"색상을 샘플링

float region = tex2D(gColourmapSampler,In.UV).x; 

는 HLSL에서 0.05098의 "지역을"준] 질문에서 제거 된, 관련이 없습니다. 이 5 %는 5/100 * 255 또는 12.75를 나타내며 텍스처에 저장 될 때 13으로 반올림된다고 가정합니다. (추론 : 0.05098 * 255 ~ = 13)

이 논리에 따르면 50 %는 127.5로 저장해야합니다.
샘플링 한 결과, 이는 0.50196이되어 128로 저장되었음을 의미합니다.

70 %를 178.5로 저장해야합니다.
여기 무슨 일 라운딩이

178로 저장 한 의미있는 나는 0.698039 수, 샘플링?
(127.5 128이되고, 178.5이된다 178?!)

편집 : OK, http://en.wikipedia.org/wiki/Bankers_rounding#Round_half_to_even 은 분명히이 "은행의 반올림"입니다. 왜 이것이 사용되는지는 모르지만 내 문제는 해결됩니다. 분명히 그것은 김프 문제입니다.


저는 Shader Model 2와 FX Composer를 사용하고 있습니다. 이것은 내 샘플러 선언입니다.

//Colour map 
texture gColourmapTexture < 
    string ResourceName = "Globe_Colourmap_Regions_Greyscale.png"; 
    string ResourceType = "2D"; 
>; 
sampler2D gColourmapSampler : register(s1) = sampler_state { 
Texture = <gColourmapTexture>; 
#if DIRECT3D_VERSION >= 0xa00 
    Filter = MIN_MAG_MIP_LINEAR; 
#else /* DIRECT3D_VERSION < 0xa00 */ 
    MinFilter = Linear; 
    MipFilter = Linear; 
    MagFilter = Linear; 
#endif /* DIRECT3D_VERSION */ 
    AddressU = Clamp; 
    AddressV = Clamp; 
}; 
+0

이미지 편집기에서 반올림이 발생합니다. 8b 텍스처는 정수 이외의 것을 표현할 수 없습니다. 텍스처에 178.5를 저장할 수 없으므로 178 또는 179를 저장해야합니다 (178/255 또는 179/255). 셰이더는 정수에 반올림을 사용하지 않습니다. 정확도를 높이기 위해 반올림하면 여기에 도달하지 않을 것입니다. – Suma

+0

하하 (Haha, ofc). 김프가 텍스처의 값을 저장하는 방법과 관련이 있어야합니다. HLSL과 아무런 관련이 없습니다 : \ – RJFalconer

답변

1

김프는 banker's rounding을 사용합니다. 분명히.

지역 코드를 파생시키기위한 코드가 삭제되었습니다.

1

나는 HLSL을 한번도 사용하지 않았지만, GLSL을 사용했다. (나는 머리가 멀다는 것을 인정해야한다.)

질감과 관련된 한 가지 문제점은 0이 첫 번째 픽셀이 아니라는 것입니다. 1은 두 번째 것이 아닙니다. 0은 텍스처의 가장자리이고 1은 첫 번째 픽셀의 오른쪽 가장자리입니다. 값은 자동으로 보간되고 정상적인 텍스처를 적용하는 대신 룩업 테이블을 적용 할 때와 같이 정밀도가 필요한 경우 심각한 문제를 일으킬 수 있습니다. 픽셀의 중간을 목표로해야하므로 [0.5,0.5], [1.5,0.5] 대신에 [0,0], [1, 0] 등이 있습니다.

적어도 그것이 GLSL에 있었던 방식입니다.

+0

보간법은 영역 테두리에 문제를 일으 킵니다 (조회 값이 유효하지 않으므로 색상이 일치하지 않음).하지만이 문제는 생각하지 않습니다. 샘플러 정의에서 쌍 선형 필터링을 비활성화하여 이음 문제를 해결하기를 바라고 있습니다. 그래도 고마워. – RJFalconer

1

주의 : [region]의 레벨은 반 내림입니다. 이미지 편집기에서 5 %를 볼 때 텍스처 8b 표현의 실제 값은 5/100 * 255 = 12.75이며 12 또는 13 일 수 있습니다. 12 일 경우 반올림하여 내릴 수 있습니다. 가장 가까운 값으로 반올림하려면이 값을 [region + 0.5] 레벨로 변경해야합니다.

또 다른 유사한 점은 (루이 필립이 이미 작성 했음) 텍스처 좌표가 반올림 규칙이라는 것입니다. 당신은 항상 두 개의 텍셀 사이에 있지 않도록 텍셀의 한 지점을 칠 필요가 있습니다. 그렇지 않으면 결과가 잘못 정의됩니다 (무작위로 두 개를 얻을 수 있습니다). 그리고 소스 텍셀 중 일부는 다른 사본이있는 동안 disapper 할 수 있습니다. 이러한 규칙은 빌리나와 포인트 샘플링에 따라 다르므로 샘플을 보정 할 때 텍셀 크기의 절반을 추가해야 할 수도 있습니다.

+0

"두 텍셀 사이에 있지 않도록 항상 텍셀의 한 지점을 칠 필요가 있습니다." 텍스처 *에있는 지점? 텍셀이 내 텍스처에서 영역 경계를 넘을 가능성이 높습니다. 이게 내 솔기 버그의 원인이라고 생각합니다. 그러나 나는 동일한 지역 값을 가진 전체 지역을 얻고있다. 그러나 이들은 인접 해 있으므로 반올림 문제가있을 수 있습니다. 나는 바닥에서 천장에 올려 놓기를 시도했지만 기쁨은 없었다. 나는 더 조사 할 것이다. 귀하의 제안에 대한 타이. – RJFalconer

+0

필자는 과거에 다음과 같은 디버깅 기법을 사용했습니다. 실제 값을 반환하는 대신 검사 할 값을 반환하고 기대 한 값인지 확인합니다. 귀하의 경우, 셰이더에서 영역을 반환하고 그것을 원하는지 확인하십시오. – Suma

+0

무차별 대입 사용 (region> foo가 파란색으로 그려지는 경우, 그렇지 않으면 region> bob이 녹색으로 그려지는 경우) 지역의 값을 결정했습니다. 이것은 일관성이있는 곳입니다. 나는 그 질문을 단순화했다. +1 날 올바른 방향으로 가리 킵니다. 그러나 문제는 여전히 풀리지 않고있다. – RJFalconer

관련 문제