Jump to content


cg shading: problem with resolutions


1 reply to this topic

#1 M1tchke

    New Member

  • Members
  • Pip
  • 1 posts

Posted 18 March 2009 - 11:33 AM

Hi,

I'm new to this forum, so goodday to all :)


I'm having a problem with a cg shader, i'm new to cg shaders so it could be a easy fix.


I'm making a screen distorter. I have a couple of splines that distort the image and then send texture coordinate info (in a texture, with help of the RGBA values) to the shader. Actually the coordinates are delta's which i add to the original texture coordinates

This works great when the texture coordinate map is, let's say 1024*1024 and the image where the coordinates are applied to, is the same resolution.

But when the resolution from the texture coordinate map is different from the resolution of the image, artifacts show up.

The problem is that the texture coordinate texture must be a power of 2, so it's always 512*512, 1024*1024, 1024*2048, ... those kind of resolutions. And the image to where i apply the coordinates must have a 1280*800 resolution.

how i tried to solve it:

i tried to put texture coordinates of the same resolution as the image (1280*800 reso) in a bigger map, so i had for example 1280*800 texture coordinates in a map of 2048*1024. In the shader, i added this values to the original texture coordinate values (vin.tc0 += Distort) but this didn't seemed to work. My texture got resized somehow, and it still had artifacts

I even tried to switch to absolute texture coordinates instead of sending deltas to the shader, but i still got artifacts (different ones though).


in short:

It's just a resolution problem. it would be great if i could 'cut' the size of a texture in the shader, so the shader wouldn't "resize" the original texture coordinates.
i get the best result when adding 1024*1024 tex coord info to the custom image resolution, but still with disturbing artifacts.

here's the shader code:



struct VertOut
{
	float2 tc0 : TEXCOORD0;
};

struct FragOut
{
	float4 col : COLOR;
};

FragOut main(
  VertOut vin,
	uniform sampler2D baseMap  : TEXUNIT0,
	uniform sampler2D pixelMap : TEXUNIT1
)
{
  FragOut OUT;

  float4 col;
  
  // Distort texture coordinates 
  float4 tcDistort4;

  tcDistort4=tex2D(pixelMap,vin.tc0);
  
  // TC's are stored in 2x 16-bit numbers, which are passed to us as floats
  // Convert RG and BA back from floats to a 16-bit floating point value
  float2 tcDistort;

  // Range: 655356 (2^16)
  tcDistort.x=tcDistort4.r+tcDistort4.g*0.00390625;
  tcDistort.y=tcDistort4.b+tcDistort4.a*0.00390625;


  //do another small conversion so i can send negative values
  tcDistort=(tcDistort-0.5)*2.0;

  //add the distorted delta's to the original texture coordinates 
  tcDistort+=vin.tc0;
  
  //make the new texture with the old map and the new tex coords
  col=tex2D(baseMap,tcDistort); 

  OUT.col=col;

  return OUT;
} 



i would very much appreciate your help.

thx !

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 4969 posts
  • LocationBellevue, WA

Posted 18 March 2009 - 04:23 PM

First of all, you should be able to use a 1280x800 (or whatever size) texture, so long as you don't expect mipmapping to work with it. In OpenGL this is called a "texture rectangle" (GL_TEXTURE_RECTANGLE) and uses texRECT instead of tex2D in the shader. Alternatively, if it's a newish graphics card it probably does support non-power-of-two textures with plain old tex2D, as well.

However, the size of the render target aside, your "unpacking" logic is slightly wrong. It's a subtle issue, but GPUs actually use a mapping for 8-bit color components where 255 is mapped to 1.0 exactly, not 255/256 = 0.9961 as it would be for a true 0.8 fixed point. In other words, when you read RGBA values from a texture, the GPU is effectively multiplying each value by 256/255 = 1.0039 when it converts it to a float.

So, in order to correctly unpack the values, you should scale the RGBA by 255/256 before running your existing unpacking logic. This undoes the GPU's automatic scaling and gets you back to the values you expected.

Also, you haven't shown your original packing logic, but you need to be aware of endianness - if the texture is RGBA and you're on a little-endian (i.e. Intel) processor, you'll need to swap the bytes in each 16-bit value before storing. If this part is wrong it could produce much bigger artifacts than the unpacking problem above. :)
reedbeta.com - developer blog, OpenGL demos, and other projects





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users