다른 객체에 대한 다른 셰이더 DirectX 11


13

나는 배우고 Direct3D 11있으며, 쉐이더 작성에 대해 찾은 모든 기본 자습서에서 Vertex와 Pixel 쉐이더가 작성되어 전체 장면을 같은 방식으로 변환합니다. 텍스처가있는 렌더 큐브와 같은 자습서 ...

그러나 나는 어떻게 객체를 구별합니까? 예를 들어, 일부 오브젝트에서 미러 표면을 시뮬레이션하고 다른 셰이더를 사용하여 나머지 장면을 렌더링하려면 어떻게해야합니까? 대부분의 게임은 다양한 모양과 변형을 달성하기 위해 많은 정점 및 픽셀 쉐이더를 사용해야한다고 생각합니다.

감사합니다.

답변:


23

예, 게임 엔진에는 일반적으로 다양한 쉐이더가 있습니다. 일반적인 패턴은 다음과 같습니다.

  1. 엔진을 초기화하고 게임 월드를로드하는 동안 렌더링에 사용할 모든 셰이더를 준비하십시오. "준비"란 메모리에로드하고 필요한 경우 컴파일 한 ID3D11Device::CreatePixelShader다음 D3D 셰이더 객체를 할당하고 준비 할 수 있도록 모든 호출을 수행합니다 . 객체를 배열 또는 다른 데이터 구조로 유지하십시오.

    일반적으로 정점 셰이더와 함께 작동하도록 설계된 픽셀 셰이더 사이에는 일대일 관계가 있습니다. 나는 그것들이 하나의 객체라고 생각하는데, 그것은 실제로 버텍스 쉐이더와 픽셀 쉐이더 (그리고 아마도 지오메트리 / 헐 / 도메인 쉐이더도 포함하고 있음)를 포함하고 있지만 "쉐이더"라고 부릅니다.

  2. 각 프레임은 렌더링 할 객체 (메시) 목록을 찾았 으면 셰이더별로 정렬합니다. 주어진 쉐이더로 모든 객체를 함께 그려서 프레임에서 쉐이더를 전환하는 횟수를 최소화하는 것이 좋습니다. 이는 셰이더 전환이 다소 비싼 작업이기 때문입니다 (프레임 당 수백 또는 천 번 수행 할 수는 있지만 실제로 그렇게 비싸지는 않습니다 ).

    실제로 한 단계 더 나아가 메쉬를 먼저 쉐이더로 정렬하고 머티리얼을 둘째로 정렬 할 수 있습니다. "소재"란 셰이더와 텍스처 및 매개 변수의 조합을 의미합니다. 셰이더에는 일반적으로 텍스처와 숫자 매개 변수 (상수 버퍼에 저장 됨)가 포함되어 있으므로 벽돌 재질과 아스팔트 재질은 다른 재질의 텍스처와 동일한 셰이더 코드를 사용할 수 있습니다.

  3. 그리려면 셰이더를 반복하고에 각 셰이더를 ID3D11DeviceContext설정하고 매개 변수 (일정한 버퍼, 텍스처 등)를 설정 한 다음 객체를 그립니다. 내가 언급 한 쉐이더 / 재질 구별을 포함한 의사 코드에서 :

    for each shader:
        // Set the device context to use this shader
        pContext->VSSetShader(shader.pVertexShader);
        pContext->PSSetShader(shader.pPixelShader);
    
        for each material that uses this shader:
            // Set the device context to use any constant buffers, textures, samplers,
            // etc. needed for this material
            pContext->VSSetConstantBuffers(...);
            pContext->PSSetConstantBuffers(...);
            pContext->PSSetShaderResources(...);
            pContext->PSSetSamplers(...);
    
            for each mesh that uses this material:
                // Set any constant buffers containing parameters specific to the mesh
                // (e.g. world matrix)
                pContext->VSSetConstantBuffers(...);
    
                // Set the context to use the vertex & index buffers for this mesh
                pContext->IASetInputLayout(mesh.pInputLayout);
                pContext->IASetVertexBuffers(...);
                pContext->IASetIndexBuffer(...);
                pContext->IASetPrimitiveTopology(...)
    
                // Draw it
                pContext->DrawIndexed(...)

객체, 메시, 셰이더, 입력 레이아웃, 상수 버퍼 등 관리에 대해 말할 수있는 것이 더 많지만 시작하기에 충분해야합니다. :)


셰이더 및 재질별로 정렬을 제안합니다. 스위칭 쉐이더 대 스위칭 재료의 비용에 대한 하드 데이터가 있습니까? DX9의 경우 VS / PS 조합을 "프로그램"이라고합니다. 그들이 DX11에서 그 용어를 여전히 사용하고 있는지 확실하지 않습니다.
Panda Pajama

1
@PandaPajama 좋은 질문입니다. 아니요, 스위칭 재료 또는 쉐이더의 실제 비용에 대한 최근 측정 값을 알지 못합니다. 이 접근 방식은 수년간 "일반적인 지혜"였지만 상황이 어떻게 바뀌 었는지 확인하기 위해 실제 측정을 수행 할 가치가 있습니다. :)
Nathan Reed
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.