Forum

Reconfigure rows of texture in HLSL

Hi Guys,

is there any way to reconfigure the rows of a texture in HLSL?
For example from 32x32 to 1024x1 pixels.

Thanks.

Ari

Sure, in a shader you’ll just need to read from transformed texture coordinates

  1. use VPOS semantic on input to get texel positions you are rendering to
  2. transform x position (since you are rendering to a single-row-texture) to 2d vector to read from your 32x32 texture

this could look like:

float4 PS(float2 vp:VPOS):COLOR{
    float2 TransformedCd=(float2(vp.x%32,(vp.x-(vp.x%32))/32.0)+0.5)/32.0;
    return tex2D(Sampler,TransformedCd);
}

(0.5 there is a halfpixel offset, for accurate read from texel centers)

Hi Unc,
thanks a lot for the explanation but as always it seems that i´m doing something wrong.

I´m using 2 data textures, one with 1024x1 pixels, and the other with 32x32 pixels that i need to transform to 1024x1 pixels.

Any idea?

The code looks like that:

//VERTEXSHADER
vs2ps VS(
    float4 PosO  : POSITION ,
    float4 TexCd : TEXCOORD0 )
{
    //declare output struct
    vs2ps Out ;

    //transform position
    Out.Pos = mul(PosO, tW) ;

    //transform texturecoordinates
    Out.TexCd = TexCd;

    return Out;
}
//PIXELSHADER

float4 PS2(float2 vp:VPOS):COLOR
    {
    float2 TransformedCd=(float2(vp.x%32,(vp.x-(vp.x%32))/32.0)+0.5)/32.0;
    return tex2D(SampTarget2,TransformedCd);
    }
float4 PS(vs2ps In): COLOR
{

float4 oldData = tex2D(SampLastFrame,In.TexCd);
float4 targetTex = tex2D(SampTarget,In.TexCd);
float4 targetTex2 = tex2D(SampTarget2,In.TexCd); //Texture to be transformed,
                                                 //but i can´t use TransformedCd ?¿
float4 targetData = tex2D(SampLastFrame, float2(In.TexCd.x, In.TexCd.y-ry));

if (In.TexCd.y>0)  ////Verlet simulation
         {
         float2 distVec = targetData.rg - oldData.rg;

         oldData.rg += (length(distVec)-targetTex.b) * Damper * normalize(distVec) ;
         
         }
         else
         {
         oldData = float4 (targetTex2.rg,targetTex.ba) ;
         }
         
if (targetTex.a)
   {
    oldData.rg = targetTex2.rg;
   }

return  oldData ;
}

Thanks again,

ari.

Well, everything depends on what are you rendering it to… My guess was, that you render to 1024x1 texture - if that is correct, probably this could work:

float4 PS(vs2ps In,float2 vp:VPOS): COLOR //now you have VPOS on input,
{
 
float4 oldData = tex2D(SampLastFrame,In.TexCd);
float4 targetTex = tex2D(SampTarget,In.TexCd);
float2 TransformedCd=(float2(vp.x%32,(vp.x-(vp.x%32))/32.0)+0.5)/32.0; 
// and can use TransformedCd
float4 targetTex2 = tex2D(SampTarget2,In.TexCd);
float4 targetData = tex2D(SampLastFrame, float2(In.TexCd.x, In.TexCd.y-ry));
...

otherwise, you might re-render your 32x32 texture to 1024x1 (using that small shader)

Hi Unc,
finally i´ve made other render pass with this shader to resample the texture, but i´m limited to 4096x1 pixels, nevertheless it would be great to do the conversion inside the shader to avoid this limitation.

Anyway, thanks for your useful information, i´m learning a lot about shaders.

Ari.

Resample shader.

float4x4 tW: WORLD;        //the models world matrix

//texture
texture Tex <string uiname="Texture";>;
sampler Samp = sampler_state    //sampler for doing the texture-lookup
{
    Texture   = (Tex);          //apply a texture to the sampler
    MipFilter = none;         //sampler states
    MinFilter = none;
    MagFilter = none;
};

float4x4 tTex: TEXTUREMATRIX <string uiname="Texture Transform";>;
float XResol <string uiname="XResol";>;

struct vs2ps
{
    float4 Pos  : POSITION;
    float2 TexCd : TEXCOORD0;
};

// --------------------------------------------------------------------------------------------------
// VERTEXSHADERS
// --------------------------------------------------------------------------------------------------
vs2ps VS(
    float4 PosO  : POSITION,
    float4 TexCd : TEXCOORD0)
{
    //declare output struct
    vs2ps Out;

    //transform position
    Out.Pos = mul(PosO, tW);
    
    //transform texturecoordinates
    Out.TexCd = TexCd;

    return Out;
}

// --------------------------------------------------------------------------------------------------
// PIXELSHADERS:
// --------------------------------------------------------------------------------------------------

float4 PS(vs2ps In,float2 vp:VPOS): COLOR //now you have VPOS on input,
{
    float2 TransformedCd=(float2(vp.x%XResol,(vp.x-(vp.x%XResol))/XResol)+0.5)/XResol;;
    //float4 targetTex2 = tex2D(TransformedCd,In.TexCd)
	return tex2D(Samp,TransformedCd.rg);
}

// --------------------------------------------------------------------------------------------------
// TECHNIQUES:
// --------------------------------------------------------------------------------------------------

technique TSimpleShader
{
    pass P0
    {
        //Wrap0 = U;  // useful when mesh is round like a sphere
        VertexShader = compile vs_3_0 VS();
        PixelShader  = compile ps_3_0 PS();
    }
}