ATI_fragment_shader

Hello. I tried ATI_fragment_shader and I have some problems with my shader, code:

// Normal map
glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0, GL_SWIZZLE_STR_ATI);
// Normalisation cube map with light vectors
glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE2, GL_SWIZZLE_STR_ATI);

// N.L
glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                   GL_REG_0_ATI, GL_NONE, GL_NONE,
                                   GL_REG_1_ATI, GL_NONE, GL_NONE);

And that’s result: http://storm.unas.cz/my_shader.gif

Where is the mistake? Why doesn’t it work?

Scale and bias ? You’re probably encoding your normals in RGBA mapping [-1;1] to [0-255], you need to perform the inverse operation before you can do the dot3.

Y.

It doesn’t work in my engine so i rewrote it using GLUT and it works. I thing there is bad opengl state or something else in my engine. I will try to read the specification.

I found bug - i was binding invalid shader.

I have a problem, this shader does not work and i dont know why. It compute per-pixel lighting for 3 lights with 8 texture units. Is there any mistake?

        // result = (N.L1*A1 + N.L2*A2 + N.L3*A3 + Color) * Diffuse
        // (Lx = cube map with light vectors, Ax = attentuation map)
        // 1. PASS
        glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0, GL_SWIZZLE_STR_ATI);  // N
        glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1, GL_SWIZZLE_STR_ATI);  // L1
        glSampleMapATI(GL_REG_2_ATI, GL_TEXTURE2, GL_SWIZZLE_STR_ATI);  // A1
        glSampleMapATI(GL_REG_3_ATI, GL_TEXTURE3, GL_SWIZZLE_STR_ATI);  // L2
        glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4, GL_SWIZZLE_STR_ATI);  // A2

        // R1 = N.L1 * A1
        glColorFragmentOp2ATI(GL_DOT3_ATI,  GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_1_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI,
                                            GL_REG_0_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);
        
        glColorFragmentOp2ATI(GL_MUL_ATI,   GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_1_ATI, GL_NONE, GL_NONE,
                                            GL_REG_2_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);
        // R3 = N.L2 * A2
        glColorFragmentOp2ATI(GL_DOT3_ATI,  GL_REG_3_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_3_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI,
                                            GL_REG_0_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);
        
        glColorFragmentOp2ATI(GL_MUL_ATI,   GL_REG_3_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_3_ATI, GL_NONE, GL_NONE,
                                            GL_REG_4_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);

        // R1 = R1 + R3
        glColorFragmentOp2ATI(GL_ADD_ATI,   GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_1_ATI, GL_NONE, GL_NONE,
                                            GL_REG_3_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);

        // 2. PASS
        glSampleMapATI(GL_REG_1_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI); // N.L1*A1 + N.L2*A2
        glSampleMapATI(GL_REG_2_ATI, GL_TEXTURE5, GL_SWIZZLE_STR_ATI);  // L3
        glSampleMapATI(GL_REG_3_ATI, GL_TEXTURE6, GL_SWIZZLE_STR_ATI);  // A3
        glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE7, GL_SWIZZLE_STR_ATI);  // Diffuse

        // R2 = N.L3 * A3
        glColorFragmentOp2ATI(GL_DOT3_ATI,  GL_REG_2_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_2_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI,
                                            GL_REG_0_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);
        
        glColorFragmentOp2ATI(GL_MUL_ATI,   GL_REG_2_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_2_ATI, GL_NONE, GL_NONE,
                                            GL_REG_3_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);

        // R0 = R1 + R2
        glColorFragmentOp2ATI(GL_ADD_ATI,   GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_1_ATI, GL_NONE, GL_NONE,
                                            GL_REG_2_ATI, GL_NONE, GL_NONE);
        
        // R0 = R0 + Color
        glColorFragmentOp2ATI(GL_ADD_ATI,   GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_0_ATI, GL_NONE, GL_NONE,
                                            GL_PRIMARY_COLOR, GL_NONE, GL_NONE);

        // R0 = R0 * Diffuse
        glColorFragmentOp2ATI(GL_MUL_ATI,   GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                            GL_REG_0_ATI, GL_NONE, GL_NONE,
                                            GL_REG_4_ATI, GL_NONE, GL_BIAS_BIT_ATI|GL_2X_BIT_ATI);

IIRC, the R300 class of hardware does only support 6 texture units. The fragment_shader_ATI extension was written around such type of cards, so this may be the reason why it doesn’t work. Otherwise debug your code line by line to see where “the shader does not work”.

IIRC, the R300 class of hardware does only support 6 texture units.
Correction: the R200. But the rest of your logic makes sense given the correction. The use of ATI_fragment_shader probably does not expose the 10 more texture units that R300+ cards have. Unfortunate, I guess, but nVidia did the same thing with texture_shader+RC.

Damn, your right Korval. R200 of course. Seems like i was almost sleeping yesterday :slight_smile: