Configuración de la funcionalidad de Depth-Stencil

En esta sección se describen los pasos para configurar el búfer de galería de símbolos de profundidad y el estado de galería de símbolos de profundidad para la fase de fusión de salida.

Una vez que sepa cómo usar el búfer de galería de símbolos de profundidad y el estado de galería de símbolos de profundidad correspondiente, consulte técnicas avanzadas de galería de símbolos.

Creación de un recurso de Depth-Stencil

Cree el búfer de galería de símbolos de profundidad mediante un recurso de textura.

ID3D11Texture2D* pDepthStencil = NULL;
D3D11_TEXTURE2D_DESC descDepth;
descDepth.Width = backBufferSurfaceDesc.Width;
descDepth.Height = backBufferSurfaceDesc.Height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = pDeviceSettings->d3d11.AutoDepthStencilFormat;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = pd3dDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil );

Crear estado de Depth-Stencil

El estado de la galería de símbolos de profundidad indica a la fase de fusión de salida cómo realizar la prueba de galería de símbolos de profundidad. La prueba de galería de símbolos de profundidad determina si se debe dibujar o no un píxel determinado.

D3D11_DEPTH_STENCIL_DESC dsDesc;

// Depth test parameters
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;

// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;

// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// Create depth stencil state
ID3D11DepthStencilState * pDSState;
pd3dDevice->CreateDepthStencilState(&dsDesc, &pDSState);

DepthEnable y StencilEnable habilitar (y deshabilitar) pruebas de profundidad y galería de símbolos. Establezca DepthEnable en FALSE para deshabilitar las pruebas de profundidad y evitar la escritura en el búfer de profundidad. Establezca StencilEnable en FALSE para deshabilitar las pruebas de galería de símbolos y evitar la escritura en el búfer de galería de símbolos (cuando DepthEnable es FALSE y StencilEnable es TRUE, la prueba de profundidad siempre pasa en la operación de galería de símbolos).

DepthEnable solo afecta a la fase de fusión de salida: no afecta al recorte, al sesgo de profundidad ni a la fijación de valores antes de que los datos se introduzcan en un sombreador de píxeles.

Enlazar datos Depth-Stencil a la fase de OM

Enlace el estado de la galería de símbolos de profundidad.

// Bind depth stencil state
pDevice->OMSetDepthStencilState(pDSState, 1);

Enlace el recurso de galería de símbolos de profundidad mediante una vista.

D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
descDSV.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;

// Create the depth stencil view
ID3D11DepthStencilView* pDSV;
hr = pd3dDevice->CreateDepthStencilView( pDepthStencil, // Depth stencil texture
                                         &descDSV, // Depth stencil desc
                                         &pDSV );  // [out] Depth stencil view

// Bind the depth stencil view
pd3dDeviceContext->OMSetRenderTargets( 1,          // One rendertarget view
                                &pRTV,      // Render target view, created earlier
                                pDSV );     // Depth stencil view for the render target

Una matriz de vistas de destino de representación se puede pasar a ID3D11DeviceContext::OMSetRenderTargets, pero todas esas vistas de destino de representación se corresponderán con una sola vista de galería de símbolos de profundidad. La matriz de destino de representación en Direct3D 11 es una característica que permite que una aplicación se represente en varios destinos de representación simultáneamente en el nivel primitivo. Las matrices de destino de representación ofrecen un mayor rendimiento sobre la configuración individual de destinos de representación con varias llamadas a ID3D11DeviceContext::OMSetRenderTargets (básicamente el método empleado en Direct3D 9).

Los destinos de representación deben ser el mismo tipo de recurso. Si se usa el suavizado multimuestrado, todos los destinos de representación enlazados y los búferes de profundidad deben tener los mismos recuentos de muestras.

Cuando se usa un búfer como destino de representación, no se admiten pruebas de galería de símbolos de profundidad y varios destinos de representación.

  • Hasta 8 destinos de representación se pueden enlazar simultáneamente.
  • Todos los destinos de representación deben tener el mismo tamaño en todas las dimensiones (ancho y alto, y profundidad para el tamaño de matriz o 3D para *Tipos de matriz).
  • Cada destino de representación puede tener un formato de datos diferente.
  • Las máscaras de escritura controlan qué datos se escriben en un destino de representación. El control de máscaras de escritura de salida en un destino por representación, por componente, qué datos se escriben en los destinos de representación.

Técnicas avanzadas de galería de símbolos

La parte de galería de símbolos del búfer de galería de símbolos de profundidad se puede usar para crear efectos de representación, como la composición, el escalado y la esquematización.

Composición

La aplicación puede usar el búfer de galería de símbolos para componer imágenes 2D o 3D en una escena 3D. Se usa una máscara en el búfer de galería de símbolos para ocluir un área de la superficie de destino de representación. La información almacenada en 2D, como texto o mapas de bits, se puede escribir en el área ocluida. Como alternativa, la aplicación puede representar primitivos 3D adicionales en la región enmascarada de galería de símbolos de la superficie de destino de representación. Incluso puede representar una escena completa.

Los juegos suelen componer varias escenas 3D juntas. Por ejemplo, los juegos de conducción suelen mostrar un espejo retrovisor. El reflejo contiene la vista de la escena 3D detrás del controlador. Básicamente, es una segunda escena 3D compuesta con la vista hacia delante del controlador.

Escalado

Las aplicaciones de Direct3D usan el escalado para controlar qué píxeles de una imagen primitiva determinada se dibujan en la superficie de destino de representación. Las aplicaciones aplican calcales a las imágenes de primitivos para permitir que los polígonos coplanares se representen correctamente.

Por ejemplo, al aplicar marcas de neumáticos y líneas amarillas a una carretera, las marcas deben aparecer directamente en la parte superior de la carretera. Sin embargo, los valores z de las marcas y la carretera son los mismos. Por lo tanto, es posible que el búfer de profundidad no genere una separación limpia entre los dos. Algunos píxeles de la primitiva posterior se pueden representar en la parte superior del primitivo frontal y viceversa. La imagen resultante parece brillar de marco a fotograma. Este efecto se denomina z-fighting o flimmering.

Para resolver este problema, use una galería de símbolos para enmascarar la sección del primitivo posterior donde aparecerá el calcedo. Desactive el almacenamiento en búfer z y represente la imagen del primitivo frontal en el área enmascarada de la superficie de destino de representación.

Se pueden usar varias mezclas de texturas para resolver este problema.

Contornos y siluetas

Puede usar el búfer de galería de símbolos para obtener más efectos abstractos, como esquematización y silhouetting.

Si la aplicación realiza dos pases de representación: uno para generar la máscara de galería de símbolos y el segundo para aplicar la máscara de galería de símbolos a la imagen, pero con los primitivos ligeramente más pequeños en el segundo paso, la imagen resultante contendrá solo el contorno del primitivo. Después, la aplicación puede rellenar el área enmascarada de la galería de símbolos de la imagen con un color sólido, lo que proporciona al primitivo un aspecto en relieve.

Si la máscara de galería de símbolos tiene el mismo tamaño y forma que el primitivo que se va a representar, la imagen resultante contiene un agujero donde debe estar el primitivo. Después, la aplicación puede rellenar el agujero con negro para producir una silueta del primitivo.

galería de símbolos de Two-Sided

Los volúmenes de sombra se usan para dibujar sombras con el búfer de galería de símbolos. La aplicación calcula los volúmenes de sombra que se convierten al ocultar la geometría, calculando los bordes de la silueta y extruyéndolas lejos de la luz en un conjunto de volúmenes 3D. Estos volúmenes se representan dos veces en el búfer de galería de símbolos.

La primera representación dibuja polígonos orientados hacia delante e incrementa los valores del búfer de galería de símbolos. La segunda representación dibuja los polígonos orientados hacia atrás del volumen de sombras y disminuye los valores del búfer de galería de símbolos. Normalmente, todos los valores incrementados y decrementados se cancelan entre sí. Sin embargo, la escena ya se ha representado con geometría normal, lo que hace que algunos píxeles produzcan un error en la prueba del búfer z cuando se represente el volumen de sombras. Los valores que quedan en el búfer de galería de símbolos corresponden a píxeles que están en la sombra. Estos contenidos restantes del búfer de galería de símbolos se usan como máscara, para mezclar alfa un cuadrante negro grande y abarcado en la escena. Con el búfer de galería de símbolos que actúa como máscara, el resultado es oscurecer píxeles que están en las sombras.

Esto significa que la geometría de sombra se dibuja dos veces por fuente de luz, por lo que presiona el rendimiento del vértice de la GPU. La característica de galería de símbolos de dos caras se ha diseñado para mitigar esta situación. En este enfoque, hay dos conjuntos de estados de galería de símbolos (denominados a continuación), uno establecido cada uno para los triángulos frontales y el otro para los triángulos orientados hacia atrás. De este modo, solo se dibuja un solo paso por volumen de sombras, por luz.

Puede encontrar un ejemplo de implementación de galería de símbolos en el ejemplo ShadowVolume10.

Leer el búfer de Depth-Stencil como una textura

Un sombreador puede leer un búfer de galería de símbolos de profundidad inactivo como textura. Una aplicación que lee un búfer de galería de símbolos de profundidad como textura se representa en dos pasos, el primer paso escribe en el búfer de galería de símbolos de profundidad y el segundo paso lee del búfer. Esto permite que un sombreador compare los valores de profundidad o galería de símbolos escritos previamente en el búfer con el valor del píxel que se representa de forma currrent. El resultado de la comparación se puede usar para crear efectos como la asignación de sombras o partículas suaves en un sistema de partículas.

Para crear un búfer de galería de símbolos de profundidad que se puede usar como un recurso de galería de símbolos de profundidad y un recurso de sombreador, es necesario realizar algunos cambios en el código de ejemplo en la sección Crear un recurso de Depth-Stencil .

  • El recurso de galería de símbolos de profundidad debe tener un formato sin tipo, como DXGI_FORMAT_R32_TYPELESS.

    descDepth.Format = DXGI_FORMAT_R32_TYPELESS;
    
  • El recurso de galería de símbolos de profundidad debe usar las marcas de enlace D3D10_BIND_DEPTH_STENCIL y D3D10_BIND_SHADER_RESOURCE.

    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
    

Además, es necesario crear una vista de recursos del sombreador para el búfer de profundidad mediante una estructura de D3D11_SHADER_RESOURCE_VIEW_DESC e ID3D11Device::CreateShaderResourceView. La vista de recursos del sombreador usará un formato con tipo, como DXGI_FORMAT_R32_FLOAT equivalente al formato sin tipo especificado cuando se creó el recurso de galería de símbolos de profundidad.

En el primer paso de representación, el búfer de profundidad se enlaza como se describe en la sección Enlazar datos Depth-Stencil a la fase de OM . Tenga en cuenta que el formato pasado a D3D11_DEPTH_STENCIL_VIEW_DESC. El formato usará un formato con tipo como DXGI_FORMAT_D32_FLOAT. Una vez que la primera representación pase el búfer de profundidad contendrá los valores de profundidad de la escena.

En la segunda representación, se usa la función ID3D11DeviceContext::OMSetRenderTargets para establecer la vista de galería de símbolos de profundidad en NULL o en un recurso de galería de símbolos de profundidad diferente y la vista de recursos del sombreador se pasa al sombreador mediante ID3D11EffectShaderResourceVariable::SetResource. Esto permite al sombreador buscar los valores de profundidad calculados en el primer paso de representación. Tenga en cuenta que es necesario aplicar una transformación para recuperar valores de profundidad si el punto de vista del primer paso de representación es diferente del segundo paso de representación. Por ejemplo, si se usa una técnica de asignación de sombras, el primer paso de representación será desde la perspectiva de una fuente de luz, mientras que el segundo paso de representación se realizará desde la perspectiva del visor.

Fase de fusión de salida

Fases de canalización (Direct3D 10)