inaccurate texture sampling

Hi,

I am trying to sample one whole texture for each fragment in the fragmentshader but the way I do it seems to be very inaccurate. I am having a GL_TEXTURE_2D which is 1px high and lets say 8px wide. I set it up like this:


glGenTextures(1,  (GLuint*)&posTex); 
	
	posTexWidth = 8*4; //8pixels with 4 channels
	
	glBindTexture(GL_TEXTURE_2D,  posTex);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB, posTexWidth, 1, 0, GL_RGBA, GL_FLOAT, data);


this is what I do in the fragmentshader:


uniform float attribTexFormat; //width of the texture in pixels
float tlTexelSize = 1.0/attribTexFormat;
float doSomeThing(){
	for(int x=0; x<int(attribTexFormat); x++){
			texHolder = texture2D(posTex, vec2(float(x)*tlTexelSize, 0.0));
...
	}
}
void main(){
...
}

I expect this code to read each pixel of the texture exactly once, but there seem to be inaccuracies which read one pixel twice and skip others. Is there something I am doing obviously wrong here? I also tried to replace GL_CLAMP in my texture setup with CLAMP_TO_EDGE and REPEAT without any success.

Okay, I just checked that if the texture width is power of two, it works just fine. Shouldn’t it be possible to work with any size though?

8 is already power of two.
But you have to aim for texel centers, not edges :
vec2((float(x)+0.5)*tlTexelSize, 0.5/1.0)

thank you so much, it works! I am trying to implement spatial hashing on the GPU and this simple mistake was causing me a headache for 24 hours yesterday!

Hey,

Another question about texCoords occured to me. I init one of my lookup textures to the maximum size needed which is eg. 1024x1px. Now I want to update the texture content using glTexSubImage2D like this:


glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, data);

so that I dont have to reallocate memory for the texture each time I update it. Since the needed pixels will most likely be less than the allocated number of pixels I thought I could simply calculate a factor like this to adjust my texel size in the shader:


uint32 maxSize = 1024;
uint32 size = 512;
float factor = (float)size/(float)maxSize;

then in the shader:


uniform float attribTexRatio; //same as factor from above
uniform float attribTexFormat; //width of texture in pixels 512 in this case

float tlTexelSize = (attribTexRatio/attribTexFormat);

then I do the texture lookups as described by zBuffer before, but unfortunatelly it does not work. I am propably missing something simple again!

if I reallocate the whole texture each time and set the texel size to 1.0/attribTexFormat it works fine, but as stated I would like to avoid that.

Thanks!

okay, it was another bug, the sampling worked just fine, sorry and thanks :slight_smile: