Citace Původně odeslal Fox!MURDER Zobrazit příspěvek
priznavam predem (doufam ze me nekdo opravi/doplni) ze nevim, jak vypada programovani shaderu v tuhle chvili, ale takova prdestava driveru, kterej obsahuje (napr.) C compiler, kterej Ceckovej zdrojak shaderu prechrousta do strojaku konkretni grafiky, tak aby tam sel spustit ...
No, jenom tak pro info sem něco málo přispěju - spíš ale tak pro zajímavost. V jedné hře na které jsem spolupracoval jsem teď vytáhl ze zdrojáků kousky shader kódu. Protože tenkrát byly běžné shader 1.x karty (Radeon8500,9000-9200, GF3Ti, GF4Ti, GF4MX) a shadery tehda nebyly ještě standardizované, tak se muselo dělat víc codepath. Schválně se můžete kouknout na rozdíl zápisu pro karty nvidia a ati. Jako první kousek je už standardizovaný kód Pixel Shaderu 2.0. Tohle je low level možnost programování. Krom toho lze Shadery 2.0 (a vyšší programovat) i ve vyšším jazyce (hlsl, cg), kdy se pak překompilovávaj. To už by se tak trochu dalo přirovnat k tomu Cčku. Ale jako stále to ještě neni ono na univerzální vecičky, toho se vážně dosáhne až u přicházející generace karet jako je G80, přesně jak je to uvedené v tom článku, že tam bude extra driver, který bude schopen nechat kartu provádět Cčkový kód.

Kód:
----- arb ps 2.0 -----

        const char diffuse_prg_asm[] =
            "!!ARBfp1.0\n"

            "TEMP tex, col;"
            "ATTRIB texcoord = fragment.texcoord;"
            "ATTRIB primcol = fragment.color.primary;"
            "PARAM light_col = program.local[0];"
            "PARAM consts = {2, -1, 0, 0};"
            "OUTPUT outcol = result.color;"

            "TEX tex, texcoord, texture, 2D;"
            "MAD tex, tex, consts.x, consts.y;"
            "MAD col, primcol, consts.x, consts.y;"

            "DP3 col.a, tex, col;"
            "MUL tex, light_col, primcol.a;"
            "MUL outcol, tex, col.a;"

            "END";
        glGenProgramsARB(1, &diffuse_prg);
        glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, diffuse_prg);
        glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
            strlen(diffuse_prg_asm), diffuse_prg_asm);

----- ati ps 1.x -----

        diffuse_prg = glGenFragmentShadersATI(1);
        glBindFragmentShaderATI(diffuse_prg);
        glBeginFragmentShaderATI();
        // Pass #1:
        glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);  // color in the texture
        // reg0 = L.H
        glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
                                           GL_REG_0_ATI, GL_NONE, GL_BIAS_BIT_ATI | GL_2X_BIT_ATI,
                                           GL_PRIMARY_COLOR_ARB, GL_NONE, GL_BIAS_BIT_ATI | GL_2X_BIT_ATI);
        // reg0 = reg0 * con0 = (L.H) * light_color
        glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
                                          GL_REG_0_ATI, GL_NONE, GL_NONE,
                                          GL_CON_0_ATI, GL_NONE, GL_NONE);
        // reg0 = reg0 * primary_color.alpha = (L.H) * light_color * intensity
        glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
                                          GL_REG_0_ATI, GL_NONE, GL_NONE,
                                          GL_PRIMARY_COLOR_ARB, GL_ALPHA, GL_NONE);
        glEndFragmentShaderATI();

------ nv ps 1.x ------

       //setup the register combiners to use 1 general combiner (max. 2 on GF 4 MX)
       glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1);
       //setup the combiner 1
       glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
       GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB);
       glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
              GL_PRIMARY_COLOR_NV, GL_EXPAND_NORMAL_NV, GL_RGB);
       glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV,
              GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
       glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV,
              GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
       glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_SPARE1_NV,
              GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE);
       //setup the final combiner
       glFinalCombinerInputNV(GL_VARIABLE_A_NV,
              GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
       glFinalCombinerInputNV(GL_VARIABLE_B_NV,
              GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
       glFinalCombinerInputNV(GL_VARIABLE_C_NV,
              GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
       glFinalCombinerInputNV(GL_VARIABLE_D_NV,
              GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
       glFinalCombinerInputNV(GL_VARIABLE_G_NV,
              GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
       glEnable(GL_REGISTER_COMBINERS_NV);
Jinak ten kód je na výpočet difuzní barvy u perpixel (dot3) osvětlení (třeba jako má Doom3 a kdejaká dnešní hra). Výpočet spekulární barvy jsem vyhodil, aby to nebylo zbytečně dlouhé. Tohle je spíš pro rozšíření obzorů.

Petrik: Ty tvoje poslední posty jsou přesně to o čem jsem mluvil.