+ Responder Tema
Resultados 1 al 3 de 3

Tema: C#–XNA-Shaders- Como Convertir Una Imagen a Escala de Grises
 

  1. #1
    JuanKSolocodigo
    Guest
    Status :
    A 1 persona le gusta este mensaje

    Exclamation C#–XNA-Shaders- Como Convertir Una Imagen a Escala de Grises

    Les comparto este artículo escrito originalmente en mi blog:
    http://juank.black-byte.com/xna-shaders-convertir-imagen-grises/

    ----------


    Hola, continuando con el tema del procesamiento de imágenes, este es el tercer artículo relacionado con la conversión de una imagen a escala de grises.

    En los dos artículos anteriores:
    http://juank.black-byte.com/xna-conv...escala-grises/
    http://juank.black-byte.com/c-bitmap...escala-grises/

    Se reviso como convertir una imagen a escala de grises utilizando XNA/Texture2D y también como hacerlo utilizando un objeto Bitmap del .net Framework.

    Sin embargo hubo un tema que no toqué y honestamente no pretendía tocar, al menos no por ahora, pero uno de mis lectores dejo sembrada en mi esa inquietud, y aquí lo tengo este artículo que muestra como convertir una imagen en escala de grises utilizando el método que es, de lejos, el más eficiente de todos y también el más sencillo una vez se sabe acerca de los Shaders.

    Como trabajar los Shaders en XNA?


    Para programar el shader he preparado un código de ejemplo inicial, el cual sencillamente crea un rectángulo y lo pone en un entorno 3D y le aplica una textura, la cual será a la que le modificaremos la información por medio del shader. Acá esta el código inicial sin Shaders.

    Código PHP:
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
     
    namespace 
    BlogHLSL
    {
        public class 
    Game1 Microsoft.Xna.Framework.Game
        
    {
            
    GraphicsDeviceManager graphics;
            
    VertexPositionTexture[] verts;
            
    BasicEffect effect;
            
    Texture2D textura;
     
            public 
    Game1()
            {
                
    graphics = new GraphicsDeviceManager(this);
                
    Content.RootDirectory "Content";
            }
     
            protected 
    override void Initialize()
            {
                
                
    GraphicsDevice.RenderState.CullMode CullMode.None;
                
    GraphicsDevice.VertexDeclaration = new VertexDeclaration(GraphicsDeviceVertexPositionTexture.VertexElements);
     
                
                
    effect = new BasicEffect(GraphicsDevicenull);
                
    effect.View Matrix.CreateLookAt(new Vector3(0,0,-10), new Vector3(0,0,1), Vector3.Up);
                
    effect.Projection Matrix.CreatePerspectiveFieldOfView(0.5f
                                                   
    Window.ClientBounds.WidthWindow.ClientBounds.Height
                                                   
    110);
                
    effect.World Matrix.Identity Matrix.CreateTranslation(1.7f,1.7f,0);
                
    effect.TextureEnabled true;
     
                
    base.Initialize();
            }
     
            protected 
    override void LoadContent()
            {
                
    textura Content.Load<texture2d>("rabbid");
                
    effect.Texture textura;
     
                
    verts = new VertexPositionTexture[4];
                
    verts[0] = new VertexPositionTexture(new Vector3(-1,1,0),      new Vector2(0,0));
                
    verts[1] = new VertexPositionTexture(new Vector3(110),     new Vector2(10));
                
    verts[2] = new VertexPositionTexture(new Vector3(-1, -2.7f0),new Vector2(01));
                
    verts[3] = new VertexPositionTexture(new Vector3(1, -2.7f0), new Vector2(11));            
            }
     
            protected 
    override void Draw(GameTime gameTime)
            {
                
    GraphicsDevice.Clear(Color.CornflowerBlue);
     
                
    effect.Begin();
                foreach (
    EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    
    pass.Begin();
                    
    GraphicsDevice.DrawUserPrimitives<vertexpositiontexture>(PrimitiveType.TriangleStripverts02);
                    
    pass.End();
                }
                
    effect.End();
                
    base.Draw(gameTime);
            }
        }

    Ahora a programar con Shaders!!!


    Tomando el código anterior como base lo que haré será dibujar la textura en otra posición, simplemente cambiando la posicion del world, la diferencia será que el efecto que usaré para dibujar la textura no será un BasicEffect sino un Effect.
    Al utilizar Effect se tiene todo el poder de los Shaders en las manos, pero se debe asumir un pequeño costo y es que dejar la aplicación haciendo exactamente lo que hacia es un poco más complicado de hacer de lo que era con un BasicEffect , si bien la funcionalidad del BasicEffect se puede considerar muy limitada.
    Shader para dibujar una textura

    BasicEffect es un shader pre implementado que viene con XNA el cual sencillamente nos permite comenzar a trabajar sin preocuparnos por saber o no de Shaders. En su lugar vamos a trabajar con Effect. Para inicializar Effect necesitamos un archivo .fx que es el que contendrá el código del shader, así que en el Content se debe agregar un nuevo archivo de tipo Effect y lo llamaré Efecto.fx.
    Este es el shader con el que iniciaré a trabajar, es decir este es el Shader mínimo que permite hacer exactamente lo mismo que con BasicEffect:

    Código PHP:
    float4x4 WorldViewProjection;
    Texture textura;
    sampler muestreador sampler_state
    {
      
    Texture = <textura>;    
      
    magfilter LINEAR
      
    minfilter LINEAR
      
    mipfilter LINEAR;
      
    AddressU mirror
      
    AddressV mirror;
    };
     
    struct VertexShaderInput
    {
        
    float4 Position POSITION0;
        
    float2 Tex TEXCOORD0;
    };
     
    struct VertexShaderOutput
    {
        
    float4 Position POSITION0;
        
    float2 Tex TEXCOORD0;
    };
     
    VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
    {    
        
    VertexShaderOutput output = (VertexShaderOutput)0;
        
    output.Position mul(input.Position WorldViewProjection);
        
    output.Texinput.Tex;
        return 
    output;
    }
     
    float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
    {
        return 
    tex2D(muestreadorinput.Tex.xy);
    }
     
    technique Technique1
    {
        
    pass Pass1
        
    {
            
    VertexShader compile vs_1_1 VertexShaderFunction();
            
    PixelShader compile ps_2_0 PixelShaderFunction();
        }

    No es complicado entender el código pero no entrare en mayores detalles porque recuerden que mi intención no es hacer un curso de Shaders, ya habrá tiempo para ello, por ahora el objetivo es aprender a aplicar el efecto de escala de grises y brindaré la información suficiente para que el artículo sea suficientemente entendible para todos.
    Una vez hecho el shader se debe preparar el código para utilizarlo, así que se debe declarar una referencia a un objeto Effect el cual he llamado shaderEffect, y en el método LoadContent adiciono este código de inicialización justo después de cargar la textura:
    Código PHP:
    Matrix tmpWorld Matrix.Identity Matrix.CreateTranslation(-0.5f1.7f0);
                
    Matrix tmpView Matrix.CreateLookAt(new Vector3(0,0,-10), new Vector3(0,0,1), Vector3.Up);
                
    Matrix tmpProjection Matrix.CreatePerspectiveFieldOfView(0.5f
                                                   
    Window.ClientBounds.WidthWindow.ClientBounds.Height
                                                   
    110);
     
                
    shaderEffect Content.Load<effect>("Efecto");
                
    shaderEffect.CurrentTechnique shaderEffect.Techniques["Technique1"];
                
    shaderEffect.Parameters["WorldViewProjection"].SetValue(tmpWorld tmpView tmpProjection);
                
    shaderEffect.Parameters["textura"].SetValue(textura); 
    Prácticamente es el mismo código que para BasicEffect pero con algunas diferencias menores, es importante recordar que el world ha sido inicializado con una traslación diferente para que la imagen de la textura quede justo al frente de la original. Otra cosa importante de notar es que a diferencia de los dos artículos anteriores donde lo que hice fue crear una copia de la textura, en este la copia solo se realiza a nivel de la memoria de video por lo cual no crearemos un nuevo Texture2D. (Esto en realidad es lo que lo hace increíblemente más rápido ya que todo el procesamiento se hace en la GPU)
    El código para dibujar en el método draw es básicamente replicar el anterior, adiciono esto justo debajo de effect.End():

    Código PHP:
    shaderEffect.Begin();
                foreach (
    EffectPass pass in shaderEffect.CurrentTechnique.Passes)
                {
                    
    pass.Begin();
                    
    GraphicsDevice.DrawUserPrimitives<vertexpositiontexture>(PrimitiveType.TriangleStripverts02);
                    
    pass.End();
                }
                
    shaderEffect.End(); 
    Ahora tengo esto:

    Shader para aplicar el efecto de escala grises

    Tal como lo mostré en los artículos anteriores, para convertir una imagen en escala de grises basta con sumar los componentes de color de cada pixel y distribuir la intensidad de color de manera proporcional a como nuestro ojo percibe los diferentes componentes de color, esto es 0.3R 0.59G 0.11B. Para hacer esto desde el shader vasta con modificar el PixelShader (en este caso PixelShaderFunction)de la siguiente forma:
    Código PHP:
    float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
    {
        
    float4 color tex2D(muestreadorinput.Tex.xy);
        
    color.rgb color.0.3 color.0.59 color.*.11;
        return 
    color;

    Y Listo! se ejecuta el programa y…:

    Hasta pronto!
Citar Citar  

  • #2
    Avatar de Latis
    Gamer Pro!
    GamerPoints: 3,064, Nivel: 8
    GamerPoints: 3,064, Nivel: 8
    Status : Latis está offline
    Fecha de Ingreso : Jun 2005
    Ubicación : Akihabara!
    Mensajes : 1,162
    Rep : Latis es una cantidad desconocida en este momento
    Gamer IDs

    PSN ID: L4TlS_ Steam ID: Mr_Portatil

    Thumbs up

    bastante interesante, pero me llamaron la atencion mas otros de los articulos de su blog. muchas gracias por tomarse el trabajo de hacerlos y ponerlos a disposicion de todos
    Citar Citar  

  • #3
    Avatar de -=MandoxS=-
    Gamer Pro!
    GamerPoints: 10,055, Nivel: 14
    GamerPoints: 10,055, Nivel: 14
    Status : -=MandoxS=- está offline
    Fecha de Ingreso : Jul 2004
    Mensajes : 4,271
    Rep : -=MandoxS=- va por un camino distinguido
    Gamer IDs

    Gamertag: MandoxS PSN ID: MandoxS Xfire ID: MandoxS Wii Code: 0403-0552-1323-5728

    Predeterminado

    Juank, como siempre muy bacanos tus aportes, chévere que estes posteando por estos lados!!!

    Bastante interesante el tema, saludos.
    AY PERO QUE RICURA DE VELOCIDAD EHH!!!!

    CONOCEME EN ESTE DOCUMENTAL
    Citar Citar  

  • + Responder Tema

    Información de Tema

    Usuarios Viendo este Tema

    Actualmente hay 1 usuarios viendo este tema. (0 miembros y 1 visitantes)

       

    Temas Similares

    1. Como ago?
      Por Zeiya en el foro FIFA
      Respuestas: 10
      Último Mensaje: 11-23-2006, 08:47 AM
    2. Como te enteraste de bw?
      Por Achece en el foro Starcraft x
      Respuestas: 34
      Último Mensaje: 09-09-2006, 09:35 PM
    3. Imagen de el Foro de Age of Empires ....
      Por ™ | AtaK en el foro Age of Empires X
      Respuestas: 16
      Último Mensaje: 12-21-2005, 09:08 PM

    Los visitantes llegaron a esta página buscando:

    convertir una imagen a escala de grises en c#

    tabla de tono de grises matrices

    shader xna 4.0

    convertir imagen a escala de grises en .net

    csharp escala de grises

    codigo en c# para cambiar una imagen de colores a escala de grises

    como pasar la imagen a escala de grises c#

    codigo en c para convertir una imagen a escala de grises

    ESCALAS DE COLOR RGB EN C#

    sacar matriz de una imagen en c sharp 2010

    xna fight code

    CREAR IMAGEN EN ESCALA DE GRISES CON C#

    codigo en c para suavisar una imagen

    shader color gris

    XNA 3.0 cargar archivos .fx

    funcion para obtener textura desde shader c3

    c# imagen rgb

    pasar imagen a matriz (0 1) c#

    como convertir imagen a matriz con c sharp

    como convierto escala de grises en c#

    effect.Texture xna 4.0

    convertir imagen escala de grices to rgb

    convertir una imagen en escala de grices word

    xna shader position.y

    convertir imagen a color a escala de grises en c

    Etiquetas para este Tema

    Permisos de Publicación

    • No puedes crear nuevos temas
    • No puedes responder temas
    • No puedes subir archivos adjuntos
    • No puedes editar tus mensajes