효과 셰이더 연결

Direct2D는 여러 효과 그래프 렌더링 패스를 단일 패스로 결합하는 효과 셰이더 연결이라는 최적화를 사용합니다.

효과 셰이더 연결 개요

효과 셰이더 연결 최적화는 미리 컴파일된 셰이더 함수를 연결하여 런타임에 픽셀 및 꼭짓점 셰이더를 생성할 수 있는 Direct3D 11.2 기능인 HLSL 셰이더 연결을 기반으로 빌드됩니다. 다음 그림에서는 효과 그래프에서 효과 셰이더 연결의 개념을 보여 줍니다. 첫 번째 그림은 4개의 렌더링 변환이 있는 일반적인 Direct2D 효과 그래프를 보여 줍니다. 셰이더 연결이 없으면 각 변환은 렌더링 패스를 사용하고 중간 표면이 필요합니다. 이 그래프에는 총 4개의 패스와 3개의 중간이 필요합니다.

셰이더 연결 없이 그래프 변환: 패스 4개 및 중간 3개

두 번째 그림은 각 렌더링 변환이 링크 가능한 함수 버전으로 대체된 것과 동일한 효과 그래프를 보여줍니다. Direct2D는 전체 그래프를 연결하고 중간자 없이 한 패스로 실행할 수 있습니다. 이렇게 하면 GPU 실행 시간이 크게 감소하고 최대 GPU 메모리 사용량이 감소할 수 있습니다.

셰이더 연결이 있는 변환 그래프: 1개 패스, 0개의 중간

 

효과 셰이더 연결은 효과 내의 개별 변환에서 작동합니다. 즉, 단일 효과가 있는 그래프도 해당 효과에 여러 개의 유효한 변환이 있는 경우 셰이더 연결의 이점을 얻을 수 있습니다.

효과 셰이더 연결 사용

효과를 사용하는 Direct2D 애플리케이션을 빌드하는 경우 효과 셰이더 연결을 활용하기 위해 아무 작업도 수행할 필요가 없습니다. Direct2D는 효과 그래프를 자동으로 분석하여 각 변환을 연결하는 가장 최적의 방법을 결정합니다.

효과 작성자는 효과 셰이더 연결을 지원하는 방식으로 효과를 구현할 책임이 있습니다. 자세한 내용은 아래 셰이더 연결 호환 사용자 지정 효과 작성 섹션을 참조하세요. 모든 기본 제공 효과는 셰이더 연결을 지원합니다.

Direct2D는 유용한 상황에서 인접한 렌더링 변환만 연결합니다. 두 변환을 연결할지 여부를 결정할 때 여러 요소를 고려합니다. 예를 들어 변환 중 하나가 꼭짓점 또는 컴퓨팅 셰이더를 사용하는 경우 픽셀 셰이더만 연결할 수 있으므로 셰이더 연결이 수행되지 않습니다. 또한 셰이더 연결과 호환되도록 효과가 작성되지 않은 경우 주변 변환이 연결되지 않습니다.

이러한 연결 위험이 있는 경우 Direct2D는 위험에 인접한 변환을 연결하지 않지만 그래프의 나머지 부분을 연결하려고 시도합니다.

연결 위험이 있는 변환 그래프: 패스 2회, 중간 1회.

셰이더 링크 호환 사용자 지정 효과 작성

사용자 지정 Direct2D 효과를 작성하는 경우 해당 변환이 효과 셰이더 연결을 지원하는지 확인해야 합니다. 이렇게 하려면 이전 사용자 지정 효과가 구현된 방식에서 약간 변경해야 합니다. 사용자 지정 효과 내의 변환이 셰이더 연결을 지원하지 않는 경우 Direct2D는 효과 그래프에서 인접한 변환과 연결하지 않습니다.

사용자 지정 효과 작성자로서 다음과 같은 몇 가지 주요 개념과 요구 사항을 알고 있어야 합니다.

  • 효과 인터페이스 구현에 대한 변경 내용 없음

    ID2D1DrawTransform과 같은 다양한 효과 인터페이스를 구현하는 코드를 수정할 필요가 없습니다.

  • 셰이더의 전체 및 내보내기 함수 버전을 모두 제공합니다.

    Direct2D에서 연결할 수 있는 효과 셰이더의 내보내기 함수 버전을 제공해야 합니다. 또한 원래의 전체 셰이더도 계속 제공해야 합니다. Direct2D는 그래프의 특정 링크에 셰이더 연결을 적용할지 여부에 따라 런타임에 올바른 셰이더 버전을 선택하기 때문입니다.

    변환이 전체 픽셀 셰이더 Blob만 제공하는 경우( ID2D1EffectContext::LoadPixelShader를 통해) 인접한 변환에 연결되지 않습니다.

  • 도우미 함수

    Direct2D는 셰이더의 전체 및 내보내기 함수 버전을 자동으로 생성하는 HLSL 도우미 함수 및 매크로를 제공합니다. 이러한 도우미는 d2d1effecthelpers.hlsli에서 찾을 수 있습니다. 또한 FXC(HLSL 컴파일러)를 사용하면 내보내기 함수 셰이더를 전체 셰이더의 프라이빗 필드에 삽입할 수 있습니다. 이러한 방식으로 셰이더를 한 번만 작성하고 두 버전을 Direct2D에 동시에 전달하면 됩니다. d2d1effecthelpers.hlsli와 FXC 컴파일러는 모두 Windows SDK의 일부로 포함됩니다.

    도우미 함수:

    또한 함수 사양 내보내기에서 아래에 설명된 사양이 충족되는 한 각 셰이더의 두 버전을 수동으로 작성하고 두 번 컴파일할 수도 있습니다 .

  • 픽셀 셰이더만

    Direct2D는 컴퓨팅 또는 꼭짓점 셰이더 연결을 지원하지 않습니다. 그러나 효과에서 꼭짓점과 픽셀 셰이더를 모두 사용하는 경우 픽셀 셰이더의 출력을 계속 연결할 수 있습니다.

  • 단순 샘플링과 복잡한 샘플링

    셰이더 함수 연결은 한 픽셀 셰이더 패스의 출력을 후속 픽셀 셰이더 패스의 입력에 연결하여 작동합니다. 이는 소비 픽셀 셰이더가 계산을 수행하기 위해 단일 입력 값만 필요한 경우에만 가능합니다. 이 값은 일반적으로 꼭짓점 셰이더에서 내보낸 텍스처 좌표에서 입력 텍스처를 샘플링하는 데 사용됩니다. 이러한 픽셀 셰이더는 간단한 샘플링을 수행했다고합니다.

    회색조 변환은 간단한 샘플링의 예입니다. 특정 출력 픽셀의 값은 해당 입력 픽셀의 값에만 따라 달라집니다.

    Gaussian 흐림과 같은 일부 픽셀 셰이더는 단일 샘플이 아닌 여러 입력 샘플에서 출력을 계산합니다. 이러한 픽셀 셰이더는 복잡한 샘플링을 수행했다고 합니다.

    가우스 흐림은 복잡한 샘플링의 예입니다. 가운데 출력 픽셀의 값은 여러 입력 픽셀에 따라 달라집니다.

    간단한 입력이 있는 셰이더 함수만 다른 셰이더 함수에서 입력을 제공할 수 있습니다. 복잡한 입력이 있는 셰이더 함수는 샘플링할 입력 텍스처와 함께 제공되어야 합니다. 즉, Direct2D는 셰이더를 복잡한 입력과 연결하지 않습니다.

    Direct2D HLSL 도우미를 사용하는 경우 셰이더가 복잡하거나 간단한 입력을 사용하는지 여부를 HLSL에 표시해야 합니다.

연결 호환 효과 셰이더 예제

다음 코드 조각은 D2D 도우미를 사용하여 간단한 연결 호환 효과 셰이더를 나타냅니다.

#define D2D_INPUT_COUNT 1
#define D2D_INPUT0_SIMPLE
#include “d2d1effecthelpers.hlsli”

D2D_PS_ENTRY(LinkingCompatiblePixelShader)
{
    float4 input = D2DGetInput(0);
    input.rgb *= input.a;
    return input;
}          

이 짧은 예제에서는 함수 매개 변수가 선언되지 않고, 각 입력의 입력 수와 입력 유형이 항목 함수 앞에 선언되고, D2DGetInput을 호출하여 입력을 검색하며, 도우미 파일이 포함되기 전에 전처리기 지시문을 정의해야 합니다.

연결 호환 셰이더는 일반 단일 패스 픽셀 셰이더와 내보내기 셰이더 함수를 모두 제공해야 합니다. D2D_PS_ENTRY 매크로를 사용하면 셰이더 컴파일 스크립트와 함께 사용할 때 이러한 각 매크로를 동일한 코드에서 생성할 수 있습니다.

전체 셰이더를 컴파일할 때 매크로는 D2D 효과 호환 입력 서명이 있는 다음 코드로 확장됩니다.

Texture2D<float4> InputTexture0;
SamplerState InputSampler0;

float4 LinkingCompatiblePixelShader(
    float4 pos   : SV_POSITION,
    float4 posScene : SCENE_POSITION,
    float4 uv0  : TEXCOORD0
    ) : SV_Target
    {
        float4 input = InputTexture0.Sample(InputSampler0, uv0.xy);
        input.rgb *= input.a;
        return input;
    }    

동일한 코드의 내보내기 함수 버전을 컴파일할 때 다음 코드가 생성됩니다.

// Shader function version
export float4 LinkingCompatiblePixelShader_Function(
    float4 input0 : INPUT0)
    {
        input.rgb *= input.a;
        return input;
    }      

일반적으로 Texture2D를 샘플링하여 검색되는 텍스처 입력은 함수 입력(input0)으로 대체되었습니다.

연결 호환 효과를 작성하기 위해 수행해야 하는 작업의 전체 단계별 설명을 보려면 사용자 지정 효과 자습서Direct2D 사용자 지정 이미지 효과 샘플을 참조하세요.

호환되는 셰이더 연결 컴파일

연결 가능하려면 D2D에 전달된 픽셀 셰이더 Blob에 셰이더의 전체 및 내보내기 함수 버전이 모두 포함되어야 합니다. 이 작업은 컴파일된 내보내기 함수를 D3D_BLOB_PRIVATE_DATA 영역에 포함시켜 수행됩니다.

셰이더가 D2D 도우미 함수를 사용하여 작성되는 경우 컴파일 시간에 D2D 컴파일 대상을 정의해야 합니다. 컴파일 대상 형식은 D2D_FULL_SHADER D2D_FUNCTION.

연결 호환 효과 셰이더를 컴파일하는 것은 2단계 프로세스입니다.

참고

Visual Studio를 사용하여 효과를 컴파일할 때는 FXC 명령을 모두 실행하는 일괄 처리 파일을 만들고 컴파일 단계 전에 실행되는 사용자 지정 빌드 단계로 이 일괄 처리 파일을 실행해야 합니다.

 

1단계: 내보내기 함수 컴파일

fxc /T <shadermodel> <MyShaderFile>.hlsl /D D2D_FUNCTION /D D2D_ENTRY=<entry> /Fl <MyShaderFile>.fxlib           

셰이더의 내보내기 함수 버전을 컴파일하려면 FXC에 다음 플래그를 전달해야 합니다.

플래그 설명
/T <셰이더모델> FXC 구문에 정의된 대로 ShaderModel>을 적절한 픽셀 셰이더 프로필로 설정합니다<. "HLSL 셰이더 연결" 아래에 나열된 프로필 중 하나여야 합니다.
<MyShaderFile.hlsl> MyShaderFile>을 HLSL 파일의 이름으로 설정합니다<.
/D D2D_FUNCTION 이 정의는 FXC에 셰이더의 내보내기 함수 버전을 컴파일하도록 지시합니다.
/D D2D_ENTRY=<entry> D2D_PS_ENTRY 매크로 내에서 정의한 HLSL 진입점의 이름으로 항목을> 설정합니다<.
/Fl <MyShaderFile.fxlib> MyShaderfile>을 셰이더의 내보내기 함수 버전을 저장할 위치로 설정합니다<. .fxlib 확장은 식별이 용이합니다.

2단계: 전체 셰이더 컴파일 및 내보내기 함수 포함

fxc /T ps_<shadermodel> <MyShaderFile>.hlsl /D D2D_FULL_SHADER /D D2D_ENTRY=<entry> /E <entry> /setprivate <MyShaderFile>.fxlib /Fo <MyShader>.cso /Fh <MyShader>.h           

포함된 내보내기 버전을 사용하여 셰이더의 전체 버전을 컴파일하려면 FXC에 다음 플래그를 전달해야 합니다.

플래그 설명
/T <셰이더모델> FXC 구문에 정의된 대로 ShaderModel>을 적절한 픽셀 셰이더 프로필로 설정합니다<. 1단계에 지정된 연결 프로필에 해당하는 픽셀 셰이더 프로필이어야 합니다.
<MyShaderFile.hlsl> MyShaderFile>을 HLSL 파일의 이름으로 설정합니다<.
/D D2D_FULL_SHADER 이 정의는 FXC에 셰이더의 전체 버전을 컴파일하도록 지시합니다.
/D D2D_ENTRY=<entry> D2D_PS_ENTRY() 매크로 내에서 정의한 HLSL 진입점의 이름으로 항목을> 설정합니다<.
/E <항목> D2D_PS_ENTRY() 매크로 내에서 정의한 HLSL 진입점의 이름으로 항목을> 설정합니다<.
/setprivate <MyShaderFile.fxlib> 이 인수는 FXC가 1단계에서 생성된 내보내기 함수 셰이더를 D3D_BLOB_PRIVATE_DATA 영역에 포함하도록 지시합니다.
/Fo <MyShader.cso> MyShader>를 최종 컴파일된 컴파일된 셰이더를 저장할 위치로 설정합니다<.
/Fh <MyShader.h> MyShader>를 최종 결합 헤더를 저장할 위치로 설정합니다<.

함수 사양 내보내기

D2D 제공 도우미를 사용하지 않고 호환되는 효과 셰이더를 작성하는 것은 권장되지 않지만 가능합니다. 전체 셰이더 및 내보내기 함수 입력 서명이 모두 D2D 사양을 준수하는지 확인하려면 주의해야 합니다.

전체 셰이더에 대한 사양은 이전 Windows 버전과 동일합니다. 간단히 말해서 픽셀 셰이더 입력 매개 변수는 SV_POSITION, SCENE_POSITION 및 효과 입력당 하나의 TEXCOORD여야 합니다.

내보내기 함수의 경우 함수는 float4를 반환해야 하며 해당 입력은 다음 형식 중 하나여야 합니다.

  • 간단한 입력

    float4 d2d_inputN : INPUTN         
    

    간단한 입력의 경우 D2D는 입력 텍스처와 셰이더 함수 사이에 샘플 함수를 삽입하거나 다른 셰이더 함수의 출력에서 입력을 제공합니다.

  • 복잡한 입력

    float4 d2d_uvN  : TEXCOORDN                
    

    복잡한 입력의 경우 D2D는 Windows 8 설명서에 설명된 대로 텍스처 좌표만 전달합니다.

  • 출력 위치

    float4 d2d_posScene : SCENE_POSITION                
    

    하나의 SCENE_POSITION 입력만 정의할 수 있습니다. 연결된 셰이더당 하나의 함수만 이 매개 변수를 활용할 수 있으므로 이 매개 변수는 필요한 경우에만 포함되어야 합니다.

D2D는 의미 체계를 검사하여 함수를 함께 연결하는 방법을 결정하기 때문에 의미 체계를 위와 같이 정의해야 합니다. 함수 입력이 위의 형식 중 하나와 일치하지 않으면 셰이더 연결에 대해 함수가 거부됩니다.

HLSL 도우미

ID3D11Linker 인터페이스

ID3D11FunctionLinkingGraph 인터페이스