PDA

View Full Version : strange ATI_FRAGMENT_SHADER + 3D texture behaviour



COZE
01-22-2004, 03:52 AM
Probably it is some my stupid bug, but I dont know where is the problem.
Im going to to lookup 3D luminance12 texture (texture1) in to 2D RGBA texture (texture2) with width 2 and height 2048.
I hope that shader is correct :




glBeginFragmentShaderATI();

//sample volume in to reg1
glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
//if( reg1 > 0.5)reg3 = 1; else reg3 = 0;
glColorFragmentOp3ATI(GL_CND_ATI, GL_REG_3_ATI, GL_NONE,GL_NONE,
GL_ONE, GL_NONE,GL_NONE,
GL_ZERO, GL_NONE,GL_NONE,
GL_REG_1_ATI, GL_RED,GL_NONE);

//reg2 = 2*reg1 - reg3; //T coordinate
glColorFragmentOp2ATI(GL_SUB_ATI, GL_REG_2_ATI, GL_NONE,GL_NONE,
GL_REG_1_ATI, GL_NONE,GL_2X_BIT_ATI,
GL_REG_3_ATI, GL_NONE,GL_NONE);

//set S tex coordinate
glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_2_ATI, GL_RED_BIT_ATI,GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE);

//sample from lookup texunit 2
glSampleMapATI(GL_REG_2_ATI, GL_REG_2_ATI, GL_SWIZZLE_STR_ATI);
//move result
glColorFragmentOp1ATI(GL_MOV_ATI,GL_REG_0_ATI,GL_N ONE,GL_NONE,GL_REG_2_ATI,GL_NONE,GL_NONE);

glEndFragmentShaderATI();



I Activate texture units, set texture transformation, but I see strange blinnking thins. But when I glEnable(GL_TEXTURE_3D), not after ActiveTextureARB ,
I see something not correkt but it approach what it should be. It looks that there are some problems with texture coordinates.

The same code with ARB_FRAGMENT_PROGRAM with 1D lookup texture, also with blending work pretty nice.
Please try to give me some tip what do I wrong.

zeckensack
01-22-2004, 05:20 AM
ATI_fragment_shader is based on a "phase" architecture. To perform a dependent read, you need to enter a new phase (of which there are only two in ATI_fs). Entering a new phase by default discards all register contents. You need to explicitly "pass" your computed texcoords into the "output phase".

So, immediately before glSampleMapATI, add the following line:

glPassTexCoordATI(GL_REG_2_ATI,GL_REG_2_ATI,GL_SWI ZZLE_STR_ATI);

zeckensack
01-22-2004, 05:34 AM
The shader can also be 'optimized' a bit.


glBeginFragmentShaderATI();
//sample volume in to reg1
glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
//if( reg1 > 0.5)reg2 = 1; else reg2 = 0;
glColorFragmentOp3ATI(GL_CND_ATI, GL_REG_2_ATI,GL_NONE,GL_NONE,
GL_ONE,GL_NONE,GL_NONE,
GL_ZERO,GL_NONE,GL_NONE,
GL_REG_1_ATI, GL_RED,GL_NONE);
//reg2.green = 2*reg1 - reg2; //T coordinate
glColorFragmentOp2ATI(GL_SUB_ATI, GL_REG_2_ATI,GL_GREEN_BIT_ATI,GL_NONE,
GL_REG_1_ATI,GL_NONE,GL_2X_BIT_ATI,
GL_REG_2_ATI,GL_NONE,GL_NONE);
//S coord is already in place

//begin second phase
glPassTexCoordATI(GL_REG_2_ATI,GL_REG_2_ATI,GL_SWI ZZLE_STR_ATI);
//sample from lookup texunit 2

glSampleMapATI(GL_REG_0_ATI, GL_REG_2_ATI, GL_SWIZZLE_STR_ATI);
//result is already in ouput register
glEndFragmentShaderATI();

COZE
01-22-2004, 07:08 AM
Thaks for reply.
Yes I forgot this, but it still dont work. If I good undetand the specification in the second pass dst = regX of glSampleMapATI() mean that result will be in regx, textunit X will be sampled with coordinates specified in interp argument.
So in case which you write textunit 0 with coordinates in reg2 will be sampled in reg0.
I did it this way, but I thing that I have some bug somewhere in Texture unit definition.
I try do this



glBeginFragmentShaderATI();

//sample volume in to reg1
glSampleMapATI(GL_REG_1_ATI,GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
//move result
glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE);

glEndFragmentShaderATI();

So simle map texture. And it still do crazy thing. Just when I somewhere in draw funcion call glEnable(GL_Texture_3D) it works. :-(

zeckensack
01-22-2004, 07:36 AM
You're right, my apologies. The last 'optimization' is invalid, because the destination register selects the texture unit to be sampled. So scratch that.

Also, unlike ARB_fragment_program, ATI_fs uses the legacy texture target priority system. Ie, you can have only one texture per "texture unit", it must be enabled, and the higer ranking texture targets for that unit must be disabled.
Priority goes like this IIRC:
1D < 2D < rect < 3D < cubemap

So indeed, you must enable the 3D texture to sample it.

What's your setup code? The shader needs the following to work as intended


glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_3D,your_luminance_texture );
glEnable(GL_TEXTURE_3D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,your_rgba_texture);
glEnable(GL_TEXTURE_2D);

Note that you must not enable the GL_TEXTURE_3D target for unit 2.

If your textures are bound to different units (GL_TEXTURE0_ARB and GL_TEXTURE1_ARB would seem natural) then you must adjust the shader's register usage accordingly.

COZE
01-23-2004, 08:31 AM
Thans, I got it.
When I disable all texture targets, except actual one for the unit it works.
But I was surprised, that is necessary call



glAlphaFragmentOp1ATI(GL_MOV_ATI,GL_REG_0_ATI,GL_N ONE,GL_REG_1_ATI,GL_ALPHA,GL_NONE);

after sampling RGBA texture in reg0???
But now it works. Thank for help.