Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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.
- Creación de un recurso de Depth-Stencil
- Creación de un estado de Depth-Stencil
- Vincular datos de Depth-Stencil a la etapa OM
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 de galería de símbolos avanzadas.
Crear un recurso Depth-Stencil
Cree el búfer de profundidad-esténcil 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 );
Creación de un 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 profundidad y plantilla 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 habilitan (y deshabilitan) pruebas de profundidad y de esténcil. 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 stencil y evitar la escritura en el búfer de stencil (cuando DepthEnable es FALSE y StencilEnable es TRUE, la prueba de profundidad siempre pasa en la operación de stencil).
DepthEnable solo afecta a la fase de fusión de salida: no afecta al recorte, el sesgo de profundidad ni la fijación de valores antes de que los datos se introduzcan en un sombreador de píxeles.
Enlazar los datos de Depth-Stencil a la etapa de OM
Vincule el estado de profundidad y plantilla.
// Bind depth stencil state
pDevice->OMSetDepthStencilState(pDSState, 1);
Enlace el recurso depth-stencil 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
Se puede pasar una matriz de vistas de destino de representación a ID3D11DeviceContext::OMSetRenderTargets; sin embargo, todas esas vistas de destino de representación se corresponderán con una sola vista de plantilla 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 multisample, todos los destinos de representación enlazados y los búferes de profundidad deben tener la misma cantidad de muestras.
Cuando se utiliza un búfer como destino de renderización, no se admiten las pruebas de profundidad-esténcil ni los múltiples destinos de renderización.
- Se pueden enlazar hasta 8 objetivos de representación simultáneamente.
- Todos los destinos de representación deben tener el mismo tamaño en todas las dimensiones (ancho y alto, y profundidad para 3D o tamaño de matriz para *tipos de array).
- Cada destino de representación puede tener un formato de datos diferente.
- Las máscaras de escritura controlan qué datos se escriben en un objetivo de renderizado. El control de las máscaras de escritura de salida determina, para cada objetivo de renderizado y cada componente, qué datos se escriben en los objetivos de renderizado.
Técnicas avanzadas de plantillas
La parte de plantilla del búfer de profundidad y plantilla se puede usar para crear efectos de representación como la composición, la aplicación de decalcomanías, y la delimitación.
- Composición
- Calcomanía
- contornos y siluetas
- Two-Sided Plantilla
- Leer el búfer de Depth-Stencil como textura
Composición
Tu aplicación puede usar el búfer de esténcil para componer imágenes 2D o 3D en una escena 3D. Se usa una máscara en el búfer de esténcil para ocluir un área de la superficie de destino de renderizado. La información almacenada en 2D, como texto o mapas de bits, puede escribirse en el área ocluida. Como alternativa, su aplicación puede representar primitivos 3D adicionales en la región enmascarada de la superficie de destino de la 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 espejo contiene la vista de la escena 3D detrás del conductor. Básicamente, es una segunda escena 3D compuesta con la vista hacia delante del controlador.
Escalado
Las aplicaciones Direct3D usan el decalado para controlar qué píxeles de una imagen primitiva determinada se dibujan en la superficie de destino de renderización. Las aplicaciones aplican adhesivos 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 del marco al marco. Este efecto se denomina "z-fighting" o "flimmering".
Para resolver este problema, use una plantilla para enmascarar la sección trasera del primitivo donde aparecerá la calcomanía. Desactive el z-buffer y renderice la imagen del primitivo frontal en el área enmascarada de la superficie de destino del renderizado.
Se pueden usar varias mezclas de texturas para resolver este problema.
Contornos y siluetas
Puede utilizar el búfer de plantilla para obtener efectos más abstractos, como esquematización y silueteado.
Si la aplicación realiza dos pasos 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 solo contendrá el contorno del primitivo. A continuación, la aplicación puede rellenar el área enmascarada por la plantilla de la imagen con un color sólido, lo que le da al primitivo un aspecto en relieve.
Si la máscara de estarcido tiene el mismo tamaño y forma que el primitivo que está renderizando, la imagen resultante contiene un agujero donde debería estar el primitivo. Su 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 esténcil. La aplicación calcula los volúmenes de sombra proyectados por la geometría que oculta, al determinar los bordes de la silueta y extruyéndolos hacia un conjunto de volúmenes 3D alejados de la luz. Estos volúmenes se representan dos veces en el búfer de plantillas.
La primera representación dibuja polígonos orientados hacia delante e incrementa los valores del búfer de plantillas. La segunda representación dibuja los polígonos orientados hacia atrás del volumen de sombras y disminuye los valores del búfer de plantilla. Normalmente, todos los valores incrementados y reducidos se cancelan entre sí. Sin embargo, la escena ya se ha representado con geometría normal, lo que provoca que algunos píxeles produzcan un error en la prueba del búfer z, ya que se representa el volumen de sombras. Los valores que quedan en el búfer de plantilla corresponden a píxeles que están en la sombra. Estos contenidos restantes del búfer de esténcil se usan como máscara, para hacer una mezcla alfa de un gran cuadro negro que abarca toda la escena. Con el búfer de plantilla actuando como máscara, el resultado es oscurecer los píxeles que están en las sombras.
Esto significa que la geometría de sombra se dibuja dos veces por fuente de luz, lo que pone presión sobre el rendimiento del vértice de la GPU. La característica de plantilla de dos caras se ha diseñado para mitigar esta situación. En este enfoque, hay dos conjuntos de estado de plantilla (denominados a continuación), uno para los triángulos frontales y el otro para los triángulos traseros. De este modo, solo se dibuja un único paso por volumen de sombras, por cada luz.
Puede encontrar un ejemplo de implementación de plantilla de dos caras en el ejemplo ShadowVolume10.
Lectura del búfer de Depth-Stencil como textura
Un búfer de profundidad y plantilla inactivo puede ser leído por un sombreador como una textura. Una aplicación que lee un búfer de profundidad-esténcil como textura se procesa en dos pasos: el primer paso escribe en el búfer de profundidad-esténcil y el segundo paso lee del búfer. Esto permite que un sombreador compare los valores de profundidad o plantilla previamente escritos en el búfer con el valor del píxel que se está procesando actualmente. 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 profundidad-esténcil debe usar los flags 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 usando una estructura D3D11_SHADER_RESOURCE_VIEW_DESC y ID3D11Device::CreateShaderResourceView. La vista de recursos del sombreador usará un formato con tipo, como DXGI_FORMAT_R32_FLOAT que es el equivalente al formato sin tipo especificado cuando se creó el recurso de galería de símbolos de profundidad.
En el primer paso de renderizado, el búfer de profundidad se vincula, tal y como se describe en la sección Vincular datos Depth-Stencil a la etapa 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. Después de la primera pasada de renderizado, el búfer de profundidad contendrá los valores de profundidad de la escena.
En el segundo paso de representación, se usa la función ID3D11DeviceContext::OMSetRenderTargets para establecer la vista de profundidad y plantilla en NULL o en un diferente recurso de profundidad y plantilla, y la vista de recursos del sombreador se pasa al sombreador mediante ID3D11EffectShaderResourceVariable::SetResource. Esto permite que el sombreador busque los valores de profundidad calculados en el primer paso de renderizado. 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 será desde la perspectiva del visor.
Temas relacionados