<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang=""><title type="html">jcanton</title><subtitle type="html">Code Line by Code Line</subtitle><id>http://geeks.ms/blogs/jcanton/atom.aspx</id><link rel="alternate" type="text/html" href="http://geeks.ms/blogs/jcanton/default.aspx" /><link rel="self" type="application/atom+xml" href="http://geeks.ms/blogs/jcanton/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2010-01-10T19:21:00Z</updated><entry><title>Wave Engine ya está disponible</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2013/02/23/wave-engine-ya-est-225-disponible.aspx" /><id>/blogs/jcanton/archive/2013/02/23/wave-engine-ya-est-225-disponible.aspx</id><published>2013-02-23T19:16:17Z</published><updated>2013-02-23T19:16:17Z</updated><content type="html">Este jueves por fin lanzamos WaveEngine (waveengine.net) tras más de dos años de desarrollo. Creo que es un proyecto muy interesante para desarrolladores C# por lo que os animo a todos a probarlo y darnos feedback para continuar mejorándolo. A continuación para motivaros a probarlo os voy a contar rápidamente algunas API highlights del proyecto, las cuales desde mi punto de vista son bastantes atractivas e interesantes para desarrollados en C#. WaveEngine ha sido diseñado bajo los principios de Component...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2013/02/23/wave-engine-ya-est-225-disponible.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208656" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Entrevista para la Newsletter de Visual Studio</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2012/12/13/entrevista-para-la-newsletter-de-visual-studio.aspx" /><id>/blogs/jcanton/archive/2012/12/13/entrevista-para-la-newsletter-de-visual-studio.aspx</id><published>2012-12-13T19:39:00Z</published><updated>2012-12-13T19:39:00Z</updated><content type="html">Javier Cant&amp;oacute;n lleva vinculado a Microsoft los &amp;uacute;ltimos 10 a&amp;ntilde;os. Reconocido MVP experto en tecnolog&amp;iacute;as como DirectX y XNA centradas en el desarrollo de Videojuegos y tratamiento de im&amp;aacute;genes, ha centrado parte de su trabajo y carrera profesional en el mundo del desarrollo vincul&amp;aacute;ndose con las &amp;uacute;ltimas tecnolog&amp;iacute;as del entretenimiento. Licenciado en Ingenier&amp;iacute;a Inform&amp;aacute;tica y especializado en el tratamiento y procesamiento de im&amp;aacute;genes...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2012/12/13/entrevista-para-la-newsletter-de-visual-studio.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207610" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Memoria compartida entre C# struct</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2012/07/15/memoria-compartida-entre-c-struct.aspx" /><id>/blogs/jcanton/archive/2012/07/15/memoria-compartida-entre-c-struct.aspx</id><published>2012-07-15T21:59:53Z</published><updated>2012-07-15T21:59:53Z</updated><content type="html">&amp;#160; Problemática: Imaginemos que estamos desarrollando un graphics ó physics engine en C#, el cual queremos que sea multiplataformas por lo que luego lo usaremos contra diferentes APIs como XNA, OpenTK y SharpDX. Trabajaremos con nuestras propias estructuras para Matrix4x4 ó Vector3 por ejemplo y luego las tendremos que traducir a las structs concretas de cada API. &amp;#160; La struct para Vector3 de nuestro motor puede ser tan simple como: public struct Vector { &amp;#160;&amp;#160;&amp;#160; public float X;...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2012/07/15/memoria-compartida-entre-c-struct.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=206097" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Windows Phone 7" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Windows+Phone+7/default.aspx" /><category term="Performance" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Performance/default.aspx" /><category term="Struct" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Struct/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jcanton/archive/tags/C_2300_/default.aspx" /></entry><entry><title>WP7 Problemas de rendimiento con Struct (II / II)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/11/09/wp7-problemas-de-rendimiento-con-struct-ii-ii.aspx" /><id>/blogs/jcanton/archive/2011/11/09/wp7-problemas-de-rendimiento-con-struct-ii-ii.aspx</id><published>2011-11-09T21:14:00Z</published><updated>2011-11-09T21:14:00Z</updated><content type="html">Realicemos un peque&amp;ntilde;o benchmark para poder evaluar cual es la p&amp;eacute;rdida de rendimiento obtenido, el cual se producir&amp;aacute; por: CPU: Tiempo empleado en gestionar las llamadas (realizar las copias de las estructuras) Para el test vamos a crear un proyecto para Windows Phone 7.1 con Visual Studio, y luego lo analizaremos con el profiler de WP7 corriendo directamente en un dispositivo real. La demo ser&amp;aacute; muy simple, colocaremos un bucle en el m&amp;eacute;todo Draw que es donde m&amp;aacute;s...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/11/09/wp7-problemas-de-rendimiento-con-struct-ii-ii.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201608" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Windows Phone 7" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Windows+Phone+7/default.aspx" /><category term="Performance" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Performance/default.aspx" /></entry><entry><title>WP7 Problemas de rendimiento con Struct (I / II)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/11/09/wp7-problemas-de-rendimiento-con-struct-i-ii.aspx" /><id>/blogs/jcanton/archive/2011/11/09/wp7-problemas-de-rendimiento-con-struct-i-ii.aspx</id><published>2011-11-09T21:11:54Z</published><updated>2011-11-09T21:11:54Z</updated><content type="html">Recientemente he pasado bastantes horas optimizando código para Windows Phone 7, y una de las primeras cosas que hay que tener en mente es que el CLR(Common Language Runtime) de WP7 no es el de Windows. Incluso en la última versión (Mango) en la que han hecho grandes mejoras, como por ejemplo que ahora el GC (Garbage Collector) ofrece un rendimiento más decente con 2 generaciones, o como al aprovechamiento de las instrucciones SIMD. Otro factor a tener en cuenta para todos esos desarrolladores que...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/11/09/wp7-problemas-de-rendimiento-con-struct-i-ii.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201607" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Windows Phone 7" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Windows+Phone+7/default.aspx" /><category term="Performance" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Performance/default.aspx" /></entry><entry><title>Wave Engine</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/09/16/wave-engine.aspx" /><id>/blogs/jcanton/archive/2011/09/16/wave-engine.aspx</id><published>2011-09-16T18:27:00Z</published><updated>2011-09-16T18:27:00Z</updated><content type="html">Buenas, Hoy es un gran d&amp;iacute;a para volver a escribir en el Blog, tras casi un a&amp;ntilde;o trabajando en Plain Concepts donde he conocido a gente muy grande y de la que he aprendido mucho, hoy hacemos p&amp;uacute;blico un v&amp;iacute;deo en el que se puede ver Bye Bye Brain App-ocalypse corriendo sobre Wave Engine en el que hemos estado trabajando durante tantos meses, el cual permite desarrollar juegos de forma productiva para m&amp;uacute;ltiples plataformas. A pesar de que a&amp;uacute;n no nos dejan desvelar...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/09/16/wave-engine.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200562" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="Windows Phone 7" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Windows+Phone+7/default.aspx" /><category term="Plain Concepts Games" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Plain+Concepts+Games/default.aspx" /><category term="Weekend" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Weekend/default.aspx" /><category term="IPad" scheme="http://geeks.ms/blogs/jcanton/archive/tags/IPad/default.aspx" /><category term="IPhone" scheme="http://geeks.ms/blogs/jcanton/archive/tags/IPhone/default.aspx" /><category term="Wave Engine" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Wave+Engine/default.aspx" /></entry><entry><title>Occlusion Culling (IV de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/03/12/occlusion-culling-iv-de-iv.aspx" /><id>/blogs/jcanton/archive/2011/03/12/occlusion-culling-iv-de-iv.aspx</id><published>2011-03-12T10:46:08Z</published><updated>2011-03-12T10:46:08Z</updated><content type="html">************************************************************************************************ - Back-face culling - Frustum Culling - Occlusion Culling - Optimizaciones para el Occlusion Culling ************************************************************************************************ En el post anterior explicamos los principios básicos del occlusión culling, y este último post lo dedicaremos a la implementación de dicha técnica de forma eficiente.&amp;#160; Recordemos rápidamente en que consistía...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/03/12/occlusion-culling-iv-de-iv.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=190268" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Occlusion Culling (III de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/02/27/occlusion-culling-iii-de-iv.aspx" /><id>/blogs/jcanton/archive/2011/02/27/occlusion-culling-iii-de-iv.aspx</id><published>2011-02-27T20:08:00Z</published><updated>2011-02-27T20:08:00Z</updated><content type="html">************************************************************************************************ - Back-face culling - Frustum Culling - Occlusion Culling - Optimizaciones para el Occlusion Culling ************************************************************************************************ Por fin toca escribir sobre la técnica que puso nombre a esta serie de artículos XD, Occlusión Culling también es una técnica que podemos incluir dentro de los algoritmos de visibilidad, esta técnica intenta...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/02/27/occlusion-culling-iii-de-iv.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=189666" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Occlusion Culling (II de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/02/13/occlusion-culling-ii-de-iv.aspx" /><id>/blogs/jcanton/archive/2011/02/13/occlusion-culling-ii-de-iv.aspx</id><published>2011-02-13T20:31:57Z</published><updated>2011-02-13T20:31:57Z</updated><content type="html">************************************************************************************************ - Back-face culling - Frustum Culling - Occlusion Culling - Optimizaciones para el Occlusion Culling ************************************************************************************************ Frustum Culling : Es otra de las técnicas de visibilidad más usadas ya que es muy simple de implementar, consiste en no enviar a la tarjeta gráfica aquellos objetos que queden fuera del volumen de render de...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/02/13/occlusion-culling-ii-de-iv.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=188908" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Occlusion Culling (I de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2011/02/06/occlusion-culling.aspx" /><id>/blogs/jcanton/archive/2011/02/06/occlusion-culling.aspx</id><published>2011-02-06T19:25:12Z</published><updated>2011-02-06T19:25:12Z</updated><content type="html">************************************************************************************************ - Back-face culling - Frustum Culling - Occlusion Culling - Optimizaciones para el Occlusion Culling ************************************************************************************************ Hacía tiempo que no escribía y me alegra que el regreso sea con un tema tan interesante como el Occlusion Culling. Esta técnica podríamos clasificarla dentro de las técnicas de visibilidad para mejorar el rendimiento...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2011/02/06/occlusion-culling.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=188486" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Simular el acelerómetro de Windows Phone 7</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/08/11/simular-el-aceler-243-metro-de-windows-phone-7.aspx" /><id>/blogs/jcanton/archive/2010/08/11/simular-el-aceler-243-metro-de-windows-phone-7.aspx</id><published>2010-08-11T19:10:00Z</published><updated>2010-08-11T19:10:00Z</updated><content type="html">Con la llegada de XNA 4.0 y el soporte para los nuevos tel&amp;eacute;fonos la API nos da acceso a una parte muy usada para el desarrollo de juegos en los tel&amp;eacute;fonos, el aceler&amp;oacute;metro, el problema es que al no tener a&amp;uacute;n los dispositivos f&amp;iacute;sicos (ya que saldr&amp;aacute;n en Septiembre-Octubre) y que el emulador que se ha proporcionado para Visual Studio 2010 tampoco nos permite emularlo, muchos desarrolladores nos encontramos limitados a la hora de crear proyectos que usen el aceler&amp;oacute;metro...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/08/11/simular-el-aceler-243-metro-de-windows-phone-7.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=180550" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Accelerometer" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Accelerometer/default.aspx" /><category term="Windows Phone 7" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Windows+Phone+7/default.aspx" /></entry><entry><title>Evento XNA 4.0 &amp; Windows Phone 7</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/05/06/evento-xna-4-0-y-windows-phone-7.aspx" /><id>/blogs/jcanton/archive/2010/05/06/evento-xna-4-0-y-windows-phone-7.aspx</id><published>2010-05-06T08:17:00Z</published><updated>2010-05-06T08:17:00Z</updated><content type="html">Actualmente me encuentro colaborando con personas de Microsoft como Isabel Gomez Miragaya en las presentaciones de Windows Phone 7 en Espa&amp;ntilde;a. El 28 de Mayo estaremos en Barcelona en un evento sobre Windows Phone 7 pero que lo centraremos en el desarrollo de videojuegos con XNA 4.0, dejo aqu&amp;iacute; m&amp;aacute;s informaci&amp;oacute;n: Windows Phone 7 Developer Hub: Desarrolla juegos para Windows Phone 7 con XNA 28 de Mayo, Hotel Barcelo Sants, Barcelona Durante este evento descubrir&amp;eacute;is la...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/05/06/evento-xna-4-0-y-windows-phone-7.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=176359" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="Multitouch" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Multitouch/default.aspx" /><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Graphics" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Graphics/default.aspx" /><category term="Evento" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Evento/default.aspx" /></entry><entry><title>XNA Graphics Pipeline</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/04/01/xna-graphics-pipeline.aspx" /><id>/blogs/jcanton/archive/2010/04/01/xna-graphics-pipeline.aspx</id><published>2010-04-01T00:20:00Z</published><updated>2010-04-01T00:20:00Z</updated><content type="html">Si queremos extraerle el máximo partido gráfico a XNA usando HLSL es importante conocer el pipeline gráfico usado por este framework: Cada uno de estos “módulos” cumplen un papel especial hasta conseguir pintar un objeto en pantalla, ya sea un modelo 3D ó una imagen 2D (la cual es pintada sobre un quad “anclado” a la pantalla). Veamos que se hace en cada uno de estos “módulos”: Vertex Data: Contiene un buffer de vértices sin transformar indexado o no indexado, es posible indicar mediante VertexDeclaration...(&lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/04/01/xna-graphics-pipeline.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=171803" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="Shaders" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Shaders/default.aspx" /><category term="HLSL" scheme="http://geeks.ms/blogs/jcanton/archive/tags/HLSL/default.aspx" /><category term="Render" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Render/default.aspx" /><category term="Graphics" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Graphics/default.aspx" /></entry><entry><title>HLSL, Un poco de historia</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/03/11/hlsl-un-poco-de-historia.aspx" /><id>/blogs/jcanton/archive/2010/03/11/hlsl-un-poco-de-historia.aspx</id><published>2010-03-11T09:30:00Z</published><updated>2010-03-11T09:30:00Z</updated><content type="html">&lt;p&gt;HLSL (High Level Shader Language) es el lenguaje desarrollado por Microsoft con el que podemos programar efectos gr&amp;aacute;ficos mediante DirectX para que sean ejecutados por la GPU (Graphics Processor Unit) situada en nuestras actuales tarjetas gr&amp;aacute;ficas, con el se pueden aplicar efectos gr&amp;aacute;ficos tan impresionantes como:&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Faces_5F00_057BAF3A.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Faces" alt="Faces" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Faces_5F00_thumb_5F00_4177CB22.png" border="0" height="283" width="404" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Pero como se ha llegado hasta todo esto que hoy conocemos y nos es tan com&amp;uacute;n, pues todo empez&amp;oacute; en 1995 con la salida de la primera tarjeta aceleradora gr&amp;aacute;fica 3D para consumo dom&amp;eacute;stico lanzada por la en aquellos tiempos empresa llamada 3Dfx, estoy convencido que todos recordar&amp;eacute;is los inicios y lo que supon&amp;iacute;a arrancar un juego con y sin que apareciese este logo al arrancar:&lt;/p&gt;
&lt;div style="padding:0px;width:425px;display:block;float:none;margin-left:auto;margin-right:auto;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:530db290-ec48-47c5-9e4b-b4ad12af580f" class="wlWriterEditableSmartContent"&gt;
&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=QY-LrdhHylU" target="_new"&gt;(Por favor, visita la web para ver este medio)&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;La 3Dfx Voodoo Card fue la primera por aquellos tiempos uno necesitaba una tarjeta gr&amp;aacute;fica 2D y una tarjeta aceleradora de gr&amp;aacute;ficos 3D, finalmente esto se fue unificando en una sola tarjeta y las llamadas tarjetas aceleradoras pasaron a ser nuestras tarjetas gr&amp;aacute;ficas 2D y 3D. Estas tarjetas provocaron una revoluci&amp;oacute;n en el mundo de los videojuegos aunque sus posibilidades eran muy limitadas, se empez&amp;oacute; a pensar en trasladar gran parte del c&amp;aacute;lculo especifico en los videojuegos de la CPU hacia la GPU. &lt;/p&gt;
&lt;p&gt;El pr&amp;oacute;ximo salto lo dio Nvidia con el lanzamiento de la GeForce 256 la cual liberaba a la CPU del c&amp;aacute;lculo de transformaci&amp;oacute;n e iluminaci&amp;oacute;n (Transform &amp;amp; Lighting) y permit&amp;iacute;a por tanto tener much&amp;iacute;simos m&amp;aacute;s objetos en pantalla iluminados al realizar esta operaci&amp;oacute;n por hardware:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/TL_5F00_0A3E175C.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="T&amp;amp;L" alt="T&amp;amp;L" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/TL_5F00_thumb_5F00_016E0F10.jpg" border="0" height="236" width="304" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;div style="padding:0px;width:425px;display:block;float:none;margin-left:auto;margin-right:auto;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:187b8565-5f08-4298-95fa-8848380e4ca6" class="wlWriterEditableSmartContent"&gt;
&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=KYiGEcjMiF4" target="_new"&gt;(Por favor, visita la web para ver este medio)&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Hubo una segunda generaci&amp;oacute;n basada en esto introducida en el mercado por Nvidia a partir de su GeForce 2 y ATI con su gama Radeon, pero en aquellos entonces todas las capacidades gr&amp;aacute;ficas estaba implementadas mediante fixed-functions, lo cual significaba que solo pod&amp;iacute;as aplicar a los objetos las transformaciones e iluminaci&amp;oacute;n que permit&amp;iacute;a el hardware de la tarjeta gr&amp;aacute;fica, esto provoc&amp;oacute; que muchos juegos de la &amp;eacute;poca tuviesen un aspecto muy parecido.&lt;/p&gt;
&lt;p&gt;Cabe destacar tambi&amp;eacute;n como 3Dfx lanz&amp;oacute; con su tarjeta Voodoo 2 la tecnolog&amp;iacute;a SLI (Scan-Line Interleave) con la que se pod&amp;iacute;an conectar dos tarjetas gr&amp;aacute;ficas en paralelo, lo cual adem&amp;aacute;s de una buena estrategia de ventas fueron los inicios de la computaci&amp;oacute;n gr&amp;aacute;fica en multiples procesadores, 3Dfx innovaba mucho y finalmente fue comprada por Nvidia.&lt;/p&gt;
&lt;p&gt;M&amp;aacute;s tarde la salida de DirectX 8 intent&amp;oacute; mejorar esto incorporando la posibilidad de poder escribir peque&amp;ntilde;os programas que ser&amp;iacute;an ejecutados por la GPU para cada v&amp;eacute;rtice y cada pixel, esto aport&amp;oacute; gran flexibilidad al desarrollo de efectos gr&amp;aacute;ficos. Estos peque&amp;ntilde;os programas se llamaban Shaders y al conjunto de especificaciones se le llam&amp;oacute; Shader Model el cual pod&amp;iacute;a dividirse en dos conjuntos las especificaciones para trabajar con v&amp;eacute;rtices llamada Vertex Shader y las especificaciones para trabajar a nivel de pixel llamadas Pixel Shader. &lt;/p&gt;
&lt;p&gt;Microsoft lanzaba las especificaciones de cada versi&amp;oacute;n de Shader Model pero las primeras tarjetas en incorporar soporte para shaders implementaban parcialmente dichas especificaciones por ello no se hablaba casi nunca de Shader Model y se especificaba hasta que versi&amp;oacute;n de Pixel Shader y Vertex Shader soportaban que no ten&amp;iacute;an porque ser la misma. Sin embargo a patir de la versi&amp;oacute;n 2.0 de Shader Model los fabricantes empezaron ha hablar ya de Shader Model lo cual indicaba que las tarjetas soportaban tanto Vertex Shader 2.0 como Pixel Shader 2.0.&lt;/p&gt;
&lt;p&gt;Por aquellos tiempos la programaci&amp;oacute;n de shader era muy similar a la programaci&amp;oacute;n en emsamblador:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Vertex Shader&lt;/b&gt;&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;vs_1_1 &lt;span style="color:#008000;"&gt;// version instruction&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#cc6633;"&gt;#define&lt;/span&gt; fogStart c9.x&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#cc6633;"&gt;#define&lt;/span&gt; fogEnd c9.z&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c9, 2, 2.33, 2.66, 3 &lt;span style="color:#008000;"&gt;// fog start values&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c10, 3, 4.5, 6, 10 &lt;span style="color:#008000;"&gt;// fog end values&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c11, 0, 0, 1, 1 &lt;span style="color:#008000;"&gt;// clamping values&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c13, 0.66, 1.51, 0, 0&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;dcl_position v0 &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;dcl_texcoord v7&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;m4x4 r0, v0, c0  &lt;span style="color:#008000;"&gt;// transform vertices by world-view-projection matrix&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;mov oPos, r0&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;mov oT0, v7&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;m4x4 r1, v0, c4  &lt;span style="color:#008000;"&gt;// transform vertices by world-view matrix&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#008000;"&gt;// fog constants calculated in the application (6 instructions)&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;mov r2.x, c13.y  &lt;span style="color:#008000;"&gt;// 1 / (fog end - fog start)&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;sub r2.y, fogEnd, r1.z &lt;span style="color:#008000;"&gt;// (fog end - distance)&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;mul r2.z, r2.y, r2.x  &lt;span style="color:#008000;"&gt;// (fog end - distance)/(fog end - fog start)&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;max r2.w, c11.x, r2.z  &lt;span style="color:#008000;"&gt;// clamp above 0&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;min r2.w, c11.z, r2.z  &lt;span style="color:#008000;"&gt;// clamp below 1&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;mov oFog, r2.w  // output per-vertex fog factor &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; r2.x&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pixel Shader&lt;/b&gt;&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;ps_1_1 &lt;span style="color:#008000;"&gt;// version instruction&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c0, 0,0,0,0&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c1, 1,1,1,1&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c2, 1.0,0.5,0,0&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;def c3, 0,-0.5,-0.25,0&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;tex t0 &lt;span style="color:#008000;"&gt;// sample texture at stage 0,&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#008000;"&gt;// with texture coordinate set 0&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;mov r0, t0 &lt;span style="color:#008000;"&gt;// output texture color&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#008000;"&gt;// mov r0, 1 - t0 // output inverted texture color&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#008000;"&gt;// add r0, t0, c2 // add more reds and greens&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#008000;"&gt;// add r0, t0, c3 // subtract greens and blues&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;// mov r0, c2 // output solid pixel color&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Lo cual hac&amp;iacute;a muy complicada su escritura, mantenimiento y reutilizaci&amp;oacute;n, por esta raz&amp;oacute;n se decidi&amp;oacute; crear lenguajes de alto nivel para la programaci&amp;oacute;n de Shader los cuales fuese compilados.&lt;/p&gt;
&lt;p&gt;Microsoft desarrollo el lenguaje HLSL (High Level Shading Language) similar a C el cual lanz&amp;oacute; con la versi&amp;oacute;n de DirectX 9, esto provoc&amp;oacute; un impulso en en el mundo de los gr&amp;aacute;ficos 3D, ahora era mucho m&amp;aacute;s f&amp;aacute;cil escribir Shaders y por lo tanto el tama&amp;ntilde;o de estos peque&amp;ntilde;os programas fue aumentando al igual que su API. &lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n se desarroll&amp;oacute; un lenguaje de alto nivel para trabajar bajo OpenGL llamado GLSL y posteriormente Nvidia lanz&amp;oacute; un lenguaje m&amp;aacute;s, llamado CG el cual permite compilar f&amp;aacute;cilmente un Shader a CG o HLSL.&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; pod&amp;eacute;is ver un ejemplo de un Shader b&amp;aacute;sico que contiene su funci&amp;oacute;n para Vertex y Pixel Shader:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;float4x4 WorldViewProjection;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;float4 VertexShaderFunction(float4 Position : POSITION) : POSITION&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; mul(Position, WorldViewProjection);&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;}&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;float4 PixelShaderFunction() : COLOR&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; float4(1, 0, 0, 1);&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;}&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;technique Technique1&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;    pass Pass1&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;        VertexShader = compile vs_1_1 VertexShaderFunction();&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;        PixelShader = compile ps_1_1 PixelShaderFunction();&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Tras programar en HLSL nunca m&amp;aacute;s quieres volver a saber nada sobre lo anterior pero siempre es importante conocer algo de lo que hab&amp;iacute;a antes, la evoluci&amp;oacute;n de la API con cada versi&amp;oacute;n de DirectX ha sido la siguiente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DirectX 8.0 y 8.1 Shader Model 1.0&lt;/li&gt;
&lt;li&gt;DirectX 9.0 Shader Model 2.0 &lt;/li&gt;
&lt;li&gt;DirectX 9.0c Shader Model 3.0 &lt;/li&gt;
&lt;li&gt;DirectX 10 y 10.1 Shader Model 4.0&lt;/li&gt;
&lt;li&gt;DirectX 11 Shader Model 5.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada una de estas versiones ha venido acompa&amp;ntilde;ada de mejoras, tanto en el n&amp;uacute;mero de instrucciones que se pod&amp;iacute;an introduccir en cada shader (sin restricci&amp;oacute;n alguna en las &amp;uacute;ltimas versiones), como al n&amp;uacute;mero de intrisic functions disponibles. Cabe destar que XNA (hasta la versi&amp;oacute;n actual XNA 3.1) est&amp;aacute; desarrollada sobre DirectX 9.0c por lo que desde este framework solo tenemos acceso a las especificaciones de Shader Model 3.0.&lt;/p&gt;
&lt;p&gt;En la actualidad se ha lanzado ya la versi&amp;oacute;n 11 de DirectX la cual da incluso un paso m&amp;aacute;s all&amp;aacute; con el DirectCompute del cual hablaremos otro d&amp;iacute;a.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=169077" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author></entry><entry><title>Alpha blending en XNA (IV de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/03/04/alpha-blending-en-xna-iv-de-iv.aspx" /><id>/blogs/jcanton/archive/2010/03/04/alpha-blending-en-xna-iv-de-iv.aspx</id><published>2010-03-04T20:23:00Z</published><updated>2010-03-04T20:23:00Z</updated><content type="html">&lt;p&gt;Vayamos ahora a por el último bloque de instrucciones presentado en el primer post:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFactor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Color(255, 255, 255, 255);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.One;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaSourceBlend = Blend.One;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Always;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 0;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Este bloque es independiente de los dos anteriores, mientras los anteriores se referían al Alpha Blending este hace referencia al Alpha Test, lo he escrito dentro del mismo artículo ya que mucha gente los suele confundir. &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Always;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 0;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Estas tres instrucciones están ligadas de forma que mientras no pongamos AlphaTestEnable = true los valores asignados a AlphaFunction y ReferenceAlpha no tendrán efecto, (por defecto AlphaTestEnable = false).&lt;/p&gt;

&lt;p&gt;Estas instrucciones configuran un test basado en el canal alpha que es mucho más rápido que el test de Alpha Blending, su funcionamiento es el siguiente, asignamos un valor de referencia (ReferenceAlpha) con un valor entre 0 y 255 y luego seleccionamos una operación de comparación la cual descartará todos los pixeles que no la cumplan. &lt;/p&gt;

&lt;p&gt;Las posibles funciones que podemos seleccionar son:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Always&lt;/b&gt; 

  &lt;br /&gt;Todos los pixeles pasan el test.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Equal&lt;/b&gt; 

  &lt;br /&gt;Acepta todos los pixeles que tienen en su canal alpha un valor igual que el de referencia.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a&gt;&lt;/a&gt;Greater&lt;/b&gt; 

  &lt;br /&gt;Acepta todos los pixeles que tienen en su canal alpha un valor mayor que el valor de referencia.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a&gt;&lt;/a&gt;GreaterEqual&lt;/b&gt; 

  &lt;br /&gt;Acepta todos los pixeles que tienen en su canal alpha un valor igual o mayor que el valor de referencia.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a&gt;&lt;/a&gt;Less&lt;/b&gt; 

  &lt;br /&gt;Acepta todos los pixeles que tienen en su canal alpha un valor menor que el valor de referencia.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a&gt;&lt;/a&gt;LessEqual&lt;/b&gt; 

  &lt;br /&gt;Acepta todos los pixeles que tienen un su canal alpha un valor menor o igual que el valor de referencia.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a&gt;&lt;/a&gt;Never&lt;/b&gt; 

  &lt;br /&gt;Ningún pixel pasa el test.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a&gt;&lt;/a&gt;NotEqual&lt;/b&gt; 

  &lt;br /&gt;Acepta todos los pixeles que tienen en su canal alpha un valor distinto del valor de referencia.&lt;/p&gt;

&lt;p&gt;Veamos algunos ejemplos:&lt;/p&gt;

&lt;p align="center"&gt;Canales RGB&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/grass_5F00_705A0E8B.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="grass" border="0" alt="grass" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/grass_5F00_thumb_5F00_1981A6CA.jpg" width="244" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p align="center"&gt;Canal Alpha&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Alpha_5F00_53FCA69E.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Alpha" border="0" alt="Alpha" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Alpha_5F00_thumb_5F00_04437B55.jpg" width="244" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;b&gt;Code 1&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Desactivado test de alpha blending&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Activamos el Alpha Test&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Pasan todos los pixeles cuyo valor en el canal alpha super 200&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Greater;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//El valor de referencia será 200&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 200;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture_5F00_09B1EBF9.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture" border="0" alt="Capture" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture_5F00_thumb_5F00_376F8EF1.jpg" width="504" height="300" /&gt;&lt;/a&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Code 2&lt;/b&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Desactivado test de alpha blending&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Activamos el Alpha Test&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Pasan todos los pixeles cuyo valor en el canal alpha sea inferior a 200&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Less;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//El valor de referencia será 200&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 200;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_489346C7.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture1" border="0" alt="Capture1" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_thumb_5F00_44594935.jpg" width="504" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este test es interesante ya que es mucho más rápido que el Alpha Blending, el cual además presenta un problema bastante grande junto al &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/01/24/problemas-con-el-zbuffer-en-xna.aspx"&gt;ZBuffer&lt;/a&gt;, y es que este algoritmo no funciona muy bien con objetos transparentes ya que recordemos que en este algoritmo íbamos marcando en un buffer la profundidad de los objetos para no pintar aquellos que estuviese eclipsados, pero en este caso cuando tenemos objetos transparentes si nos interesa que se pinten todos aquellos objetos que están por detrás de estos, mucha gente decide simplemente desactivar la escritura en el Zbuffer pero esto es un error, lo correcto sería:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;b&gt;Realizar un render de todos los objetos opacos de la escena.&lt;/b&gt; &lt;/li&gt;

  &lt;li&gt;&lt;b&gt;Ordenar por profundidad de atrás hacia delante los objetos transparentes de la escena.&lt;/b&gt; &lt;/li&gt;

  &lt;li&gt;&lt;b&gt;Pintar los objetos transparentes en orden (desactivando la escritura del zbuffer).&lt;/b&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Como se puede intuir esta solución es bastante lenta si pretendemos pintar muchos planos con transparencias pero casualmente una de las situaciones que más se presentan en los videojuegos es el pintado de vegetación usando billboards (que son planos con texturas de hierba).&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/SpeedTree_5F00_32B9389D.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="SpeedTree" border="0" alt="SpeedTree" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/SpeedTree_5F00_thumb_5F00_75D490FD.jpg" width="504" height="371" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Para mejorar el rendimiento de esto el equipo de &lt;a href="http://www.speedtree.com/"&gt;SpeedTree&lt;/a&gt; fue el primero en combinar el &lt;b&gt;Alpha Blending&lt;/b&gt; con el &lt;b&gt;Alpha test&lt;/b&gt;, de forma que los billboard más cercanos se pintaban usando AlphaBlending +&amp;#160; pre-ordenado y el resto usando Alpha Test sin ordenar pero usando un truco, modificando los canales alpha de las texturas de hierba con otras texturas de ruido para ocultar la apreciación de errores de profundidad en el dibujado.&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/FractalTexture_5F00_19410F96.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="FractalTexture" border="0" alt="FractalTexture" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/FractalTexture_5F00_thumb_5F00_2FB3AE1D.jpg" width="500" height="327" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por último comentar que todos estos atributos relacionados con Alpha del RenderState también pueden ser configurados directamente desde el código HLSL, por ejemplo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;technique Feathering&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    pass Pass0&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      VertexShader = compile vs_1_1 vs11();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      PixelShader  = compile ps_1_1 ps11();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      SrcBlend = SrcAlpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      DestBlend = InvSrcAlpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      ZWriteEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    pass Pass1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      VertexShader = compile vs_1_1 vs11();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      PixelShader  = compile ps_1_1 ps11();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      AlphaRef = 0x00000040;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      AlphaFunc = GreaterEqual;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      ZWriteEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    } &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/14/alpha-blending-en-xna-i-de-iv.aspx"&gt;Alpha Blending en XNA (I de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/18/alpha-blending-en-xna-ii-de-iv.aspx"&gt;Alpha Blending en XNA (II de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/25/alpha-blending-en-xna-iii-de-iv.aspx"&gt;Alpha Blending en XNA (III de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/03/04/alpha-blending-en-xna-iv-de-iv.aspx"&gt;Alpha Blending en XNA (IV de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=168809" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="Render" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Render/default.aspx" /><category term="Graphics" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Graphics/default.aspx" /><category term="RenderState" scheme="http://geeks.ms/blogs/jcanton/archive/tags/RenderState/default.aspx" /></entry><entry><title>Alpha blending en XNA (III de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/02/25/alpha-blending-en-xna-iii-de-iv.aspx" /><id>/blogs/jcanton/archive/2010/02/25/alpha-blending-en-xna-iii-de-iv.aspx</id><published>2010-02-25T08:16:07Z</published><updated>2010-02-25T08:16:07Z</updated><content type="html">&lt;p&gt;Recordemos que al principio del todo presentamos un gran conjunto de parámetros que están relacionados con el Alpha dentro de la API de XNA:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFactor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Color(255, 255, 255, 255);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.One;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaSourceBlend = Blend.One;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Always;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 0;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;En esta ocasión nos centraremos en el segundo bloque, este está relacionado con el canal alpha del backbuffer y mucha gente los suele confundir con los del primer grupo. Lo más importante es que todos estos parámetros vienen desactivados por defecto, y seguirán así mientras no pongamos SeparateAlphaBlendEnable a true. En muchos sitios podemos ver como se asignan valores a AlphaSourceBlend y AlphaDestinationBlend sin haber activado SeparateAlphaBlendEnable por lo que esos cambios no tendrán ningún efecto. También hay que tener en cuenta que ciertas instrucciones de XNA modifican el Device.RenderState, como pueden ser la instrucción de SpriteBacth ó la de pass de un effect.&lt;/p&gt;

&lt;p&gt;Pasemos a explicar cual es la finalidad de este grupo de instrucciones, cuando queremos pintar objetos translucidos en la escena y estamos realizando un render sobre el framebuffer, este a su vez es también una imagen y por lo tanto tiene sus canales R, G, B, y A. El canal Alpha del framebuffer suele usarse para guardar información extra sobre todo cuando se aplican efectos de postprocessing en los que el render final es una composición de varios renders previos. &lt;/p&gt;

&lt;p&gt;Bien con SeparateAlphaBlendEnable = false a la hora de realizar el test de Alpha durante el render se usa la fórmula:&lt;/p&gt;

&lt;p align="center"&gt;(Source * SourceBlend) (blendFunction) (Destination * DestinationBlend)&lt;/p&gt;

&lt;p align="left"&gt;esta operación se realiza tanto para los canales RGB como para el canal alpha del framebuffer, sin embargo cuando configuramos SeparateAlphaBlendEnable = true podemos cambiar esto y hacer que se apliquen dos operaciones (una para los canales RGB y otra para el canal alpha).&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;Operación1 sobre canales RGB&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p align="left"&gt;(Source.RGB * SourceBlend) (blendFunction) (Destination.RGB * DestinationBlend)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p align="left"&gt;&lt;strong&gt;Operación2 sobre el canal Alpha&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p align="left"&gt;(Source.A * AlphaSourceBlend) (AlphaBlendOperation) (Destination.A * AlphaDestinationBlend)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p align="left"&gt;Veamos un ejemplo, utilizaremos la siguiente textura en PNG que contendrá tanto los canales RGB como el canal Alpha, aunque veámoslos por separado:&lt;/p&gt;

&lt;p align="center"&gt;Canales RGB&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Glass_5F00_4762F151.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Glass" border="0" alt="Glass" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Glass_5F00_thumb_5F00_071CB20A.jpg" width="132" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="center"&gt;Canal Alpha &lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Alpha_5F00_33C56BE3.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Alpha" border="0" alt="Alpha" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Alpha_5F00_thumb_5F00_59BB1C39.png" width="132" height="132" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Vamos a aplicar una operación a los canales RGB con BlendFactor para hacer la vidriera semitranslucida, y por otra parte vamos a usar el canal Alpha de la textura y vamos a mezclarlo con el canal alpha de FrameBuffer. Para poder apreciar la diferencia en todos los canales del FrameBuffer usaremos el siguiente procedimiento,&amp;#160; renderizamos sobre un RenderTarget2D y posteriormente pintaremos la textura de este RenderTarget2D usando un SpriteBatch al cual le aplicaremos un Shader:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XNA Code:&lt;/strong&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Pintamos sobre un RenderTarget2D&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SetRenderTarget(0, rt);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;graphics.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        Color.Black, 1.0f, 0);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Background&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Draw(background, Vector2.Zero, Color.White);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.End();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.VertexDeclaration = vertexDeclaration;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.CullMode = CullMode.None;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Configuración del RenderState&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFactor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Color(127, 127, 127);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.BlendFactor;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.InverseBlendFactor;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaSourceBlend = Blend.SourceAlpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Render&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;effect.Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (EffectPass pass &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; effect.CurrentTechnique.Passes)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    pass.Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    effect.Parameters[&lt;span style="color:#006080;"&gt;&amp;quot;World&amp;quot;&lt;/span&gt;].SetValue(Matrix.CreateRotationY(rotation));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    effect.Parameters[&lt;span style="color:#006080;"&gt;&amp;quot;View&amp;quot;&lt;/span&gt;].SetValue(Matrix.CreateLookAt(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Vector3(0, 0, -4), Vector3.Zero, Vector3.Up));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    effect.Parameters[&lt;span style="color:#006080;"&gt;&amp;quot;Projection&amp;quot;&lt;/span&gt;].SetValue(Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1, 10000));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    effect.Parameters[&lt;span style="color:#006080;"&gt;&amp;quot;DiffuseTexture&amp;quot;&lt;/span&gt;].SetValue(textures[index]);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    graphics.GraphicsDevice.DrawUserPrimitives&amp;lt;VertexPositionNormalTexture&amp;gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            PrimitiveType.TriangleList, boxData, 0, 2);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    pass.End();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;effect.End();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Ahora pintamos la imágen almacenada en el RenderTarget2D sobre un SpriteBatch&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SetRenderTarget(0, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;alphaEffect.Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;alphaEffect.CurrentTechnique.Passes[0].Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;alphaEffect.Parameters[&lt;span style="color:#006080;"&gt;&amp;quot;Alpha&amp;quot;&lt;/span&gt;].SetValue(alpha);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Draw(rt.GetTexture(), Vector2.Zero, Color.White);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;alphaEffect.CurrentTechnique.Passes[0].End();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;alphaEffect.End();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.End();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Shader&lt;/strong&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;sampler ColorMapSampler;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Alpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;float4 PixelShaderFunctionAlpha(float2 TexCoord : TEXCOORD0) : COLOR0&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(Alpha)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;float&lt;/span&gt; a = tex2D(ColorMapSampler, TexCoord).a;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; float4(a, a, a, 1);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; tex2D(ColorMapSampler, TexCoord);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;technique Technique1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    pass Pass1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        PixelShader = compile ps_2_0 PixelShaderFunctionAlpha();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Este Shader nos permitirá mediante el valor de un parámetro “Alpha”, ver los canales RGB ó el canal alpha del resultado final.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="center"&gt;&lt;strong&gt;Resultado en los canales RGB del FrameBuffer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture2_5F00_11F99352.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture2" border="0" alt="Capture2" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture2_5F00_thumb_5F00_6E7CEEEC.jpg" width="504" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="center"&gt;&lt;strong&gt;Resultado en el canal alpha del FrameBuffer&lt;/strong&gt;&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_4C44E366.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Capture1" border="0" alt="Capture1" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_thumb_5F00_71CE60C7.jpg" width="504" height="300" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Bueno como veis si antes teníamos muchas posibilidades, ahora con SeparateAlphaBlendEnable estas se incrementan aún más, ya que AlphaSourceBlend y AlphaDestinationBlend pueden ser configurados con cualquiera de los valores Blend vistos anteriormente para SourceBlend y DestinationBlend, de igual modo AlphaBlendOperation puede tomar cualquiera de los valores que vimos para BlendFunction.&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/14/alpha-blending-en-xna-i-de-iv.aspx"&gt;Alpha Blending en XNA (I de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/18/alpha-blending-en-xna-ii-de-iv.aspx"&gt;Alpha Blending en XNA (II de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/25/alpha-blending-en-xna-iii-de-iv.aspx"&gt;Alpha Blending en XNA (III de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/03/04/alpha-blending-en-xna-iv-de-iv.aspx"&gt;Alpha Blending en XNA (IV de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=168150" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="Shaders" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Shaders/default.aspx" /><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="HLSL" scheme="http://geeks.ms/blogs/jcanton/archive/tags/HLSL/default.aspx" /><category term="Render" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Render/default.aspx" /><category term="Graphics" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Graphics/default.aspx" /><category term="RenderState" scheme="http://geeks.ms/blogs/jcanton/archive/tags/RenderState/default.aspx" /></entry><entry><title>Alpha blending en XNA (II de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/02/18/alpha-blending-en-xna-ii-de-iv.aspx" /><id>/blogs/jcanton/archive/2010/02/18/alpha-blending-en-xna-ii-de-iv.aspx</id><published>2010-02-18T23:03:19Z</published><updated>2010-02-18T23:03:19Z</updated><content type="html">&lt;p&gt;Recordemos la formula general usada para las transparecias:&lt;/p&gt;  &lt;p align="center"&gt;(Source * SourceBlend) (blendFunction) (Destination * DestinationBlend)&lt;/p&gt;  &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="left"&gt;En los dos ejemplos anteriores usamos como BlendFunction la operación suma que suele ser la más común, pero se pueden usar otras, la lista completa es:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;strong&gt;Add&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;result = (Source * SourceBlend) + (Destination * DestinationBlend)&lt;/p&gt;    &lt;p align="left"&gt;&lt;strong&gt;Max&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = max( (Source * SourceBlend), (Destination * DestinationBlend)&lt;/p&gt;    &lt;p align="left"&gt;&lt;strong&gt;Min&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;result = min( (Source * SourceBlend), (Destination * DestinationBlend)&lt;/p&gt;    &lt;p align="left"&gt;&lt;strong&gt;ReverseSubtract&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;result = (Destination * DestinationBlend) - (Source * SourceBlend)&lt;/p&gt;    &lt;p align="left"&gt;&lt;strong&gt;Subtract&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = (Source * SourceBlend) - (Destination * DestionationBlend)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;Para los parámetros SourceBlend y DestionationBlend que como vimos anteriormente nos indica el nivel de aportación a la mezcla del Source (lo que queremos pintar con transparencia) y del Destination (lo que ya está se ha pintado en el framebuffer, el fondo), y los configuramos para que usaran un valor constante de alpha para toda la textura usando el BlendFactor ó que usaran el canal alpha de la textura, pero también existen muchos otros valores, aquí os dejo la lista completa también:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Zero&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by (0, 0, 0, 0). &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;One&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by (1, 1, 1, 1). &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;SourceColor&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the source color. This can be represented as (Rs, Gs, Bs, As), where R, G, B, and A respectively stand for the red, green, blue, and alpha source values. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;InverseSourceColor&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the inverse of the source color. This can be represented as (1 − Rs, 1 − Gs, 1 − Bs, 1 − As) where R, G, B, and A respectively stand for the red, green, blue, and alpha destination values. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;SourceAlpha&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the alpha value of the source. This can be represented as (As, As, As, As), where As is the alpha source value. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;InverseSourceAlpha&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the inverse of the alpha value of the source. This can be represented as (1 − As, 1 − As, 1 − As, 1 − As), where As is the alpha destination value. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;DestinationAlpha&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the alpha value of the destination. This can be represented as (Ad, Ad, Ad, Ad), where Ad is the destination alpha value. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;InverseDestinationAlpha&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the inverse of the alpha value of the destination. This can be represented as (1 − Ad, 1 − Ad, 1 − Ad, 1 − Ad), where Ad is the alpha destination value. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;DestinationColor&lt;/strong&gt;       &lt;br /&gt;Each component color is multiplied by the destination color. This can be represented as (Rd, Gd, Bd, Ad), where R, G, B, and A respectively stand for red, green, blue, and alpha destination values. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;InverseDestinationColor&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the inverse of the destination color. This can be represented as (1 − Rd, 1 − Gd, 1 − Bd, 1 − Ad), where Rd, Gd, Bd, and Ad respectively stand for the red, green, blue, and alpha destination values. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;SourceAlphaSaturation&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by either the alpha of the source color, or the inverse of the alpha of the source color, whichever is greater. This can be represented as (&lt;em&gt;f&lt;/em&gt;, &lt;em&gt;f&lt;/em&gt;, &lt;em&gt;f&lt;/em&gt;, 1), where &lt;em&gt;f&lt;/em&gt; = &lt;strong&gt;min&lt;/strong&gt;(A, 1 − Ad). &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;BothInverseSourceAlpha&lt;/strong&gt;       &lt;br /&gt;(Win32 only) Each component of the source color is multiplied by the inverse of the alpha of the source color, and each component of the destination color is multiplied by the alpha of the source color. This can be represented as (1 − As, 1 − As, 1 − As, 1 − As), with a destination blend factor of (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the SourceBlend render state. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;BlendFactor&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by a constant set in BlendFactor. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;InverseBlendFactor&lt;/strong&gt;       &lt;br /&gt;Each component of the color is multiplied by the inverse of a constant set in BlendFactor. This blend mode is supported only if SupportsBlendFactor is true in the SourceBlendCapabilities or DestinationBlendCapabilities properties. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;a&gt;&lt;/a&gt;BothSourceAlpha&lt;/strong&gt;       &lt;br /&gt;This mode is obsolete. The same effect can be achieved by setting the source and destination blend factors to &lt;strong&gt;SourceAlpha&lt;/strong&gt; and &lt;strong&gt;InverseSourceAlpha&lt;/strong&gt; in separate calls. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ahora es cuando muchos os estaréis preguntando que para que tantos valores, pues como veis las posibles combinaciones son muchas y con todas ellas el resultado es algo diferente, que sean más o menos útiles ya es otra cosa XD.&lt;/p&gt;  &lt;p&gt;Las combinaciones más usadas y conocidas son:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Alpha Blending&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;(source * &lt;font color="#0080c0"&gt;Blend.SourceAlpha&lt;/font&gt;) + (destination * &lt;font color="#0080ff"&gt;Blend.InvSourceAlpha&lt;/font&gt;)&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Additive Blending&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;(source * &lt;font color="#0080ff"&gt;Blend.One&lt;/font&gt;) + (destination * &lt;font color="#0080ff"&gt;Blend.One&lt;/font&gt;)&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Multiplicative Blending&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;(source * &lt;font color="#0080ff"&gt;Blend.Zero&lt;/font&gt;) + (destination * &lt;font color="#0080ff"&gt;Blend.SourceColor&lt;/font&gt;)&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;2X Multiplicative Blending&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;(source * &lt;font color="#0080ff"&gt;Blend.DestinationColor&lt;/font&gt;) + (destination * &lt;font color="#0080ff"&gt;Blend.SourceColor&lt;/font&gt;)&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/BlendModes_5F00_041A3F6A.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="BlendModes" border="0" alt="BlendModes" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/BlendModes_5F00_thumb_5F00_1682901F.jpg" width="504" height="169" /&gt;&lt;/a&gt; &lt;/p&gt;    &lt;p align="center"&gt;1. Alpha Blending, 2. Additive Blending, 3. Multiplicative Blending, 4. 2X Multiplicative Blending&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;También cabe destacar que existen diferentes formas de pensar en la transparencia esta que acabamos de ver podemos llamar la forma convencional en la mayoría de APIs.&lt;/p&gt;  &lt;p align="left"&gt;&lt;strong&gt;Conventional Alpha Blending&lt;/strong&gt;&lt;/p&gt;  &lt;p align="left"&gt;Idea:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;blend(source, destination) = (source.rgb * source.a) + (destination.rgb * (1 – source.a))&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;En XNA:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div id="codeSnippetWrapper"&gt;     &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;       &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;&lt;/pre&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pero como podemos observar en esta situación los valores RGB y el alpha son independientes, de manera que sería posible tener un objeto totalmente transparente con valores de color en RGB, esto a un informático no le preocupa en exceso, pero no es un comportamiento muy real. Por ello existen otras formas de pensar en la transparencia como:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Premultiplied Alpha Blending&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Idea:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;blend(source, destination) = source.rgb + ( destination.rgb * (1 – source.a) )&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En XNA:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div id="codeSnippetWrapper"&gt;
    &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.One;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;&lt;/pre&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;En este caso el alpha y el RGB están ligados y para que un objeto sea transparente debe tener el máximo de transparencia, y el color de RGB debe ser nulo (0,0,0). Si os fijáis la formula es la misma que la anterior solo que el source.rgb lo multiplicamos por 1, esto implica que si el objeto es translucido tendremos que realizar una conversión previa de las texturas para pasarlas a premultiplied format:&lt;/p&gt;

&lt;p align="center"&gt;color.rgb *= color.a&lt;/p&gt;

&lt;p align="left"&gt;Uno de los grandes motivos por el que se tiende a usar está técnica es porque se adapta mejor con DTX compression.&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/14/alpha-blending-en-xna-i-de-iv.aspx"&gt;Alpha Blending en XNA (I de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/18/alpha-blending-en-xna-ii-de-iv.aspx"&gt;Alpha Blending en XNA (II de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/25/alpha-blending-en-xna-iii-de-iv.aspx"&gt;Alpha Blending en XNA (III de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/03/04/alpha-blending-en-xna-iv-de-iv.aspx"&gt;Alpha Blending en XNA (IV de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=167710" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Render" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Render/default.aspx" /><category term="Graphics" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Graphics/default.aspx" /><category term="RenderState" scheme="http://geeks.ms/blogs/jcanton/archive/tags/RenderState/default.aspx" /></entry><entry><title>Alpha blending en XNA (I de IV)</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/02/14/alpha-blending-en-xna-i-de-iv.aspx" /><id>/blogs/jcanton/archive/2010/02/14/alpha-blending-en-xna-i-de-iv.aspx</id><published>2010-02-14T14:37:00Z</published><updated>2010-02-14T14:37:00Z</updated><content type="html">&lt;p&gt;Alpha blending es la técnica con la cual podemos trabajar con transparencias tanto en 2D como en 3D, nos centraremos en pintar un plano con una textura y veremos diferentes formas de aplicar esta técnica.&lt;/p&gt;  &lt;p&gt;Para el primer ejemplo usaremos una textura de vidriera:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Glass_5F00_46409AED.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Glass" border="0" alt="Glass" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Glass_5F00_thumb_5F00_3FAD1B5D.jpg" width="132" height="132" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;la cual nos gustaría aplicar a un plano en 3D y que se viese translucido. Si simplemente la textura el resultado sería algo como:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_107B2FC6.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture1" border="0" alt="Capture1" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_thumb_5F00_7E6EEC38.jpg" width="504" height="300" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Aquí entran en juego todos los parámetros con los que podemos trabajar, estos los podemos dividir en 3 grupos y sus valores por defecto son:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFactor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Color(255, 255, 255, 255);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.One;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaSourceBlend = Blend.One;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.Zero;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Always;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 0;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Todos estos son muchos parámetros y mucha gente termina confundiéndolos, para empezar nos centraremos solo en el primer grupo:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;AlphaBlendEnable&lt;/b&gt; deberemos ponerlo a true si queremos activar el test de AlphaBlending.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;BlendFunction&lt;/b&gt;, &lt;b&gt;SourceBlend&lt;/b&gt; y &lt;b&gt;DestinationBlend&lt;/b&gt; serán usados para determinar el color de cada pixel en el framebuffer tras la mezcla mediante la siguiente fórmula:&lt;/p&gt;

&lt;p align="center"&gt;(Source * SourceBlend) (blendFunction) (Destination * DestinationBlend)&lt;/p&gt;

&lt;p align="left"&gt;En este ejemplo concreto:&lt;/p&gt;

&lt;p align="left"&gt;- Source representará los colores almacenados en la textura de vidriera.&lt;/p&gt;

&lt;p align="left"&gt;- SourceBlend será el valor por el que multiplicaremos Source e indicará su contribución a la mezcla.&lt;/p&gt;

&lt;p align="left"&gt;- BlendFunction representa una operación que puede ser suma, recta….&lt;/p&gt;

&lt;p align="left"&gt;- Destination es el color que ya está en el framebaffer en nuestro caso la imagen de fondo con los árboles.&lt;/p&gt;

&lt;p align="left"&gt;- DestinationBlend indicará la contribución del fondo a la mezcla.&lt;/p&gt;

&lt;p align="left"&gt;Para irnos familiarizando con todos estos parámetros seguiremos con el ejemplo de la vidriera, nosotros lo que queríamos era que se viese translucida (con el mismo valor de translucidez por toda la superficie) para ello usaremos el parámetro &lt;b&gt;BlendFactor&lt;/b&gt; que os ayudará a aplicar un valor constante de translucidez a toda la superficie, la manera de usarlo será configurar el valor de BlendFactor y posteriormente usar este desde SourceBlend y DestinationBlend, por ejemplo:&lt;/p&gt;

&lt;p align="left"&gt;&amp;#160;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Activamos el AlphaBlending&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Los valores de color están entre (0-255) con 127 le estamos indicando que queremos que sea un 50% translucida&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFactor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Color(127, 127, 127);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Utilizamores como operador la suma para la mezcla&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Multiplica los valores RGB de la vidriera por el valor de BlendFactor &lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.BlendFactor;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Multiplica los valores RGB del fondo por el valor inverso de Blend factor (1 - BlendFactor)&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.InverseBlendFactor;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="left"&gt;El resultado:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture2_5F00_094BCD81.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture2" border="0" alt="Capture2" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture2_5F00_thumb_5F00_4DABBEC0.jpg" width="504" height="299" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;En este caso estábamos trabajando con una textura que no traía información en el canal Alpha ó este veían vacio (todo a 1), las texturas suelen almacenar 4 canales Red, Green, Blue, Alpha (RGBA). &lt;/p&gt;

&lt;p&gt;Probemos ahora con una textura con canal alpha para lo cual necesitaremos un formato que sea capaz de almacenarlo por ejemplo PNG:&lt;/p&gt;

&lt;p align="center"&gt;Canales RGB&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Glass_5F00_0A804093.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Glass" border="0" alt="Glass" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Glass_5F00_thumb_5F00_215F120F.jpg" width="132" height="132" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p align="center"&gt;Canal Alpha&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/canalAlpha_5F00_67039C2D.png"&gt;&lt;/a&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="canalAlpha" border="0" alt="canalAlpha" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/canalAlpha_5F00_thumb_5F00_0CF94C84.png" width="132" height="132" /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;El canal alpha al ser un solo canal, si lo presentamos en una imagen esta será en blanco y negro. En este caso podemos ver como la vidriera no tiene los mismos niveles de translucidez en toda su superficie, todo lo que esté más cercano al blanco será opaco, por lo que tanto el marco como el centro serán totalmente opacos (resultado de multiplicar RGB * 1).&lt;/p&gt;

&lt;p&gt;Ahora ya el BlendFactor no nos sirve necesitamos que tanto SourceBlend como DestinationBlend reciban información del canal alpha de la textura, esto lo haremos de la siguiente forma:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Activamos el AlphaBlending&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Utilizamores como operador la suma para la mezcla&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Multiplica los valores RGB de la vidriera por la información almacenada en el canal alpha de la textura&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;//Multiplica los valores RGB del fondo por el inverso de los valores multiplicados en el canal alpha de la textura (1 - alpha)&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;El resultado es el siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture3_5F00_36F94AAC.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture3" border="0" alt="Capture3" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture3_5F00_thumb_5F00_481D0282.jpg" width="504" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/14/alpha-blending-en-xna-i-de-iv.aspx"&gt;Alpha Blending en XNA (I de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/18/alpha-blending-en-xna-ii-de-iv.aspx"&gt;Alpha Blending en XNA (II de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/02/25/alpha-blending-en-xna-iii-de-iv.aspx"&gt;Alpha Blending en XNA (III de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://geeks.ms/blogs/jcanton/archive/2010/03/04/alpha-blending-en-xna-iv-de-iv.aspx"&gt;Alpha Blending en XNA (IV de IV)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;************************************************************************************************&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=167360" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Render" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Render/default.aspx" /><category term="Graphics" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Graphics/default.aspx" /><category term="RenderState" scheme="http://geeks.ms/blogs/jcanton/archive/tags/RenderState/default.aspx" /></entry><entry><title>Problemas con el ZBuffer en XNA</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/01/24/problemas-con-el-zbuffer-en-xna.aspx" /><id>/blogs/jcanton/archive/2010/01/24/problemas-con-el-zbuffer-en-xna.aspx</id><published>2010-01-24T18:51:23Z</published><updated>2010-01-24T18:51:23Z</updated><content type="html">&lt;p&gt;El zbuffer es el algoritmo que se utiliza a la hora de dibujar los objetos en pantalla para decidir que objetos están delante de otros, recibe este nombre ya que se realiza un test de las coordenadas z de los objetos para comparar la profundidad a la que se encuentran en el mundo 3D. Esto a muchos matemáticos o físicos les puede resultar extraño ya que están acostumbrados a que en sus sistema de referencia la z es el vector que apunta hacia arriba, en los gráficos 3D el eje z es el que “entra hacia dentro de la pantalla” para sus valores positivos. Mucha gente piensa que esto se debe a discusiones entre informáticos y matemáticos o físicos XD, pero no es cierto, simplemente se debe a que se intentan facilitar las operaciones que se tienen que realizar con la cámara para representar los modelos y por ellos la cámara en un mundo 3D siempre se pone “como mirando al suelo” perpendicular al plano XY.&lt;/p&gt;  &lt;p&gt;Los problemas de Zbuffer pueden ser confundidos con problemas de flip de normales, suelen tener un aspecto como:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="center"&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture_5F00_176EB117.png"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture" border="0" alt="Capture" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture_5F00_thumb_5F00_78E42493.png" width="360" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Render Correcto&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_34B090BC.png"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Capture1" border="0" alt="Capture1" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jcanton/Capture1_5F00_thumb_5F00_774F905A.png" width="360" height="281" /&gt;&lt;/a&gt;Render con problema de Zbuffer&lt;/p&gt;  &lt;p align="left"&gt;Como se puede apreciar en la segunda imagen, el algoritmo que decide que se debe pintar delante y que detrás está fallando, de todas formas para detectar este tipo de problemas también os podréis fijar en que si rotáis el modelo puede que desde algunos ángulos se vea correctamente y desde otros no.&lt;/p&gt;  &lt;p align="left"&gt;Este es uno de los primeros problemas con los que se encuentran muchas de las personas que empiezan a trabajar con XNA, esto se debe generalmente a problemas en el código del render. XNA facilita muchas tareas y los que descubren esta tecnología después de haber trabajado con muchas otras librerías anteriores ven el “cielo abierto” y este tipo de problemas los saben detectar rápidamente y buscarle soluciones, el problema normalmente lo tienen los desarrolladores con menos experiencia que se adaptan rápidamente a la facilidad de trabajar con XNA pero cuando les surge un problema de este tipo no entienden el porque ocurre, muchos incluso piensan que el problema se debe al formato de modelos que usan ó a que no se ha exportado bien desde alguno de los programas de diseño con los que trabajan 3D Studio Max, Maya, SoftImage, blender, …&lt;/p&gt;  &lt;p&gt;El problema suele aparecer cuando se intenta mezclar un render2D y un render3D al mismo tiempo usando para dibujar esto las clases SpriteBatch y BasicEffect que vienen por defecto con XNA, un posible ejemplo:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;Matrix[] transforms = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Matrix[model.Bones.Count];&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;model.CopyAbsoluteBoneTransformsTo(transforms); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;localWorld = Matrix.Identity                &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;* Matrix.CreateRotationY(rotation.Y)                &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;* Matrix.CreateRotationX(rotation.X)                &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;* Matrix.CreateRotationZ(rotation.Z)                &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;* Matrix.CreateTranslation(position)                &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;* Matrix.CreateScale(scale); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (ModelMesh mesh &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; model.Meshes)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (BasicEffect effect &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; mesh.Effects)    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.EnableDefaultLighting();        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.PreferPerPixelLighting = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;         &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.World = transforms[mesh.ParentBone.Index] * localWorld * camera.World;        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.View = camera.View;        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.Projection = camera.Projection;    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }     &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    mesh.Draw();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;} &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.DrawString(font, &lt;span style="color:#006080;"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;, Vector2.Zero, Color.White);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Draw(Texture, position, Color.White);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.End(); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Draw(gameTime);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Este es el render básico 3D que podemos encontrar en los tutoriales de XNA, en el que pintamos un modelo 3D usando BasicEffect, y en una segunda parte pintamos un texto y una textura en 2D con spritebatch, este código probará estos errores de ZBuffer de los que hemos hablado, una posible solución sería:&lt;/p&gt;

&lt;p&gt;Cambiar la línea del spritebatch.Begin(); por:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spritebatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Con esto le estamos indicando que realice el test de alfa para la textura y el texto, que envíe los elementos 2D directamente sin ordenarlos previamente y que salve el estado del Device y lo restaura justo después de realizar el dibujado 2D. La clave está en lo último en salvar el Device y el motivo es que spritebatch modifica la configuración del Device actual (la configuración con la que hemos pintado el modelo 3D y que viene por defecto) desactivando el Zbuffer y no restaurándolo después. &lt;/p&gt;

&lt;p&gt;Lo importante es que aunque uséis esta solución entendáis porque soluciona el problema, guardar el estado del Device y restaurarlo en cada frame es algo más lento que si configuráramos directamente el Device con una configuración completa valida para todo aquello que queremos dibujar, o si solo cambiáramos ciertos parámetros del Device y no todos, de todas formas tampoco estamos hablando de unas grandes pérdidas de tiempo, aunque para obtener resultado más profesionales esto si que sería algo a estudiar.&lt;/p&gt;

&lt;p&gt;Además del Zbuffer ¿qué otras cosas modifica el spritebatch de la configuración del Device que puedan darme problemas?, pues aquí os dejo una lista completa de las configuraciones que realiza el spritebatch sobre el Device:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DepthBufferEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Greater;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.ReferenceAlpha = 0; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Clamp;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Clamp; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].MagFilter = TextureFilter.Linear;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].MinFilter = TextureFilter.Linear;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].MipFilter = TextureFilter.Linear; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].MipMapLevelOfDetailBias = 0.0f;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.SamplerStates[0].MaxMipLevel = 0; &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Además de esto también modifica los vértices, los índices, la declaración de vértices, e incluso las propiedades del Device para pixel and vertex shader.&lt;/p&gt;

&lt;p&gt;Una solución más eficiente sería simplemente reactivar el zbuffer después del SpriteBatch.End(), de la siguiente forma:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.DepthBufferEnable = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaBlendEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;GraphicsDevice.RenderState.AlphaTestEnable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Y eso fue todo XD.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=165843" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="Render" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Render/default.aspx" /><category term="Errores" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Errores/default.aspx" /></entry><entry><title>Shaders en XNA</title><link rel="alternate" type="text/html" href="/blogs/jcanton/archive/2010/01/10/shaders-en-xna.aspx" /><id>/blogs/jcanton/archive/2010/01/10/shaders-en-xna.aspx</id><published>2010-01-10T19:21:00Z</published><updated>2010-01-10T19:21:00Z</updated><content type="html">&lt;p&gt;Hace unas semanas Jesús Bosch me lió para dar un webcast online (si Jesús fue así ahora no lo niegues XD), y la idea principal es que iba a ser un webcast orientado a desarrolladores de XNA por lo que todos tendrían ya unos ciertos conocimientos previos sobre esta tecnología.&lt;/p&gt;  &lt;p&gt;La charla entonces la centré en una introducción al mundo de los shaders y a como poder hacer uso de ellos dentro de XNA, los shaders para que el que no sepa de que estoy hablando son mini programas que se escriben para ser ejecutados en la GPU (Graphics Processing Unit, el procesador de las tarjetas gráficas de nuestros ordenadores). &lt;/p&gt;  &lt;p&gt;Estas tarjetas están especializadas en cálculos en coma flotante y matriciales a diferencia de las CPU que son procesadores de propósito general, por lo que el rendimiento de nuestros juegos y aplicaciones con XNA y Shaders puede verse incrementado enormemente. Es más para el que lo desconozca en XNA todo se pinta mediante Shaders, por eso para poder ejecutar XNA en cualquier ordenador se requiere una tarjeta que soporte Pixel and Vertex Shader 1.1 al menos, esto tampoco es una restricción muy grande para los días que corren, ya cualquier chip gráfico de los que llevan varios años integrando en las placas base como las típicas de Intel 950 ya soportan esto.&lt;/p&gt;  &lt;p&gt;Este es el principal motivo por el cual el rendimiento 3D de aplicaciones XNA está tan cercano al de aplicaciones DirectX escritas en C++. Como actualmente el cálculo intensivo se desplaza a la GPU, para la CPU quedan otro tipo de cálculos como puede ser la lógica del juego ó la IA, y es esto lo que se escribe en C#.&lt;/p&gt;  &lt;p&gt;Para conseguir esta transparencia dentro de XNA y que los usuarios que prueban esta tecnología puedan desarrollar juegos con un alto rendimiento gráfico sin tener que preocuparse de aprender un lenguaje de Shaders como el HLSL, el equipo de desarrollo de XNA a creado dos clases básicas que se usan para pintar en 2D y en 3D.&lt;/p&gt;  &lt;p&gt;Para 2D tenemos el spriteBatch:&lt;/p&gt;  &lt;p&gt;Imagen:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spriteBatch.Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spriteBatch.Draw(Texture, Rectangle, Color.White);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spriteBatch.End();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;pre class="csharpcode"&gt;Texto:&lt;/pre&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spriteBatch.Begin();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spriteBatch.DrawString(font, &lt;span style="color:#006080;"&gt;&amp;quot;Hola Mundo&amp;quot;&lt;/span&gt;, Position, Color.Red);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;spriteBatch.End();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;al cual le indicamos si queremos pintar un texto ó una imagen y el se encarga de dibujarlo en pantalla sobre un plano que coloca frente a la cámara, todo esto lo hace mediante un shader y de forma transparente para nosotros, el código de dicho shader está liberado y podéis verlo &lt;a href="http://creators.xna.com/en-US/utilities/spritebatchshader"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para pintar modelos 3D han desarrollado el objeto BasicEffect:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (ModelMesh mesh &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; MyModel)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (BasicEffect effect &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; mesh.Effects)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.EnableDefaultLighting();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.World = world;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.View = camera.view;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        effect.Projection = camera.projection;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    mesh.Draw();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;el cual también usa un shader internamente y del cual también podemos bichear su código fuente &lt;a href="http://creators.xna.com/en-US/utilities/basiceffectshader"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A pesar de estas facilidades si realmente queremos sacarle partido a nuestras tarjetas gráficas lo mejor es escribir nuestros propios shaders, y este webcast sobre shaders es un punto por el que empezar a conocer todo ese mundo, (aviso que son 2 horas a un buen ritmo XD). &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Ahora está disponible en &lt;a href="http://channel9.msdn.com/posts/channel9spain/XNA-Shaders/"&gt;Channel 9 Spain&lt;/a&gt; gracias a Alejandro Hidalgo, espero que os sea útil.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=164706" width="1" height="1"&gt;</content><author><name>jcanton</name><uri>http://geeks.ms/members/jcanton/default.aspx</uri></author><category term="Shaders" scheme="http://geeks.ms/blogs/jcanton/archive/tags/Shaders/default.aspx" /><category term="XNA" scheme="http://geeks.ms/blogs/jcanton/archive/tags/XNA/default.aspx" /><category term="HLSL" scheme="http://geeks.ms/blogs/jcanton/archive/tags/HLSL/default.aspx" /></entry></feed>