두 텍스처 사이의 "차이"를 찾기 위해 셰이더를 사용하는 것이 가능합니까? (XNA/HLSL)

StackOverflow https://stackoverflow.com/questions/1182158

  •  19-09-2019
  •  | 
  •  

문제

"모션의 가장자리"를 감지하는 간단한 웹캠 기반 애플리케이션을 만들었으므로 현재 프레임의 픽셀이 이전 프레임과 크게 다른 위치를 보여주는 텍스처를 그립니다. 이것은 내 코드입니다.

// LastTexture is a Texture2D of the previous frame.
// CurrentTexture is a Texture2D of the current frame.
// DifferenceTexture is another Texture2D.
// Variance is an int, default 100;

Color[] differenceData = new Color[CurrentTexture.Width * CurrentTexture.Height];
Color[] currentData = new Color[CurrentTexture.Width * CurrentTexture.Height];
Color[] lastData = new Color[LastTexture.Width * LastTexture.Height];

CurrentTexture.GetData<Color>(currentData);
LastTexture.GetData<Color>(lastData);

for (int i = 0; i < currentData.Length; i++)
{
    int sumCD = ColorSum(currentData[i]); // ColorSum is the same as c.R + c.B + c.G where c is a Color.
    int sumLD = ColorSum(lastData[i]);
    if ((sumCD > sumLD - Variance) && (sumCD < sumLD + Variance))
        differenceData[i] = new Color(0, 0, 0, 0); // If the current pixel is within the range of +/- the Variance (default: 100) variable, it has not significantly changes so is drawn black.
    else
        differenceData[i] = new Color(0, (byte)Math.Abs(sumCD - sumLD), 0); // This has changed significantly so is drawn a shade of green.
}

DifferenceTexture = new Texture2D(game1.GraphicsDevice, CurrentTexture.Width, CurrentTexture.Height);
DifferenceTexture.SetData<Color>(differenceData);

LastTexture = new Texture2D(game1.GraphicsDevice,CurrentTexture.Width, CurrentTexture.Height);
LastTexture.SetData<Color>(currentData);

셰이더를 사용 하여이 계산을 GPU에 오프로드하는 방법이 있습니까 (위의 방법을 사용하여 약 25/26 fps로 갈 수 있지만 조금 느립니다)? HLSL 셰이더가 어떻게 작동하는지에 대한 기본적인 이해가 있고 전체 솔루션을 기대하지 않습니다. 이것이 가능한지, 셰이더에서 "차이"텍스처 데이터를 얻는 방법을 알고 싶습니다. .

미리 감사드립니다.

도움이 되었습니까?

해결책

문제에 대한 듀얼 스레드 접근법을 사용하기로 결정한 위의 의견과 관련하여 Microsoft의 .NET Parallel Extensions CTP를 확인하십시오. Microsoft.com

Xbox360에 배포 할 계획이 없다면이 라이브러리는 XNA와 잘 작동하며 특정 루프 및 반복에서 대규모 속도 향상을 보았습니다.

기본적으로 몇 줄의 코드 만 변경하면됩니다.

for (int i = 0; i < currentData.Length; i++)
{
    // ...
}

다음으로 변경됩니다.

Parallel.For(0, currentData.Length, delegate(int i)
{
   // ...
});

프로세서의 각 코어가 자동으로 숫자 위기에 도움이됩니다. 빠르고 훌륭합니다.

행운을 빕니다!

다른 팁

픽셀 셰이더 내부에 두 개의 텍스처를 샘플링 한 다음 차이를 색상 값으로 기록 할 수 있습니다. 당신이 설정 한 경우 a 렌더링 대상, 셰이더에서 ouput 색상 정보는 프레임 버퍼 대신이 텍스처에 저장됩니다.

나는 당신이 어떤 속도 이득을 볼 것으로 예상되는지 모르겠지만, 그것이 내가 그렇게하는 방법입니다.

*편집 - 아, 그리고 나는 당신이 사용하는 샘플링 유형을 알고있는 것을 잊었습니다. 결과에 영향을 미칩니다. 알고리즘이 GPU로 직접 번역되도록하려면 포인트 샘플링을 사용하여 시작하십시오.

그만큼 송전 연산자 또는 Edge Detection을 위해 게임 엔진 및 기타 실시간 응용 프로그램에 사용됩니다. 픽셀 셰이더로 쓰는 것은 사소한 일입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top