XNA Creators Club Online
Page 1 of 1 (9 items)
Sort Posts: Previous Next

Two textures with different co-ordinates in one pixel shader.

Last post 1/31/2008 6:02 AM by David Johnston. 8 replies.
  • 1/30/2008 8:59 AM

    Two textures with different co-ordinates in one pixel shader.

    I currently have a shader effect which I'd like to pass two different textures into.  I also want to use TEXCOORD0 and TEXCOORD1 to specify the different texture co-ordinates for each texture.  I only want to render a small quad from the first texture (which is 512x512 pixels) so the co-ordinates are something like (64,64), (128, 64), (128, 128), (64,128).  I want to wrap the second texture so the co-ordinates end up being in a completely different space.  It's a 128x128 pixel image and the co-ordinates for this one might be (100, 100), (500, 100), (500, 500), (100, 500).

    By the time my co-ordinates get to the pixel shader they been mapped to the range (0..1) rather than (0..texsize).  The trouble is this mapping only seems to be based on the first texture so TEXCOORD0 is fine but TEXCOORD1 gets completely distorted.

    I'm passing both textures as constants to the shader.  Is there any way to specify how this mapping occurs or do I just need to add some constant parameters to perform the transformation myself.

    Cheers,

        Dave

     

    http://www.smudgedcat.com
  • 1/30/2008 11:47 AM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Your description of the problem is a little unclear, so I can't be sure that what I'm saying applies to your situation but here goes.

    Texture coordinates are usually given in the range 0-1. The pixel shader commands (e.g. tex2D()) that read from a texture expect that 0,0 is one corner of the texture and 1,1 the opposite corner, values outside the range 0-1 are wrapped or clamped depending on the sampler states. If you want to use texture coordinates in a different scale then you will have to map them to the 0-1 range before use (e.g. u * (1.0/texWidth), v * (1.0/texHeight)).

    If you need more help perhaps you could say a little more about what it is you're doing.
  • 1/30/2008 12:25 PM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Thanks for the response Leaf.  Looks like my problem is why I have to specify the texture co-ordinates in pixels.  I'm definitely specifying pixels in the XNA code which end up being in the range [0..1] in the pixel shader.  I'm not using a vertex shader, does anyone know if the default one would perform a mapping like this somehow?

    Cheers,

        Dave

     

    http://www.smudgedcat.com
  • 1/30/2008 12:43 PM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Are you using SpriteBatch? That has a built in vertex shader which converts the rectangles you pass in into 0..1 range?
    Play Kissy Poo - a game for 4 year olds on Xbox and windows
    The ZBuffer
    News and information for XNA
      Follow The Zman on twitter, Email me
        Please read the forum FAQs - Bug/Feature reporting
          Don't forget to mark good answers and good playtest feedback when you see it!!!
  • 1/30/2008 3:11 PM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    The ZMan [MVP/Moderator]:
    Are you using SpriteBatch? That has a built in vertex shader which converts the rectangles you pass in into 0..1 range?

    No, I'm calling DrawUserPrimitives() using my own vertex type consisting of VertexElementUsage.Position(0), VertexElementUsage.TextureCoordinate(0) and VertexElementUsage.TextureCoordinate(1).

    Dave

     

     

    http://www.smudgedcat.com
  • 1/30/2008 4:33 PM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Answer
    Reply Quote
    David Johnston:

    I'm not using a vertex shader, does anyone know if the default one would perform a mapping like this somehow?



    Are you sure you haven't set a vertex shader? On this laptop at least, calling DrawUser*() without a vertex shader fails. Using a vertex shader that maps the pixel scale texture coords into 0-1 works fine for me, so I suggest you do something like that.
  • 1/30/2008 7:58 PM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Answer
    Reply Quote
    There is no such thing as a default vertex shader. If you don't explicitly set a shader, you just get whatever was left over by whoever previously did set a vertex shader. Most likely, this means you will be picking up the SpriteBatch vertex shader (which scales texcoord0 from pixels into texture units, does not pass through texcoord1 at all, and on Xbox, does crazy stuff to the vertex position in order to implement hardware instancing for drawing sprite quads as fast as possible), but it could equally well be something previously used by a BasicEffect, or whatever else was drawn right before the object in question.

    It's obviously not a good idea to rely on this: you always need to set both the vertex and pixel shader before you draw anything.
    XNA Framework Developer - blog - homepage
  • 1/30/2008 8:57 PM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Hi,

    I think you should look into your shader code (the fx file) and see how it is transforming/scaling the textures you are passing to it. I looked at a shader (from NVidia) wich takes two textures and creates a bump map effect with them. It uses two textures (in a different way compared with your description), but it may be help in understanding how the fx code uses them.

    Here's a piece of the shader code, with the Parameters names, and how they are scaled in the shader:

    texture ColorTexture : DIFFUSE <
    string ResourceName = "rockwall.jpg";
    string UIName = "Color Texture";
    string ResourceType = "2D";
    >;

    sampler2D ColorSampler = sampler_state {
    Texture = <ColorTexture>;
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
    };

    texture ReliefTexture : NORMAL <
    string ResourceName = "rockwall.tga";
    string UIName = "Normal-Map Texture";
    string ResourceType = "2D";
    >;

    sampler2D ReliefSampler = sampler_state {
    Texture = <ReliefTexture>;
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
    };

    In other shader samples, they uses Clamp to scale AddressU (same with V and W), like this:

    texture EnvTexture : ENVIRONMENT <
    string ResourceName = "default_reflection.dds";
    string UIName = "Environment";
    string ResourceType = "Cube";
    >;

    samplerCUBE EnvSampler = sampler_state {
    Texture = <EnvTexture>;
    MagFilter = Linear;
    MinFilter = Linear;
    MipFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
    AddressW = Clamp;
    };

     

    I'm guessing this Clamp and/or Wrap functions, the parameters asignement to the passed textures and how they are processed in the Pixel and Vertex shader may have something to do with your issue.

  • 1/31/2008 6:02 AM In reply to

    Re: Two textures with different co-ordinates in one pixel shader.

    Shawn Hargreaves:
    There is no such thing as a default vertex shader. If you don't explicitly set a shader, you just get whatever was left over by whoever previously did set a vertex shader. Most likely, this means you will be picking up the SpriteBatch vertex shader (which scales texcoord0 from pixels into texture units, does not pass through texcoord1 at all, and on Xbox, does crazy stuff to the vertex position in order to implement hardware instancing for drawing sprite quads as fast as possible), but it could equally well be something previously used by a BasicEffect, or whatever else was drawn right before the object in question.

    It's obviously not a good idea to rely on this: you always need to set both the vertex and pixel shader before you draw anything.

    That would explain it!  Thanks to Leaf's suggestion I've added a vertex shader and got everything working but it's good to know exactly why I was getting such wierd results.

    I think I managed to fall into this trap because I was originally using a SpriteBatch but then changed to use DrawUserPrimitives.  I did wonder if I needed a vertex shader but since I was getting *something* I assumed there was some kind of default that was just passing everything through.

    Thanks for everyone's expert help as always!

    Cheers,

        Dave

     

    http://www.smudgedcat.com
Page 1 of 1 (9 items) Previous Next