DirectX의 렌더링Rendering in DirectX

참고

이 문서는 레거시 WinRT 네이티브 Api와 관련이 있습니다.This article relates to the legacy WinRT native APIs. 새 네이티브 앱 프로젝트의 경우 OPENXR API 를 사용 하는 것이 좋습니다.For new native app projects, we recommend using the OpenXR API.

Windows Mixed Reality는 DirectX를 기반으로 하 여 사용자를 위한 풍부한 3D 그래픽 환경을 생성 합니다.Windows Mixed Reality is built on DirectX to produce rich, 3D graphical experiences for users. 렌더링 추상화는 시스템에서 예측 하는 holographic 장면 관찰자의 위치 및 방향에 대 한 이유를 앱에서 사용할 수 있도록 하는 DirectX 바로 위에 있습니다.The rendering abstraction sits just above DirectX, which lets apps reason about the position and orientation of holographic scene observers predicted by the system. 그러면 개발자는 각 카메라를 기준으로 holograms를 찾을 수 있습니다. 그러면 사용자가 이동할 때 다양 한 공간 좌표계에서 앱이 이러한 holograms을 렌더링 합니다.The developer can then locate their holograms based on each camera, letting the app render these holograms in various spatial coordinate systems as the user moves around.

참고:이 연습에서는 Direct3D 11의 holographic 렌더링에 대해 설명 합니다.Note: This walkthrough describes holographic rendering in Direct3D 11. Direct3D 12 Windows Mixed Reality 앱 템플릿은 혼합 현실 앱 템플릿 확장과 함께 제공 됩니다.A Direct3D 12 Windows Mixed Reality app template is also supplied with the Mixed Reality app templates extension.

현재 프레임에 대 한 업데이트Update for the current frame

Holograms에 대 한 응용 프로그램 상태를 업데이트 하려면 앱에서 다음을 수행 합니다.To update the application state for holograms, once per frame the app will:

  • 디스플레이 관리 시스템에서 HolographicFrame 를 가져옵니다.Get a HolographicFrame from the display management system.
  • 렌더링이 완료 되 면 카메라 보기가 표시 되는 현재 예측으로 장면을 업데이트 합니다.Update the scene with the current prediction of where the camera view will be when render is completed. Holographic 장면에는 카메라를 두 개 이상 사용할 수 있습니다.Note, there can be more than one camera for the holographic scene.

Holographic 카메라 보기로 렌더링 하려면 프레임당 한 번, 앱에서 다음을 수행 합니다.To render to holographic camera views, once per frame the app will:

  • 각 카메라에 대해 시스템의 카메라 보기 및 프로젝션 매트릭스를 사용 하 여 현재 프레임에 대 한 장면을 렌더링 합니다.For each camera, render the scene for the current frame, using the camera view and projection matrices from the system.

새 holographic 프레임을 만들고 해당 예측을 가져옵니다.Create a new holographic frame and get its prediction

HolographicFrame 에는 앱에서 현재 프레임을 업데이트 하 고 렌더링 하는 데 필요한 정보가 있습니다.The HolographicFrame has information that the app needs to update and render the current frame. 앱은 Createnextframe 메서드를 호출 하 여 각 새 프레임을 시작 합니다.The app begins each new frame by calling the CreateNextFrame method. 이 메서드가 호출 되 면 사용 가능한 최신 센서 데이터를 사용 하 여 예측을 수행 하 고 currentprediction 개체에 캡슐화 합니다.When this method is called, predictions are made using the latest sensor data available, and encapsulated in CurrentPrediction object.

새 프레임 개체는 특정 시간 동안만 유효 하므로 렌더링 된 각 프레임에 사용 해야 합니다.A new frame object must be used for each rendered frame as it is only valid for an instant in time. Currentprediction 속성은 카메라 위치와 같은 정보를 포함 합니다.The CurrentPrediction property contains information such as the camera position. 이 정보는 프레임이 사용자에 게 표시 될 것으로 예상 되는 정확한 시점에 추정 됩니다.The information is extrapolated to the exact moment in time when the frame is expected to be visible to the user.

다음 코드는 Appmain:: Update 에서 발췌 한 것 됩니다.The following code is excerpted from AppMain::Update:

// The HolographicFrame has information that the app needs in order
// to update and render the current frame. The app begins each new
// frame by calling CreateNextFrame.
HolographicFrame holographicFrame = m_holographicSpace.CreateNextFrame();

// Get a prediction of where holographic cameras will be when this frame
// is presented.
HolographicFramePrediction prediction = holographicFrame.CurrentPrediction();

카메라 업데이트 처리Process camera updates

백 버퍼는 프레임에서 프레임으로 변경 될 수 있습니다.Back buffers can change from frame to frame. 앱은 각 카메라에 대해 백 버퍼의 유효성을 검사 하 고 필요에 따라 리소스 뷰 및 깊이 버퍼를 해제 하 고 다시 만들어야 합니다.Your app needs to validate the back buffer for each camera, and release and recreate resource views and depth buffers as needed. 예측의 포즈 집합은 현재 프레임에서 사용 되는 카메라의 신뢰할 수 있는 목록입니다.Notice that the set of poses in the prediction is the authoritative list of cameras being used in the current frame. 일반적으로이 목록을 사용 하 여 카메라 집합을 반복 합니다.Usually, you use this list to iterate on the set of cameras.

Appmain:: Update 에서:From AppMain::Update:

m_deviceResources->EnsureCameraResources(holographicFrame, prediction);

From DeviceResources:: EnsureCameraResources:From DeviceResources::EnsureCameraResources:

for (HolographicCameraPose const& cameraPose : prediction.CameraPoses())
{
    HolographicCameraRenderingParameters renderingParameters = frame.GetRenderingParameters(cameraPose);
    CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
    pCameraResources->CreateResourcesForBackBuffer(this, renderingParameters);
}

렌더링을 위한 기반으로 사용할 좌표계를 가져옵니다.Get the coordinate system to use as a basis for rendering

Windows Mixed Reality를 사용 하면 앱에서 실제 세계의 위치를 추적 하는 데 연결 된 고정 참조 프레임과 같은 다양 한 좌표계를 만들 수 있습니다.Windows Mixed Reality lets your app create various coordinate systems, like attached and stationary reference frames for tracking locations in the physical world. 그러면 앱이 이러한 좌표계를 사용 하 여 각 프레임 holograms를 렌더링 하는 위치를 지정할 수 있습니다.Your app can then use these coordinate systems to reason about where to render holograms each frame. API에서 좌표를 요청 하는 경우 항상 해당 좌표를 표시 하려는 SpatialCoordinateSystem 를 전달 합니다.When requesting coordinates from an API, you'll always pass in the SpatialCoordinateSystem within which you want those coordinates to be expressed.

Appmain:: Update 에서:From AppMain::Update:

pose = SpatialPointerPose::TryGetAtTimestamp(
    m_stationaryReferenceFrame.CoordinateSystem(), prediction.Timestamp());

그런 다음 이러한 좌표계를 사용 하 여 장면에서 콘텐츠를 렌더링할 때 스테레오 뷰 매트릭스를 생성할 수 있습니다.These coordinate systems can then be used to generate stereo view matrices when rendering the content in your scene.

From CameraResources:: UpdateViewProjectionBuffer:From CameraResources::UpdateViewProjectionBuffer:

// Get a container object with the view and projection matrices for the given
// pose in the given coordinate system.
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);

응시 및 제스처 입력 처리Process gaze and gesture input

응시직접 입력은 시간을 기반으로 하지 않으며 sttimer 함수에서 업데이트할 필요가 없습니다.Gaze and hand input aren't time-based and don't have to update in the StepTimer function. 그러나이 입력은 앱이 각 프레임을 확인 해야 하는 항목입니다.However this input is something that the app needs to look at each frame.

프로세스 시간 기반 업데이트Process time-based updates

실시간 렌더링 앱은 시간 기반 업데이트를 처리 하는 몇 가지 방법이 필요 합니다. Windows Holographic 앱 템플릿은 DirectX 11 UWP 앱 템플릿에서 제공 되는 단계 타이머와 유사한 sttimer 구현을 사용 합니다.Any real-time rendering app will need some way to process time-based updates - the Windows Holographic app template uses a StepTimer implementation, similar to the StepTimer provided in the DirectX 11 UWP app template. 이 Sttimer 샘플 도우미 클래스는 고정 된 시간 단계 업데이트, 가변 시간 단계 업데이트 및 기본 모드를 가변 시간 단계로 제공할 수 있습니다.This StepTimer sample helper class can provide fixed time-step updates, variable time-step updates, and the default mode is variable time steps.

Holographic 렌더링의 경우 고정 된 시간 단계로 구성할 수 있으므로 타이머 함수에 너무 많이 배치 하지 않기로 선택 했습니다.For holographic rendering, we've chosen not to put too much into the timer function because you can configure it to be a fixed time step. 프레임 마다 두 번 이상 호출 될 수 있습니다. 일부 프레임의 경우에는 holographic 데이터 업데이트가 프레임당 한 번만 수행 되어야 합니다.It might get called more than once per frame – or not at all, for some frames – and our holographic data updates should happen once per frame.

Appmain:: Update 에서:From AppMain::Update:

m_timer.Tick([this]()
{
    m_spinningCubeRenderer->Update(m_timer);
});

좌표계에서 holograms 위치 및 회전Position and rotate holograms in your coordinate system

단일 좌표계에서 작업 하는 경우 템플릿이 SpatialStationaryReferenceFrame 를 사용 하 여 작업 하는 경우이 프로세스는 3d 그래픽에서 다른 방법으로 사용 되는 것과는 다릅니다.If you're operating in a single coordinate system, as the template does with the SpatialStationaryReferenceFrame, this process isn't different from what you're otherwise used to in 3D graphics. 여기서는 큐브를 회전 하 고 고정 좌표계의 위치를 기준으로 모델 매트릭스를 설정 합니다.Here, we rotate the cube and set the model matrix based on the position in the stationary coordinate system.

SpinningCubeRenderer:: Update 에서:From SpinningCubeRenderer::Update:

// Rotate the cube.
// Convert degrees to radians, then convert seconds to rotation angle.
const float    radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
const double   totalRotation = timer.GetTotalSeconds() * radiansPerSecond;
const float    radians = static_cast<float>(fmod(totalRotation, XM_2PI));
const XMMATRIX modelRotation = XMMatrixRotationY(-radians);

// Position the cube.
const XMMATRIX modelTranslation = XMMatrixTranslationFromVector(XMLoadFloat3(&m_position));

// Multiply to get the transform matrix.
// Note that this transform does not enforce a particular coordinate system. The calling
// class is responsible for rendering this content in a consistent manner.
const XMMATRIX modelTransform = XMMatrixMultiply(modelRotation, modelTranslation);

// The view and projection matrices are provided by the system; they are associated
// with holographic cameras, and updated on a per-camera basis.
// Here, we provide the model transform for the sample hologram. The model transform
// matrix is transposed to prepare it for the shader.
XMStoreFloat4x4(&m_modelConstantBufferData.model, XMMatrixTranspose(modelTransform));

고급 시나리오에 대 한 참고 사항: 회전 하는 큐브는 단일 참조 프레임 안에 홀로그램을 배치 하는 방법을 보여 주는 간단한 예입니다.Note about advanced scenarios: The spinning cube is a simple example of how to position a hologram within a single reference frame. 동일한 렌더링 된 프레임에서 동시에 여러 SpatialCoordinateSystems를 사용할 수도 있습니다.It's also possible to use multiple SpatialCoordinateSystems in the same rendered frame, at the same time.

상수 버퍼 데이터 업데이트Update constant buffer data

콘텐츠에 대 한 모델 변환은 평소와 같이 업데이트 됩니다.Model transforms for content are updated as usual. 이제 렌더링할 좌표계에 대해 유효한 변환을 계산 합니다.By now, you'll have computed valid transforms for the coordinate system you'll be rendering in.

SpinningCubeRenderer:: Update 에서:From SpinningCubeRenderer::Update:

// Update the model transform buffer for the hologram.
context->UpdateSubresource(
    m_modelConstantBuffer.Get(),
    0,
    nullptr,
    &m_modelConstantBufferData,
    0,
    0
);

보기 및 프로젝션 변환에 대 한 자세한 정보What about view and projection transforms? 최상의 결과를 얻으려면 그리기 호출에 대해 거의 준비가 될 때까지 대기 하 고 싶습니다.For best results, we want to wait until we're almost ready for our draw calls before we get these.

현재 프레임을 렌더링 합니다.Render the current frame

Windows Mixed Reality에서 렌더링 하는 것은 2D 모노 디스플레이에서 렌더링 하는 것과 크게 다르지 않지만 몇 가지 차이점이 있습니다.Rendering on Windows Mixed Reality isn't much different from rendering on a 2D mono display, but there are a few differences:

  • Holographic 프레임 예측은 중요 합니다.Holographic frame predictions are important. 프레임이 표시 될 때 예측에 더 가깝습니다. holograms이 더 좋아집니다.The closer the prediction is to when your frame is presented, the better your holograms will look.
  • Windows Mixed Reality는 카메라 보기를 제어 합니다.Windows Mixed Reality controls the camera views. Holographic 프레임이 나중에 표시 되기 때문에 각 항목에 렌더링 합니다.Render to each one because the holographic frame will be presenting them for you later.
  • 인스턴스 그리기를 렌더링 대상 배열에 사용 하 여 스테레오 렌더링을 수행 하는 것이 좋습니다.We recommend doing stereo rendering using instanced drawing to a render target array. Holographic 앱 템플릿은 렌더링 대상 뷰를 Texture2DArray 에 사용 하는 렌더링 대상 배열에 대해 인스턴스화된 그리기의 권장 되는 방법을 사용 합니다.The holographic app template uses the recommended approach of instanced drawing to a render target array, which uses a render target view onto a Texture2DArray.
  • 스테레오 인스턴스를 사용 하지 않고 렌더링 하려면 각 눈 마다 하나씩 두 개의 비 배열 RenderTargetViews를 만들어야 합니다.If you want to render without using stereo instancing, you'll need to create two non-array RenderTargetViews, one for each eye. 각 RenderTargetViews는 시스템에서 앱에 제공 되는 Texture2DArray 의 두 조각 중 하나를 참조 합니다.Each RenderTargetViews references one of the two slices in the Texture2DArray provided to the app from the system. 이것은 일반적으로 인스턴스를 사용 하는 것 보다 느리므로 권장 되지 않습니다.This isn't recommended, as it's typically slower than using instancing.

업데이트 된 HolographicFrame 예측 가져오기Get an updated HolographicFrame prediction

프레임 예측을 업데이트 하면 이미지 안정화의 효율성이 향상 됩니다.Updating the frame prediction enhances the effectiveness of image stabilization. 예측 사이의 시간을 단축 하 고 프레임이 사용자에 게 표시 되는 시간 때문에 holograms의 보다 정확한 위치를 지정 합니다.You get more accurate positioning of holograms because of the shorter time between the prediction and when the frame is visible to the user. 프레임 예측은 렌더링 직전에 업데이트 하는 것이 좋습니다.Ideally update your frame prediction just before rendering.

holographicFrame.UpdateCurrentPrediction();
HolographicFramePrediction prediction = holographicFrame.CurrentPrediction();

각 카메라에 렌더링Render to each camera

예측에서 카메라의 집합에 대 한 루프를 실행 하 고이 집합의 각 카메라에 렌더링 합니다.Loop on the set of camera poses in the prediction, and render to each camera in this set.

렌더링 패스 설정Set up your rendering pass

Windows Mixed Reality에서는 stereoscopic 렌더링을 사용 하 여 깊이의 효과를 높이고 stereoscopically를 렌더링 하므로 왼쪽 및 오른쪽 디스플레이가 모두 활성화 됩니다.Windows Mixed Reality uses stereoscopic rendering to enhance the illusion of depth and to render stereoscopically, so both the left and the right display are active. Stereoscopic 렌더링을 사용 하 여 두 표시 사이에 오프셋이 있습니다. 즉, 두뇌는 실제 깊이로 조정할 수 있습니다.With stereoscopic rendering, there's an offset between the two displays, which the brain can reconcile as actual depth. 이 섹션에서는 Windows Holographic 앱 템플릿의 코드를 사용 하 여 인스턴스를 사용 하는 stereoscopic 렌더링에 대해 설명 합니다.This section covers stereoscopic rendering using instancing, using code from the Windows Holographic app template.

각 카메라에는 자체 렌더링 대상 (백 버퍼) 및 뷰 및 프로젝션 매트릭스가 holographic 공간으로 포함 됩니다.Each camera has its own render target (back buffer), and view and projection matrices, into the holographic space. 앱은 카메라 단위로 깊이 버퍼와 같은 다른 카메라 기반 리소스를 만들어야 합니다.Your app will need to create any other camera-based resources - such as the depth buffer - on a per-camera basis. Windows Holographic 앱 템플릿에서 이러한 리소스를 DX:: CameraResources에 함께 묶는 도우미 클래스를 제공 합니다.In the Windows Holographic app template, we provide a helper class to bundle these resources together in DX::CameraResources. 렌더링 대상 뷰를 설정 하 여 시작 합니다.Start by setting up the render target views:

Appmain:: Render 에서:From AppMain::Render:

// This represents the device-based resources for a HolographicCamera.
DX::CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();

// Get the device context.
const auto context = m_deviceResources->GetD3DDeviceContext();
const auto depthStencilView = pCameraResources->GetDepthStencilView();

// Set render targets to the current holographic camera.
ID3D11RenderTargetView *const targets[1] =
    { pCameraResources->GetBackBufferRenderTargetView() };
context->OMSetRenderTargets(1, targets, depthStencilView);

// Clear the back buffer and depth stencil view.
if (m_canGetHolographicDisplayForCamera &&
    cameraPose.HolographicCamera().Display().IsOpaque())
{
    context->ClearRenderTargetView(targets[0], DirectX::Colors::CornflowerBlue);
}
else
{
    context->ClearRenderTargetView(targets[0], DirectX::Colors::Transparent);
}
context->ClearDepthStencilView(
    depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

예측을 사용 하 여 카메라에 대 한 보기 및 프로젝션 매트릭스 가져오기Use the prediction to get the view and projection matrices for the camera

각 holographic 카메라에 대 한 보기 및 프로젝션 매트릭스가 모든 프레임에서 변경 됩니다.The view and projection matrices for each holographic camera will change with every frame. 각 holographic 카메라에 대해 상수 버퍼의 데이터를 새로 고칩니다.Refresh the data in the constant buffer for each holographic camera. 예측을 업데이트 한 후와 해당 카메라에 대 한 그리기 호출을 수행 하기 전에이 작업을 수행 합니다.Do this after you updated the prediction, and before you make any draw calls for that camera.

Appmain:: Render 에서:From AppMain::Render:

// The view and projection matrices for each holographic camera will change
// every frame. This function refreshes the data in the constant buffer for
// the holographic camera indicated by cameraPose.
if (m_stationaryReferenceFrame)
{
    pCameraResources->UpdateViewProjectionBuffer(
        m_deviceResources, cameraPose, m_stationaryReferenceFrame.CoordinateSystem());
}

// Attach the view/projection constant buffer for this camera to the graphics pipeline.
bool cameraActive = pCameraResources->AttachViewProjectionBuffer(m_deviceResources);

여기서는 카메라 포즈에서 매트릭스를 가져오는 방법을 보여 줍니다.Here, we show how the matrices are acquired from the camera pose. 이 프로세스를 진행 하는 동안 카메라의 현재 뷰포트도 가져옵니다.During this process, we also obtain the current viewport for the camera. 좌표계를 제공 하는 방법에 유의 하세요 .이 좌표계는 응시를 이해 하는 데 사용한 것과 동일한 좌표계 이며 회전 하는 큐브를 배치 하는 데 사용 하는 것과 동일 합니다.Note how we provide a coordinate system: this is the same coordinate system we used to understand gaze, and it's the same one we used to position the spinning cube.

From CameraResources:: UpdateViewProjectionBuffer:From CameraResources::UpdateViewProjectionBuffer:

// The system changes the viewport on a per-frame basis for system optimizations.
auto viewport = cameraPose.Viewport();
m_d3dViewport = CD3D11_VIEWPORT(
    viewport.X,
    viewport.Y,
    viewport.Width,
    viewport.Height
);

// The projection transform for each frame is provided by the HolographicCameraPose.
HolographicStereoTransform cameraProjectionTransform = cameraPose.ProjectionTransform();

// Get a container object with the view and projection matrices for the given
// pose in the given coordinate system.
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);

// If TryGetViewTransform returns a null pointer, that means the pose and coordinate
// system cannot be understood relative to one another; content cannot be rendered
// in this coordinate system for the duration of the current frame.
// This usually means that positional tracking is not active for the current frame, in
// which case it is possible to use a SpatialLocatorAttachedFrameOfReference to render
// content that is not world-locked instead.
DX::ViewProjectionConstantBuffer viewProjectionConstantBufferData;
bool viewTransformAcquired = viewTransformContainer != nullptr;
if (viewTransformAcquired)
{
    // Otherwise, the set of view transforms can be retrieved.
    HolographicStereoTransform viewCoordinateSystemTransform = viewTransformContainer.Value();

    // Update the view matrices. Holographic cameras (such as Microsoft HoloLens) are
    // constantly moving relative to the world. The view matrices need to be updated
    // every frame.
    XMStoreFloat4x4(
        &viewProjectionConstantBufferData.viewProjection[0],
        XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) *
            XMLoadFloat4x4(&cameraProjectionTransform.Left))
    );
    XMStoreFloat4x4(
        &viewProjectionConstantBufferData.viewProjection[1],
        XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) *
            XMLoadFloat4x4(&cameraProjectionTransform.Right))
    );
}

각 프레임은 뷰포트를 설정 해야 합니다.The viewport should be set each frame. 꼭 짓 점 셰이더 (최소)는 일반적으로 뷰/프로젝션 데이터에 액세스할 수 있어야 합니다.Your vertex shader (at least) will generally need access to the view/projection data.

From CameraResources:: AttachViewProjectionBuffer:From CameraResources::AttachViewProjectionBuffer:

// Set the viewport for this camera.
context->RSSetViewports(1, &m_d3dViewport);

// Send the constant buffer to the vertex shader.
context->VSSetConstantBuffers(
    1,
    1,
    m_viewProjectionConstantBuffer.GetAddressOf()
);

카메라 백 버퍼에 렌더링 하 고 깊이 버퍼를 커밋합니다.Render to the camera back buffer and commit the depth buffer:

좌표계가 과정이 되지 않는 경우 (예: 추적이 중단 된 경우) 앱에서 해당 프레임에 대해 렌더링할 수 없기 때문에 뷰/프로젝션 데이터를 사용 하기 전에 TryGetViewTransform 이 성공 했는지 확인 하는 것이 좋습니다.It's a good idea to check that TryGetViewTransform succeeded before trying to use the view/projection data, because if the coordinate system isn't locatable (for example, tracking was interrupted) your app can't render with it for that frame. CameraResources 클래스가 성공적인 업데이트를 나타내는 경우에만이 템플릿은 회전 하는 큐브에서 렌더링 을 호출 합니다.The template only calls Render on the spinning cube if the CameraResources class indicates a successful update.

Windows Mixed Reality에는 개발자 또는 사용자가 세계에 배치 하는 위치에 holograms을 유지 하기 위한 이미지 안정화 기능이 포함 되어 있습니다.Windows Mixed Reality includes features for image stabilization to keep holograms positioned where a developer or user puts them in the world. 이미지 안정화를 사용 하면 렌더링 파이프라인에서 내재 된 대기 시간을 숨겨 사용자에 게 가장 적합 한 holographic 환경을 보장할 수 있습니다.Image stabilization helps hide the latency inherent in a rendering pipeline to ensure the best holographic experiences for users. 포커스 지점을 지정 하 여 이미지 안정화를 향상 시킬 수도 있고, 실시간으로 최적화 된 이미지를 계산 하기 위한 깊이 버퍼가 제공 될 수도 있습니다.A focus point may be specified to enhance image stabilization even further, or a depth buffer may be provided to compute optimized image stabilization in real time.

최상의 결과를 위해 앱은 CommitDirect3D11DepthBuffer API를 사용 하 여 깊이 버퍼를 제공 해야 합니다.For best results, your app should provide a depth buffer using the CommitDirect3D11DepthBuffer API. Windows Mixed Reality는 깊이 버퍼의 기 하 도형 정보를 사용 하 여 이미지 안정화를 실시간으로 최적화할 수 있습니다.Windows Mixed Reality can then use geometry information from the depth buffer to optimize image stabilization in real time. Windows Holographic 앱 템플릿은 기본적으로 응용 프로그램의 깊이 버퍼를 커밋 하 여 홀로그램 안정성을 최적화 하도록 지원 합니다.The Windows Holographic app template commits the app's depth buffer by default, helping optimize hologram stability.

Appmain:: Render 에서:From AppMain::Render:

// Only render world-locked content when positional tracking is active.
if (cameraActive)
{
    // Draw the sample hologram.
    m_spinningCubeRenderer->Render();
    if (m_canCommitDirect3D11DepthBuffer)
    {
        // On versions of the platform that support the CommitDirect3D11DepthBuffer API, we can 
        // provide the depth buffer to the system, and it will use depth information to stabilize 
        // the image at a per-pixel level.
        HolographicCameraRenderingParameters renderingParameters =
            holographicFrame.GetRenderingParameters(cameraPose);
        
        IDirect3DSurface interopSurface =
            DX::CreateDepthTextureInteropObject(pCameraResources->GetDepthStencilTexture2D());

        // Calling CommitDirect3D11DepthBuffer causes the system to queue Direct3D commands to 
        // read the depth buffer. It will then use that information to stabilize the image as
        // the HolographicFrame is presented.
        renderingParameters.CommitDirect3D11DepthBuffer(interopSurface);
    }
}

참고

Windows는 GPU에서 깊이 질감을 처리 하므로 깊이 버퍼를 셰이더 리소스로 사용할 수 있어야 합니다.Windows will process your depth texture on the GPU, so it must be possible to use your depth buffer as a shader resource. 사용자가 만든 ID3D11Texture2D는 형식이 아닌 형식 이어야 하며 셰이더 리소스 뷰로 바인딩되어야 합니다.The ID3D11Texture2D that you create should be in a typeless format and it should be bound as a shader resource view. 이미지 안정화를 위해 커밋될 수 있는 깊이 질감을 만드는 방법에 대 한 예제는 다음과 같습니다.Here is an example of how to create a depth texture that can be committed for image stabilization.

CommitDirect3D11DepthBuffer에 대 한 깊이 버퍼 리소스 생성 코드:Code for Depth buffer resource creation for CommitDirect3D11DepthBuffer:

// Create a depth stencil view for use with 3D rendering if needed.
CD3D11_TEXTURE2D_DESC depthStencilDesc(
    DXGI_FORMAT_R16_TYPELESS,
    static_cast<UINT>(m_d3dRenderTargetSize.Width),
    static_cast<UINT>(m_d3dRenderTargetSize.Height),
    m_isStereo ? 2 : 1, // Create two textures when rendering in stereo.
    1, // Use a single mipmap level.
    D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE
);

winrt::check_hresult(
    device->CreateTexture2D(
        &depthStencilDesc,
        nullptr,
        &m_d3dDepthStencil
    ));

CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(
    m_isStereo ? D3D11_DSV_DIMENSION_TEXTURE2DARRAY : D3D11_DSV_DIMENSION_TEXTURE2D,
    DXGI_FORMAT_D16_UNORM
);
winrt::check_hresult(
    device->CreateDepthStencilView(
        m_d3dDepthStencil.Get(),
        &depthStencilViewDesc,
        &m_d3dDepthStencilView
    ));

Holographic 내용 그리기Draw holographic content

Windows Holographic 앱 템플릿은 인스턴스 기 하 도형을 크기 2의 Texture2DArray로 그리는 권장 기법을 사용 하 여 스테레오에서 콘텐츠를 렌더링 합니다.The Windows Holographic app template renders content in stereo by using the recommended technique of drawing instanced geometry to a Texture2DArray of size 2. 이에 대 한 인스턴스 및 Windows Mixed Reality에서 작동 하는 방식을 살펴보겠습니다.Let's look at the instancing part of this, and how it works on Windows Mixed Reality.

From SpinningCubeRenderer:: Render:From SpinningCubeRenderer::Render:

// Draw the objects.
context->DrawIndexedInstanced(
    m_indexCount,   // Index count per instance.
    2,              // Instance count.
    0,              // Start index location.
    0,              // Base vertex location.
    0               // Start instance location.
);

각 인스턴스는 상수 버퍼에서 다른 뷰/프로젝션 행렬에 액세스 합니다.Each instance accesses a different view/projection matrix from the constant buffer. 다음은 두 행렬의 배열인 상수 버퍼 구조입니다.Here's the constant buffer structure, which is just an array of two matrices.

Hlsl에서 VPRTVertexShader hlsl 에 포함 된 VertexShaderShared.From VertexShaderShared.hlsl, included by VPRTVertexShader.hlsl:

// A constant buffer that stores each set of view and projection matrices in column-major format.
cbuffer ViewProjectionConstantBuffer : register(b1)
{
    float4x4 viewProjection[2];
};

각 픽셀에 대해 렌더링 대상 배열 인덱스를 설정 해야 합니다.The render target array index must be set for each pixel. 다음 코드 조각에서 viewId는 SV_RenderTargetArrayIndex 의미 체계에 매핑됩니다.In the following snippet, output.viewId is mapped to the SV_RenderTargetArrayIndex semantic. 이를 위해서는 선택적 Direct3D 11.3 기능을 지원 해야 합니다 .이 기능을 사용 하면 모든 셰이더 단계에서 렌더링 대상 배열 인덱스 의미 체계를 설정할 수 있습니다.This requires support for an optional Direct3D 11.3 feature, which allows the render target array index semantic to be set from any shader stage.

From VPRTVertexShader. hlsl:From VPRTVertexShader.hlsl:

// Per-vertex data passed to the geometry shader.
struct VertexShaderOutput
{
    min16float4 pos     : SV_POSITION;
    min16float3 color   : COLOR0;

    // The render target array index is set here in the vertex shader.
    uint        viewId  : SV_RenderTargetArrayIndex;
};

Hlsl에서 VPRTVertexShader hlsl 에 포함 된 VertexShaderShared.From VertexShaderShared.hlsl, included by VPRTVertexShader.hlsl:

// Per-vertex data used as input to the vertex shader.
struct VertexShaderInput
{
    min16float3 pos     : POSITION;
    min16float3 color   : COLOR0;
    uint        instId  : SV_InstanceID;
};

// Simple shader to do vertex processing on the GPU.
VertexShaderOutput main(VertexShaderInput input)
{
    VertexShaderOutput output;
    float4 pos = float4(input.pos, 1.0f);

    // Note which view this vertex has been sent to. Used for matrix lookup.
    // Taking the modulo of the instance ID allows geometry instancing to be used
    // along with stereo instanced drawing; in that case, two copies of each 
    // instance would be drawn, one for left and one for right.
    int idx = input.instId % 2;

    // Transform the vertex position into world space.
    pos = mul(pos, model);

    // Correct for perspective and project the vertex position onto the screen.
    pos = mul(pos, viewProjection[idx]);
    output.pos = (min16float4)pos;

    // Pass the color through without modification.
    output.color = input.color;

    // Set the render target array index.
    output.viewId = idx;

    return output;
}

이 메서드를 사용 하 여 스테레오 렌더링 대상 배열로 기존 인스턴스 그리기 기술을 사용 하려는 경우에는 일반적으로 사용 하는 인스턴스 수를 두 번 그립니다.If you want to use your existing instanced drawing techniques with this method of drawing to a stereo render target array, draw twice the number of instances you normally have. 셰이더에는 입력. s i d id 를 2로 나누고, 개체 당 데이터의 버퍼에 인덱싱할 수 있는 원본 인스턴스 id (예:)를 가져옵니다. int actualIdx = input.instId / 2;In the shader, divide input.instId by 2 to get the original instance ID, which can be indexed into (for example) a buffer of per-object data: int actualIdx = input.instId / 2;

HoloLens에서 스테레오 콘텐츠를 렌더링 하는 방법에 대 한 중요 정보Important note about rendering stereo content on HoloLens

Windows Mixed Reality는 모든 셰이더 단계에서 렌더링 대상 배열 인덱스를 설정 하는 기능을 지원 합니다.Windows Mixed Reality supports the ability to set the render target array index from any shader stage. 일반적으로이 작업은 Direct3D 11에 대 한 의미 체계를 정의 하는 방식 때문에 기 하 도형 셰이더 단계 에서만 수행할 수 있는 작업입니다.Normally, this is a task that could only be done in the geometry shader stage because of the way the semantic is defined for Direct3D 11. 여기서는 꼭 짓 점 및 픽셀 셰이더 단계 집합만 사용 하 여 렌더링 파이프라인을 설정 하는 방법의 전체 예제를 보여 줍니다.Here, we show a complete example of how to set up a rendering pipeline with just the vertex and pixel shader stages set. 셰이더 코드는 위에서 설명한 것과 같습니다.The shader code is as described above.

From SpinningCubeRenderer:: Render:From SpinningCubeRenderer::Render:

const auto context = m_deviceResources->GetD3DDeviceContext();

// Each vertex is one instance of the VertexPositionColor struct.
const UINT stride = sizeof(VertexPositionColor);
const UINT offset = 0;
context->IASetVertexBuffers(
    0,
    1,
    m_vertexBuffer.GetAddressOf(),
    &stride,
    &offset
);
context->IASetIndexBuffer(
    m_indexBuffer.Get(),
    DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
    0
);
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
context->IASetInputLayout(m_inputLayout.Get());

// Attach the vertex shader.
context->VSSetShader(
    m_vertexShader.Get(),
    nullptr,
    0
);
// Apply the model constant buffer to the vertex shader.
context->VSSetConstantBuffers(
    0,
    1,
    m_modelConstantBuffer.GetAddressOf()
);

// Attach the pixel shader.
context->PSSetShader(
    m_pixelShader.Get(),
    nullptr,
    0
);

// Draw the objects.
context->DrawIndexedInstanced(
    m_indexCount,   // Index count per instance.
    2,              // Instance count.
    0,              // Start index location.
    0,              // Base vertex location.
    0               // Start instance location.
);

HoloLens가 아닌 장치에서 렌더링 하는 방법에 대 한 중요 정보Important note about rendering on non-HoloLens devices

꼭 짓 점 셰이더의 렌더링 대상 배열 인덱스를 설정 하려면 그래픽 드라이버가 선택적 Direct3D 11.3 기능을 지원 해야 합니다 .이 기능은 HoloLens에서 지원 됩니다.Setting the render target array index in the vertex shader requires that the graphics driver supports an optional Direct3D 11.3 feature, which HoloLens does support. 앱은 렌더링을 위한 해당 기법도 안전 하 게 구현할 수 있으며 모든 요구 사항은 Microsoft HoloLens에서 실행 하기 위해 충족 됩니다.Your app may can safely implement just that technique for rendering, and all requirements will be met for running on the Microsoft HoloLens.

Holographic 앱에 대 한 강력한 개발 도구인 HoloLens 에뮬레이터를 사용 하 고 Windows 10 Pc에 연결 된 Windows Mixed Reality 모던 헤드셋 장치를 지 원하는 경우를 들 수 있습니다.It may be the case that you want to use the HoloLens emulator as well, which can be a powerful development tool for your holographic app - and support Windows Mixed Reality immersive headset devices that are attached to Windows 10 PCs. 모든 Windows 혼합 현실에 대해 HoloLens가 아닌 렌더링 경로에 대 한 지원은 Windows Holographic 앱 템플릿에도 빌드됩니다.Support for the non-HoloLens rendering path - for all of Windows Mixed Reality - is also built into the Windows Holographic app template. 템플릿 코드에서 개발 PC의 GPU에서 holographic 앱을 실행할 수 있도록 하는 코드를 찾을 수 있습니다.In the template code, you'll find code to enable your holographic app to run on the GPU in your development PC. DeviceResources 클래스가이 선택적 기능 지원을 확인 하는 방법은 다음과 같습니다.Here's how the DeviceResources class checks for this optional feature support.

From DeviceResources:: CreateDeviceResources:From DeviceResources::CreateDeviceResources:

// Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options, sizeof(options));
if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
{
    m_supportsVprt = true;
}

이 선택적 기능 없이 렌더링을 지원 하려면 앱에서 geometry 셰이더를 사용 하 여 렌더링 대상 배열 인덱스를 설정 해야 합니다.To support rendering without this optional feature, your app must use a geometry shader to set the render target array index. 이 코드 조각은 VSSetConstantBuffers 에 추가 되 고, 이전 섹션에 표시 된 코드 예제의 Pssetshader 이전에 는 HoloLens에서 스테레오를 렌더링 하는 방법을 설명 합니다.This snippet would be added after VSSetConstantBuffers, and before PSSetShader in the code example shown in the previous section that explains how to render stereo on HoloLens.

From SpinningCubeRenderer:: Render:From SpinningCubeRenderer::Render:

if (!m_usingVprtShaders)
{
    // On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
    // VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
    // a pass-through geometry shader is used to set the render target 
    // array index.
    context->GSSetShader(
        m_geometryShader.Get(),
        nullptr,
        0
    );
}

HLSL 참고:이 경우 TEXCOORD0와 같은 항상 허용 되는 셰이더 의미 체계를 사용 하 여 렌더링 대상 배열 인덱스를 geometry 셰이더에 전달 하는 약간 수정 된 꼭 짓 점 셰이더도 로드 해야 합니다.HLSL NOTE: In this case, you must also load a slightly modified vertex shader that passes the render target array index to the geometry shader using an always-allowed shader semantic, such as TEXCOORD0. 기 하 도형 셰이더가 작업을 수행할 필요가 없습니다. 템플릿 기 하 도형 셰이더는 SV_RenderTargetArrayIndex 의미 체계를 설정 하는 데 사용 되는 렌더링 대상 배열 인덱스를 제외 하 고 모든 데이터를 통과 합니다.The geometry shader doesn't have to do any work; the template geometry shader passes through all data, with the exception of the render target array index, which is used to set the SV_RenderTargetArrayIndex semantic.

Hlsl에 대 한 앱 템플릿 코드 GeometryShader:App template code for GeometryShader.hlsl:

// Per-vertex data from the vertex shader.
struct GeometryShaderInput
{
    min16float4 pos     : SV_POSITION;
    min16float3 color   : COLOR0;
    uint instId         : TEXCOORD0;
};

// Per-vertex data passed to the rasterizer.
struct GeometryShaderOutput
{
    min16float4 pos     : SV_POSITION;
    min16float3 color   : COLOR0;
    uint rtvId          : SV_RenderTargetArrayIndex;
};

// This geometry shader is a pass-through that leaves the geometry unmodified 
// and sets the render target array index.
[maxvertexcount(3)]
void main(triangle GeometryShaderInput input[3], inout TriangleStream<GeometryShaderOutput> outStream)
{
    GeometryShaderOutput output;
    [unroll(3)]
    for (int i = 0; i < 3; ++i)
    {
        output.pos   = input[i].pos;
        output.color = input[i].color;
        output.rtvId = input[i].instId;
        outStream.Append(output);
    }
}

표시Present

Holographic 프레임을 사용 하 여 스왑 체인을 표시 합니다.Enable the holographic frame to present the swap chain

Windows Mixed Reality를 사용 하는 경우 시스템은 스왑 체인을 제어 합니다.With Windows Mixed Reality, the system controls the swap chain. 그러면 시스템에서 각 holographic 카메라에 대 한 프레임을 관리 하 여 고품질 사용자 환경을 보장 합니다.The system then manages presenting frames to each holographic camera to ensure a high-quality user experience. 또한 각 카메라에 대해 이미지 안정화 또는 혼합 현실 캡처와 같은 시스템 측면을 최적화 하기 위해 각 프레임을 업데이트 하는 뷰포트를 제공 합니다.It also provides a viewport update each frame, for each camera, to optimize aspects of the system such as image stabilization or Mixed Reality Capture. 따라서 DirectX를 사용 하는 holographic 앱은 DXGI 스왑 체인에 존재 하는을 호출 하지 않습니다.So, a holographic app using DirectX doesn't call Present on a DXGI swap chain. 대신 HolographicFrame 클래스를 사용 하 여 그리기를 완료 한 후 프레임에 대 한 모든 swapchain을 표시 합니다.Instead, you use the HolographicFrame class to present all swapchains for a frame once you're done drawing it.

DeviceResources::P 다시 보낸 위치:From DeviceResources::Present:

HolographicFramePresentResult presentResult = frame.PresentUsingCurrentPrediction();

기본적으로이 API는 프레임이 반환 될 때까지 대기 합니다.By default, this API waits for the frame to finish before it returns. Holographic apps는 새 프레임에서 작업을 시작 하기 전에 이전 프레임이 완료 될 때까지 기다려야 합니다 .이는 대기 시간을 줄이고 프레임 예측에서 더 나은 결과를 허용 하기 때문입니다.Holographic apps should wait for the previous frame to finish before starting work on a new frame, because this reduces latency and allows for better results from holographic frame predictions. 이것은 하드 규칙이 아니며, 렌더링을 위해 한 화면 새로 고침 보다 오랜 시간이 걸리는 프레임을 사용 하는 경우 HolographicFramePresentWaitBehavior 매개 변수를 PresentUsingCurrentPrediction에 전달 하 여이 대기를 비활성화할 수 있습니다.This isn't a hard rule, and if you have frames that take longer than one screen refresh to render you can disable this wait by passing the HolographicFramePresentWaitBehavior parameter to PresentUsingCurrentPrediction. 이 경우에는 비동기 렌더링 스레드를 사용 하 여 GPU에서 연속 로드를 유지 관리할 가능성이 높습니다.In this case, you would likely use an asynchronous rendering thread to maintain a continuous load on the GPU. HoloLens 장치의 새로 고침 빈도는 60 hz 이며, 한 프레임의 기간은 약 16 밀리초입니다.The refresh rate of the HoloLens device is 60 hz, where one frame has a duration of approximately 16 ms. 모던 헤드셋 장치는 60 hz에서 90 hz 사이에 있을 수 있습니다. 90 hz에서 디스플레이를 새로 고치면 각 프레임의 기간이 약 11 밀리초가 됩니다.Immersive headset devices can range from 60 hz to 90 hz; when refreshing the display at 90 hz, each frame will have a duration of approximately 11 ms.

HolographicFrame와 협력 하 여 DeviceLost 시나리오를 처리 합니다.Handle DeviceLost scenarios in cooperation with the HolographicFrame

DirectX 11 앱은 일반적으로 DeviceLost 오류가 있는지 확인 하기 위해 DXGI 스왑 체인의 present 함수에서 반환 된 HRESULT를 확인 하려고 합니다.DirectX 11 apps would typically want to check the HRESULT returned by the DXGI swap chain's Present function to find out if there was a DeviceLost error. HolographicFrame 클래스는이를 처리 합니다.The HolographicFrame class handles this for you. 반환 된 HolographicFramePresentResult 를 검사 하 여 Direct3D 장치 및 장치 기반 리소스를 해제 하 고 다시 만들어야 하는지 여부를 확인 합니다.Inspect the returned HolographicFramePresentResult to find out if you need to release and recreate the Direct3D device and device-based resources.

// The PresentUsingCurrentPrediction API will detect when the graphics device
// changes or becomes invalid. When this happens, it is considered a Direct3D
// device lost scenario.
if (presentResult == HolographicFramePresentResult::DeviceRemoved)
{
    // The Direct3D device, context, and resources should be recreated.
    HandleDeviceLost();
}

Direct3D 장치를 분실 하 고 다시 만든 경우 새 장치를 사용 하기 시작 하도록 HolographicSpace 에 지시 해야 합니다.If the Direct3D device was lost, and you did recreate it, you have to tell the HolographicSpace to start using the new device. 이 장치에 대해 스왑 체인이 다시 작성 됩니다.The swap chain will be recreated for this device.

From DeviceResources:: InitializeUsingHolographicSpace:From DeviceResources::InitializeUsingHolographicSpace:

m_holographicSpace.SetDirect3D11Device(m_d3dInteropDevice);

프레임이 표시 되 면 주 프로그램 루프로 돌아가서 다음 프레임으로 계속할 수 있습니다.Once your frame is presented, you can return back to the main program loop and allow it to continue to the next frame.

하이브리드 그래픽 Pc 및 혼합 현실 응용 프로그램Hybrid graphics PCs and mixed reality applications

Windows 10 크리에이터 업데이트 Pc는 개별 및 통합 Gpu를 모두 사용 하 여 구성할 수 있습니다.Windows 10 Creators Update PCs may be configured with both discrete and integrated GPUs. 이러한 유형의 컴퓨터를 사용 하 여 Windows는 헤드셋이 연결 된 어댑터를 선택 합니다.With these types of computers, Windows will choose the adapter the headset is connected to. 응용 프로그램에서 생성 하는 DirectX 장치가 동일한 어댑터를 사용 하는지 확인 해야 합니다.Applications must ensure the DirectX device it creates uses the same adapter.

가장 일반적인 Direct3D 샘플 코드는 하이브리드 시스템이 헤드셋에 사용 되는 것과 다를 수 있는 기본 하드웨어 어댑터를 사용 하 여 DirectX 장치를 만드는 방법을 보여 줍니다.Most general Direct3D sample code demonstrates creating a DirectX device using the default hardware adapter, which on a hybrid system may not be the same as the one used for the headset.

문제를 해결 하려면 HolographicSpaceHolographicAdapterID 를 사용 합니다. PrimaryAdapterId () 또는 HolographicDisplay. AdapterId ().To work around any issues, use the HolographicAdapterID from either HolographicSpace.PrimaryAdapterId() or HolographicDisplay.AdapterId(). 그런 다음이 adapterId를 사용 하 여 IDXGIFactory4 Adapterbyluid를 사용 하는 올바른 DXGIAdapter를 선택할 수 있습니다.This adapterId can then be used to select the right DXGIAdapter using IDXGIFactory4.EnumAdapterByLuid.

From DeviceResources:: InitializeUsingHolographicSpace:From DeviceResources::InitializeUsingHolographicSpace:

// The holographic space might need to determine which adapter supports
// holograms, in which case it will specify a non-zero PrimaryAdapterId.
LUID id =
{
    m_holographicSpace.PrimaryAdapterId().LowPart,
    m_holographicSpace.PrimaryAdapterId().HighPart
};

// When a primary adapter ID is given to the app, the app should find
// the corresponding DXGI adapter and use it to create Direct3D devices
// and device contexts. Otherwise, there is no restriction on the DXGI
// adapter the app can use.
if ((id.HighPart != 0) || (id.LowPart != 0))
{
    UINT createFlags = 0;

    // Create the DXGI factory.
    ComPtr<IDXGIFactory1> dxgiFactory;
    winrt::check_hresult(
        CreateDXGIFactory2(
            createFlags,
            IID_PPV_ARGS(&dxgiFactory)
        ));
    ComPtr<IDXGIFactory4> dxgiFactory4;
    winrt::check_hresult(dxgiFactory.As(&dxgiFactory4));

    // Retrieve the adapter specified by the holographic space.
    winrt::check_hresult(
        dxgiFactory4->EnumAdapterByLuid(
            id,
            IID_PPV_ARGS(&m_dxgiAdapter)
        ));
}
else
{
    m_dxgiAdapter.Reset();
}

Idxgid 어댑터를 사용 하 여 DeviceResources:: CreateDeviceResources를 업데이트 하는 코드Code to update DeviceResources::CreateDeviceResources to use IDXGIAdapter

// Create the Direct3D 11 API device object and a corresponding context.
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;

const D3D_DRIVER_TYPE driverType = m_dxgiAdapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
const HRESULT hr = D3D11CreateDevice(
    m_dxgiAdapter.Get(),        // Either nullptr, or the primary adapter determined by Windows Holographic.
    driverType,                 // Create a device using the hardware graphics driver.
    0,                          // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
    creationFlags,              // Set debug and Direct2D compatibility flags.
    featureLevels,              // List of feature levels this app can support.
    ARRAYSIZE(featureLevels),   // Size of the list above.
    D3D11_SDK_VERSION,          // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
    &device,                    // Returns the Direct3D device created.
    &m_d3dFeatureLevel,         // Returns feature level of device created.
    &context                    // Returns the device immediate context.
);

하이브리드 그래픽 및 미디어 파운데이션Hybrid graphics and Media Foundation

하이브리드 시스템에서 미디어 파운데이션를 사용 하면 미디어 파운데이션가 시스템 동작을 기본값으로 설정 하므로 비디오가 렌더링 되지 않거나 비디오 질감이 손상 되는 문제가 발생할 수 있습니다.Using Media Foundation on hybrid systems may cause issues where video won't render or video texture are corrupt because Media Foundation is defaulting to a system behavior. 일부 시나리오에서는 다중 스레딩을 지원 하기 위해 별도의 ID3D11Device를 만들어야 하며, 올바른 생성 플래그가 설정 됩니다.In some scenarios, creating a separate ID3D11Device is required to support multi-threading and the correct creation flags are set.

ID3D11Device를 초기화할 때 D3D11_CREATE_DEVICE_VIDEO_SUPPORT 플래그는 D3D11_CREATE_DEVICE_FLAG의 일부로 정의 해야 합니다.When initializing the ID3D11Device, D3D11_CREATE_DEVICE_VIDEO_SUPPORT flag must be defined as part of the D3D11_CREATE_DEVICE_FLAG. 장치 및 컨텍스트를 만든 후에는 Setmultithreadprotected 를 호출 하 여 다중 스레딩을 사용 하도록 설정 합니다.Once the device and context is created, call SetMultithreadProtected to enable multithreading. 장치를 IMFDXGIDeviceManager에 연결 하려면 IMFDXGIDeviceManager:: resetdevice 함수를 사용 합니다.To associate the device with the IMFDXGIDeviceManager, use the IMFDXGIDeviceManager::ResetDevice function.

ID3D11Device와 IMFDXGIDeviceManager를 연결 하는 코드:Code to associate a ID3D11Device with IMFDXGIDeviceManager:

// create dx device for media pipeline
winrt::com_ptr<ID3D11Device> spMediaDevice;

// See above. Also make sure to enable the following flags on the D3D11 device:
//   * D3D11_CREATE_DEVICE_VIDEO_SUPPORT
//   * D3D11_CREATE_DEVICE_BGRA_SUPPORT
if (FAILED(CreateMediaDevice(spAdapter.get(), &spMediaDevice)))
    return;                                                     

// Turn multithreading on 
winrt::com_ptr<ID3D10Multithread> spMultithread;
if (spContext.try_as(spMultithread))
{
    spMultithread->SetMultithreadProtected(TRUE);
}

// lock the shared dxgi device manager
// call MFUnlockDXGIDeviceManager when no longer needed
UINT uiResetToken;
winrt::com_ptr<IMFDXGIDeviceManager> spDeviceManager;
hr = MFLockDXGIDeviceManager(&uiResetToken, spDeviceManager.put());
if (FAILED(hr))
    return hr;
    
// associate the device with the manager
hr = spDeviceManager->ResetDevice(spMediaDevice.get(), uiResetToken);
if (FAILED(hr))
    return hr;

참고 항목See also