texRECT and shaders

Started by
6 comments, last by Bruno 18 years ago
Hi., What i'm tryng to do, is a simple post-processing effect, only on some surfaces of the game (glass,etc). So, what i do is i capture the framebuffer to a rectangle texture, and then i want to distort it using a normal map (2d regular texture). This is the CG shader:

void main(
float4 TexCoord0 : TEXCOORD0,
float4 TexCoord1 : TEXCOORD1,
out half4 oColor : COLOR,
uniform float timer,
uniform samplerRECT Texture0,
uniform sampler2D Texture1
)
{
	float3 noiseVec;
	float2 displacement;

	displacement = TexCoord0.xy;
	displacement.x += timer;
	displacement.y += timer;

	noiseVec = normalize(tex2D(Texture1, displacement.xy));
	noiseVec = (noiseVec.xyz * 2.0 - 1.0) * 0.035;
	oColor = texRECT(Texture0, TexCoord0.xy + noiseVec.xy);
}

The result that i have, is a simple offset of the texture, and nothing else. I tried replacing the rectangle texture with a 2d texture, and it seems to be working, but i really need to use a rectangle texture, so, it seems this is not the correct way to use rectangle textures ? Anyone sees a problem in the shader ? And just for clarity, i'm enabling GL_TEXTURE_RECTANGLE_NV, and GL_TEXTURE1_ARB.
Advertisement
Hi...

In the shader, you are using the same (or at least similar) texture coord for both the normalmap and the rect texture. This means that one of them must be wrong because 2D textures want texcoords in the range [0, 1]x[0, 1] and rect textures in the range [0, width]x[0, height] (for TEXTURE_RECTANGLE_NV).

I think ARB_non_power_of_two lets you have rect textures with [0,1] texcoords, but i'm not sure about that.

HellRaiZer
HellRaiZer
thanks HellRaizer,

Actually, i haven't tought about the texture coordinates range, but in the shader, i don't think i'm using the same for both.., the rect texture is using Texture0, and the normalmap\noiseVec is using Texture1.

Maybe the error is here ?


glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,noise.data);

glEnable(GL_TEXTURE_RECTANGLE_NV);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, screenCopy.data);


glBegin(GL_QUADS);
glMultiTexCoord2fARB(GL_TEXTURE_RECTANGLE_NV,0,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
glVertex2i(0 ,0);

glMultiTexCoord2fARB(GL_TEXTURE_RECTANGLE_NV,1024,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,0);
glVertex2i(1024 ,0);

glMultiTexCoord2fARB(GL_TEXTURE_RECTANGLE_NV,1024,768);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,1);
glVertex2i(1024,768);

glMultiTexCoord2fARB(GL_TEXTURE_RECTANGLE_NV,0,768);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,1);
glVertex2i(0 ,768);
glEnd();
Quote:Original post by Bruno
Actually, i haven't tought about the texture coordinates range, but in the shader, i don't think i'm using the same for both.., the rect texture is using Texture0, and the normalmap\noiseVec is using Texture1.
In your shader you are assigning displacement to TexCoord0.xy before adding timer instead of TexCoord1.xy which is what I assume you want to use.

EDIT: Also, the target parameter of glMultiTexCoord2f "must be one of GL_TEXTUREi, where 0 ≤ i < GL_MAX_TEXTURE_UNITS, which is an implementation-dependent value." Replace those GL_TEXTURE_RECTANGLE_NVs in there with GL_TEXTURE0 (or GL_TEXTURE0_ARB if you prefer).

EDIT2: This isn't a big deal, but there is an ARB version of texture rectangles. It's the same thing as the EXT and NV versions except it has additions to GLSL (which is what you're using). Even the defines are the same, but it's a good idea to use the proper ones anyway. Again it's not a big deal in this case.
Yeah, you guys are right..,
I made the changes in the shader, but still, i'm getting no distortion, i don't get this.., i'm sure the problem is in the fact that i'm using a rectangle texture.

Quote:EDIT: Also, the target parameter of glMultiTexCoord2f "must be one of GL_TEXTUREi, where 0 ≤ i < GL_MAX_TEXTURE_UNITS, which is an implementation-dependent value." Replace those GL_TEXTURE_RECTANGLE_NVs in there with GL_TEXTURE0 (or GL_TEXTURE0_ARB if you prefer).


Thanks, i wasn't sure about using GL_TEXTURE_RECTANGLE_NV there either, i'l remove it but i already tried that too .., and no changes.
Whoops... ignore part of my EDIT2 above. I just realized you're not using GLSL. You should still use the ARB defines instead of the NV ones though.

Another thing I just noticed now is setting noiseVec looks a little odd. I don't think you should be normalizing what you read from the texture. Assuming it is a normal RGB texture it will be clamped to [0,1]. So you should scale and bias that directly to [-1,1]. Then I think it should be unit length if the normal you output to the normal map was unit length, so I don't think you need to normalize it. And I guess the scaling by 0.035 is because that's the amount you want to offset the texture coordinates. Now the big problem with this is that your noiseVec will be in the range [-0.035, 0.035] and, again, the non-normalized texture coordinate range of the rectangular texture makes that small of an offset not really affect the result all that much. I think scaling the x component of noiseVec by the texture's width and the y component by the texture's height might work for you. That might not give the "correct" result (I'm not sure) because it's a non-uniform scaling of the normal, but you should be able to see something happen then.
Quote:
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,noise.data);

// MISSING LINE HERE
// glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_RECTANGLE_NV);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, screenCopy.data);
...


I don't know if this is a typo (you forgot the line) but you must set the active texture to 0 for the rectangle texture before you bind it.

And i think Kalidor is correct about the texcoords.

HellRaiZer
HellRaiZer
oh well, can't get this working with texture rectangles, no matter what i do.,
I made a offscreen rendering to a pbuffer with the texture rectangle , and copied it to a regular 2d texture, and everything is working now.

This topic is closed to new replies.

Advertisement