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

Sampling textures in HLSL

Last post 3/7/2007 2:07 PM by cronholio. 10 replies.
  • 3/7/2007 3:12 AM

    Sampling textures in HLSL

    I want to sample a texture stored in a register on the graphicsDevice at multiple UV locations within an effect. I can sample this texture at the current UV location fine, but if I try to create another sampler at a different UV location it doesn't work. Here's what the effect looks like:

     

    //the width and height of the current screen

    float Width;

    float Height;

    //the texture sampler

    sampler ColSampler : register(s1);

    struct VS_OUTPUT

    {

        float2 uv[2]   : TEXCOORD0;

    }

    VS_OUTPUT vsMain( float2 uv : TEXCOORD )

    {

        float WidthOffset = 1.0/Width;

        float HeightOffset = 1.0/Height;

        VS_OUTPUT o;

        o.uv[0] = uv;

        o.uv[1] = uv + float2( WidthOffset, HeightOffset );

        return o;

        float WidthOffset = 1.0/Width;

        float HeightOffset = 1.0/Height;

        VS_OUTPUT o;

        o.uv[0] = uv;

        o.uv[1] = uv + float2( WidthOffset, HeightOffset );

        return o;

        float WidthOffset = 1.0/Width;

        float HeightOffset = 1.0/Height;

        VS_OUTPUT o;

        o.uv[0] = uv;

        o.uv[1] = uv + float2( WidthOffset, HeightOffset );

        return o;

    }

    float4 psMain(VS_OUTPUT i) : COLOR0

    {

        float4 col = tex2D(ColSampler, i.uv[0]); //This works fine

        float4 col = tex2D(ColSampler, i.uv[1]); //This always returns black

    ...

    }

    On a possibly related note, how can I set the sampler state on a texture that is stored in a register? It possible I may try to smaple UVs greater than 1 or less than 0, so I want to wrap the texture. Everything I've tried gives a syntax error when I compile.

  • 3/7/2007 7:18 AM In reply to

    Re: Sampling textures in HLSL

    Can you get it working if both value are set to the same value without the offset? Maybe there's something wrong with the offset calculation and you're going off the end of the texture? I don't know enough about using arrays in HLSL, but I've done something like the following before:

    //the width and height of the current screen

    float Width;

    float Height;

    //the texture sampler

    sampler ColSampler : register(s1);

    struct VS_OUTPUT

    {

        float2 uv1   : TEXCOORD0;

        float2 uv2   : TEXCOORD1;

    }

    VS_OUTPUT vsMain( float2 uv : TEXCOORD )

    {

        float WidthOffset = 1.0/Width;

        float HeightOffset = 1.0/Height;

        VS_OUTPUT o;

        o.uv1 = uv;

        o.uv2 = uv + float2( WidthOffset, HeightOffset );

        return o;

        float WidthOffset = 1.0/Width;

        float HeightOffset = 1.0/Height;

        VS_OUTPUT o;

        o.uv1 = uv;

        o.uv2 = uv + float2( WidthOffset, HeightOffset );

        return o;

     

    }

    float4 psMain(VS_OUTPUT i) : COLOR0

    {

        float4 col = tex2D(ColSampler, i.uv1); //This works fine

        float4 col = tex2D(ColSampler, i.uv2); //This always returns black

    ...

    }

    Bill Reiss - Dr. Popper currently in peer review

    XNA Tutorials for Beginners
  • 3/7/2007 7:38 AM In reply to

    Re: Sampling textures in HLSL

    The array is something I saw in the Shader X books. I tried making individual uv coords as well and the result is the same. Basicly, I can't sample anything other than the current uv location if that makes any sense. If I try to add or subract from u or v, it just doesn't draw the texture at all.

    I thought maybe overrunning the UV boundaries would be a problem, so I added a check to make sure U and V were both greater than zero and less than 1. It didn't work. Thinking maybe my Width and Height values weren't being set, I tried adding just 0.1 to U which you would think would shift the image... no good. I tried to force the shader to always sample the same pixel in the center of the texture... no good. Like I said it only let's me sample at the current uv coordinates.

    I'm wondering if something is wrog with my graphics card or something.

  • 3/7/2007 8:08 AM In reply to

    Re: Sampling textures in HLSL

    Now we are getting somewhere. I tried just loading some random texture and passing it into the shader without using registers. I can sample it where ever I want. So the problem seems to be using textures that are in registers.

    The question now becomes how can I pass a texture that has been generated from a render target into a shader without using registers? I tried doing this before, could not get it to work. I asked on the MSDN forums and Shawn Hargraves pointed me to the mutlitexturing example on this site which uses registers.

  • 3/7/2007 8:25 AM In reply to

    Re: Sampling textures in HLSL

    I just wanted to clarify, are you talking about using shaders without using the Effect system? Also what sample are you talking about?

     Cheers,
    Leaf.
     

  • 3/7/2007 8:28 AM In reply to

    Re: Sampling textures in HLSL

    I now have a solution, but I don't like it. I have two textures, one which I will only sample at the current coords, and one I need to sample wherever.. I have to pass the one I want to randomly sample into the shader attached to the sprite, and the other I pass through a register. I am going to work with this, but if anyone can give me a better solution I'm all ears.
  • 3/7/2007 8:36 AM In reply to

    Re: Sampling textures in HLSL

    JunkMailer:

    I just wanted to clarify, are you talking about using shaders without using the Effect system? Also what sample are you talking about?

     Cheers,
    Leaf.
     

     

    What is the difference between a shader an the effect system? I have an fx file that contains a vertex and pixel shader and a technique... is that the effects system?

    The sample is here:

    http://creators.xna.com/Headlines/developmentaspx/archive/2007/02/13/Sprite-Effects-Sample.aspx

    The sample covers multitexturing with sprites. Textures are passed to shaders through registers. The problem seems to be that when a texture is in a register you cannot sample it at arbitrary coordinates. I don't know how it works, but I'm guessing the register doesn't store the whole texture, just the current texel.

  • 3/7/2007 9:39 AM In reply to

    Re: Sampling textures in HLSL

    Ah, I understand now. I was wondering why you were using a register. That sample uses registers to fit in with SpriteBatch drawing, it's basically replacing the SpriteBatch pixel shader. The texture that you pass in to SpriteBatch.Draw() is set to use register s0, so any additional textures should use another sampler register.

    Note, samplers always use registers. The syntax you are using is just to tell the system exactly which register to use. So it shouldn't make any difference.

    If you are using the shader with a SpriteBatch then you shouldn't be replacing the vertex shader. If you aren't using SpriteBatch I don't see why you need to specify the sampler register.

    Perhaps you could explain a little more about what it is you are actually trying to do.

    Cheers,
    Leaf.

  • 3/7/2007 10:06 AM In reply to

    Re: Sampling textures in HLSL

    Basicly I'm doing some NPR rendering. I'm trying to implement and edge detector I wrote into HLSL

    I render the whole 3D scene with diffuse shaders and put it in a color texture.

    I render the whole scene again using shaders that produce Normals, Depth and IDs in the RGB channels and store that into another texture.

    I then have a full screen sprite which is being rendered through an effect. I attach the normal/depth/id texture to the sprite (which I guess is s0 like you say) and I set the color texture to s1. I then do edge detection on the normal/z/id and add the result to the color texture and draw that on the sprite.

    Based on what you are saying there's no reason why I shouldn't be able to arbitrarily sample any texture in any register. Thing is though, I can't seem to make arbitrary sampling work at all on any texture unless I attach it to the sprite directly, or pass it into the shader as a texture. Maybe it had something to do with trying to create UVs in the Vertex shader.

    I am no longer using the vertex shader for anything. I am creating the UV coordinates in the pixel shader and everything is working well. I just don't quite understand why things must be done the way I am currently doing it.

    Thanks for reading all this...

  • 3/7/2007 1:29 PM In reply to

    Re: Sampling textures in HLSL

    Is this your whole vertex shader code? It could not run in this form as you don’t have a position in your output.

  • 3/7/2007 2:07 PM In reply to

    Re: Sampling textures in HLSL

    No, not all the code. I just posted the relevant bits to the problem I was having.
Page 1 of 1 (11 items) Previous Next