示例#1
0
        private static string GetColorInString(GXCombineColorInput inputType, GXKonstColorSel konst, TevOrder texMapping)
        {
            switch (inputType)
            {
            case GXCombineColorInput.ColorPrev: return(m_tevOutputRegs[0] + ".rgb");

            case GXCombineColorInput.AlphaPrev: return(m_tevOutputRegs[0] + ".aaa");

            case GXCombineColorInput.C0: return(m_tevOutputRegs[1] + ".rgb");

            case GXCombineColorInput.A0: return(m_tevOutputRegs[1] + ".aaa");

            case GXCombineColorInput.C1: return(m_tevOutputRegs[2] + ".rgb");

            case GXCombineColorInput.A1: return(m_tevOutputRegs[2] + ".aaa");

            case GXCombineColorInput.C2: return(m_tevOutputRegs[3] + ".rgb");

            case GXCombineColorInput.A2: return(m_tevOutputRegs[3] + ".aaa");

            case GXCombineColorInput.TexColor: return(GetTexTapString(texMapping) + ".rgb");

            case GXCombineColorInput.TexAlpha: return(GetTexTapString(texMapping) + ".aaa");

            case GXCombineColorInput.RasColor: return(GetVertColorString(texMapping) + ".rgb");

            case GXCombineColorInput.RasAlpha: return(GetVertColorString(texMapping) + ".aaa");

            case GXCombineColorInput.One: return("1.0f.rrr");

            case GXCombineColorInput.Half: return("0.5f.rrr");

            case GXCombineColorInput.Konst: return(GetKonstColorString(konst) + ".rgb");

            case GXCombineColorInput.Zero: return("0.0f.rrr");

            default:
                WLog.Warning(LogCategory.TEVShaderGenerator, null, "Unknown Color Input type: {0}", inputType);
                return("0.0f.rrr");
            }
        }
示例#2
0
        private static string GetKonstColorString(GXKonstColorSel konst)
        {
            switch (konst)
            {
            case GXKonstColorSel.KCSel_1: return("1.0.rrrr");

            case GXKonstColorSel.KCSel_7_8: return("0.875.rrrr");

            case GXKonstColorSel.KCSel_3_4: return("0.75.rrrr");

            case GXKonstColorSel.KCSel_5_8: return("0.625.rrrr");

            case GXKonstColorSel.KCSel_1_2: return("0.5.rrrr");

            case GXKonstColorSel.KCSel_3_8: return("0.375.rrrr");

            case GXKonstColorSel.KCSel_1_4: return("0.25.rrrr");

            case GXKonstColorSel.KCSel_1_8: return("0.125.rrrr");

            case GXKonstColorSel.KCSel_K0: return("konst0.rgba");

            case GXKonstColorSel.KCSel_K1: return("konst1.rgba");

            case GXKonstColorSel.KCSel_K2: return("konst2.rgba");

            case GXKonstColorSel.KCSel_K3: return("konst3.rgba");

            case GXKonstColorSel.KCSel_K0_R: return("konst0.rrrr");

            case GXKonstColorSel.KCSel_K1_R: return("konst1.rrrr");

            case GXKonstColorSel.KCSel_K2_R: return("konst2.rrrr");

            case GXKonstColorSel.KCSel_K3_R: return("konst3.rrrr");

            case GXKonstColorSel.KCSel_K0_G: return("konst0.gggg");

            case GXKonstColorSel.KCSel_K1_G: return("konst1.gggg");

            case GXKonstColorSel.KCSel_K2_G: return("konst2.gggg");

            case GXKonstColorSel.KCSel_K3_G: return("konst3.gggg");

            case GXKonstColorSel.KCSel_K0_B: return("konst0.bbbb");

            case GXKonstColorSel.KCSel_K1_B: return("konst1.bbbb");

            case GXKonstColorSel.KCSel_K2_B: return("konst2.bbbb");

            case GXKonstColorSel.KCSel_K3_B: return("konst3.bbbb");

            case GXKonstColorSel.KCSel_K0_A: return("konst0.aaaa");

            case GXKonstColorSel.KCSel_K1_A: return("konst1.aaaa");

            case GXKonstColorSel.KCSel_K2_A: return("konst2.aaaa");

            case GXKonstColorSel.KCSel_K3_A: return("konst3.aaaa");

            default:
                WLog.Warning(LogCategory.TEVShaderGenerator, null, "Unsupported GXKonstColorSel: {0}, returning 1.0", konst);
                return("1.0");
            }
        }
        private static void WriteStage(StringBuilder stream, int stageIndex, Material mat, MAT3 data)
        {
            // Basic TEV Operation:
            // Inputs: [0 <= A, B, C <= 255] [-1024 <= D <= 1023]
            // Lerp between A and B using C as the interpolation factor. Optionally negate the result
            // using op. Input D and a bias (0, +0.5, -0.5) are added to the result. Then a constant
            // scale (1, 2, 4, 0.5) is applied. Result is optionally clamped before being written to
            // an output buffer.

            TevStage tevStage = mat.TevStages[stageIndex];
            TevOrder tevOrder = mat.TevOrders[stageIndex];

            stream.AppendFormat("\t// TEV Stage {0}\n", stageIndex);
            stream.AppendFormat("\t// Unknown0: {0} ColorInA: {1} ColorInB: {2} ColorInC: {3} ColorInD: {4} ColorOp: {5} ColorBias: {6} ColorScale: {7} ColorClamp: {8} ColorRegId: {9}\n", tevStage.Unknown0, tevStage.ColorIn[0], tevStage.ColorIn[1], tevStage.ColorIn[2], tevStage.ColorIn[3], tevStage.ColorOp, tevStage.ColorBias, tevStage.ColorScale, tevStage.ColorClamp, tevStage.ColorRegister);
            stream.AppendFormat("\t// AlphaInA: {0} AlphaInB: {1} AlphaInC: {2} AlphaInD: {3} AlphaOp: {4} AlphaBias: {5} AlphaScale: {6} AlphaClamp: {7} AlphaRegId: {8} Unknown1: {9}\n", tevStage.AlphaIn[0], tevStage.AlphaIn[1], tevStage.AlphaIn[2], tevStage.AlphaIn[3], tevStage.AlphaOp, tevStage.AlphaBias, tevStage.AlphaScale, tevStage.AlphaClamp, tevStage.AlphaRegister, tevStage.Unknown1);
            stream.AppendFormat("\t// Tev Order TexCoordId: {0} TexMap: {1} ChannelId: {2}\n", tevOrder.TexCoordId, tevOrder.TexMap, tevOrder.ChannelId);

            TevSwapMode      swapMode     = mat.TevSwapModes[stageIndex];
            TevSwapModeTable rasSwapTable = mat.TevSwapModeTables[swapMode.RasSel];
            TevSwapModeTable texSwapTable = mat.TevSwapModeTables[swapMode.TexSel];

            stream.AppendFormat("\t// TEV Swap Mode: RasSel: {0} TexSel: {1}\n", swapMode.RasSel, swapMode.TexSel);
            stream.AppendFormat("\t// Ras Swap Table: R: {0} G: {1} B: {2} A: {3}\n", rasSwapTable.R, rasSwapTable.G, rasSwapTable.B, rasSwapTable.A);
            stream.AppendFormat("\t// Tex Swap Table: R: {0} G: {1} B: {2} A: {3}\n", texSwapTable.R, texSwapTable.G, texSwapTable.B, texSwapTable.A);

            int  texcoord     = (int)tevOrder.TexCoordId;
            bool bHasTexCoord = (int)tevOrder.TexCoordId < mat.NumTexGens;

            // Build a Swap Mode for swapping texture color input/rasterized color input to the TEV Stage.
            string[] rasSwapModeTable = new string[4];
            string   swapColors       = "rgba";

            for (int i = 0; i < 4; i++)
            {
                char[] swapTable = new char[4];

                swapTable[0]        = swapColors[rasSwapTable.R];
                swapTable[1]        = swapColors[rasSwapTable.G];
                swapTable[2]        = swapColors[rasSwapTable.B];
                swapTable[3]        = swapColors[rasSwapTable.A];
                rasSwapModeTable[i] = new string(swapTable);
            }

            string[] texSwapModeTable = new string[4];
            for (int i = 0; i < 4; i++)
            {
                char[] swapTable = new char[4];

                swapTable[0]        = swapColors[texSwapTable.R];
                swapTable[1]        = swapColors[texSwapTable.G];
                swapTable[2]        = swapColors[texSwapTable.B];
                swapTable[3]        = swapColors[texSwapTable.A];
                texSwapModeTable[i] = new string(swapTable);
            }


            // ToDo: Implement Indirect Stages

            // If our TEV Stage uses rasterized alpha or color inputs
            if (tevStage.ColorIn[0] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[0] == GXCombineColorInput.RasColor ||
                tevStage.ColorIn[1] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[1] == GXCombineColorInput.RasColor ||
                tevStage.ColorIn[2] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[2] == GXCombineColorInput.RasColor ||
                tevStage.ColorIn[3] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[3] == GXCombineColorInput.RasColor ||
                tevStage.AlphaIn[0] == GXCombineAlphaInput.RasAlpha || tevStage.AlphaIn[1] == GXCombineAlphaInput.RasAlpha ||
                tevStage.AlphaIn[2] == GXCombineAlphaInput.RasAlpha || tevStage.AlphaIn[3] == GXCombineAlphaInput.RasAlpha)
            {
                stream.AppendFormat("\t// TEV Swap Mode\n");
                stream.AppendFormat("\trastemp = {0}.{1};\n", m_tevRasTable[(int)tevOrder.ChannelId], rasSwapModeTable[rasSwapTable.A]); // ToDo: No idea if this works.
            }

            if (tevOrder.TexCoordId != GXTexCoordSlot.Null)
            {
                int texmap = tevOrder.TexMap;
                if (true /* !bHasIndStage*/)
                {
                    if (bHasTexCoord)
                    {
                        stream.AppendFormat("\ttevcoord.xy = TexGen{0}.xy;\n", texcoord);
                    }
                    else
                    {
                        stream.AppendFormat("\ttevcoord.xy = vec2(0, 0);\n");
                    }
                }

                string texswap = texSwapModeTable[texSwapTable.A]; // Again, no idea if this works.

                stream.Append("\ttextemp = ");
                SampleTexture(stream, "vec2(tevcoord.xy)", texswap, texmap);
            }
            else
            {
                stream.AppendFormat("\ttextemp = vec4(1,1,1,1); // tevOrder specified no texture!\n");
            }

            if (tevStage.ColorIn[0] == GXCombineColorInput.Konst || tevStage.ColorIn[1] == GXCombineColorInput.Konst ||
                tevStage.ColorIn[2] == GXCombineColorInput.Konst || tevStage.ColorIn[3] == GXCombineColorInput.Konst ||
                tevStage.AlphaIn[0] == GXCombineAlphaInput.Konst || tevStage.AlphaIn[1] == GXCombineAlphaInput.Konst ||
                tevStage.AlphaIn[2] == GXCombineAlphaInput.Konst || tevStage.AlphaIn[3] == GXCombineAlphaInput.Konst)
            {
                GXKonstColorSel kc = mat.KonstColorSelectors[stageIndex];
                GXKonstAlphaSel ka = mat.KonstAlphaSelectors[stageIndex];
                stream.AppendFormat("\t// KonstColorSel: {0} KonstAlphaSel: {1}\n", kc, ka);
                stream.AppendFormat("\tkonsttemp = vec4({0}, {1});\n", m_tevKSelTableC[(int)kc], m_tevKSelTableA[(int)ka]);
            }

            stream.AppendFormat("\ttevin_a = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[0]], m_tevAInputTable[(int)tevStage.AlphaIn[0]]);
            stream.AppendFormat("\ttevin_b = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[1]], m_tevAInputTable[(int)tevStage.AlphaIn[1]]);
            stream.AppendFormat("\ttevin_c = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[2]], m_tevAInputTable[(int)tevStage.AlphaIn[2]]);
            stream.AppendFormat("\ttevin_d = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[3]], m_tevAInputTable[(int)tevStage.AlphaIn[3]]);

            // COLOR COMBINER
            stream.AppendFormat("\t// Color Combine\n");
            stream.AppendFormat("\t{0} = clamp(", m_tevCOutputTable[(byte)tevStage.ColorRegister]);
            if (tevStage.ColorOp == GXTevOp.Add || tevStage.ColorOp == GXTevOp.Sub)
            {
                WriteTevRegular(stream, "rgb", tevStage.ColorBias, tevStage.ColorOp, tevStage.ColorScale, tevStage.ColorClamp);
            }
            else
            {
                string[] opTable = new string[]
                {
                    "((tevin_a.r > tevin_b.r) ?  tevin_c.rgb : vec3(0,0,0))",                                // GXTevOp::Comp_R8_GT
                    "((tevin_a.r == tevin_b.r) ? tevin_c.rgb : vec3(0,0,0))",                                // GXTevOp::Comp_R8_EQ
                    "((dot(tevin_a.rgb, comp16) >  dot(tevin_b.rgb, comp16)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR16_GT
                    "((dot(tevin_a.rgb, comp16) == dot(tevin_b.rgb, comp16)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR16_EQ
                    "((dot(tevin_a.rgb, comp24) >  dot(tevin_b.rgb, comp24)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR24_GT
                    "((dot(tevin_a.rgb, comp24) == dot(tevin_b.rgb, comp24)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR24_EQ
                    "(max(sign(tevin_a.rgb - tevin_b.rgb), vec3(0,0,0)) * tevin_c.rgb)",                     // GXTevOp::Comp_RGB8_GT
                    "((vec3(1,1,1) - sign(abs(tevin_a.rgb - tevin_b.rgb))) * tevin_c.rgb)",                  // GXTevOp::Comp_RGB8_EQ
                };

                int index = (int)tevStage.ColorOp - 8;
                stream.AppendFormat("tevin_d.rgb + {0}", opTable[index]);
            }

            if (tevStage.ColorClamp)
            {
                stream.AppendFormat(", vec3(0,0,0), vec3(1,1,1))");
            }
            else
            {
                stream.AppendFormat(", vec3(-1024, -1024, -1024), vec3(1023, 1023, 1023))");
            }
            stream.AppendFormat(";\n");

            // ALPHA COMBINER
            stream.AppendFormat("\t// Alpha Combine\n");
            stream.AppendFormat("\t{0} = clamp(", m_tevAOutputTable[(byte)tevStage.AlphaRegister]);
            if (tevStage.AlphaOp == GXTevOp.Add || tevStage.AlphaOp == GXTevOp.Sub)
            {
                WriteTevRegular(stream, "a", tevStage.AlphaBias, tevStage.AlphaOp, tevStage.AlphaScale, tevStage.AlphaClamp);
            }
            else
            {
                string[] opTable = new string[]
                {
                    "((tevin_a.r > tevin_b.r) ?  tevin_c.a : 0)",                                   // GXTevOp::Comp_R8_GT
                    "((tevin_a.r == tevin_b.r) ? tevin_c.a : 0)",                                   // GXTevOp::Comp_R8_EQ
                    "((dot(tevin_a.rgb, comp16) >  dot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR16_GT
                    "((dot(tevin_a.rgb, comp16) == dot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR16_EQ
                    "((dot(tevin_a.rgb, comp24) >  dot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR24_GT
                    "((dot(tevin_a.rgb, comp24) == dot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR24_EQ
                    "((tevin_a.a >  tevin_b.a) ? tevin_c.a : 0)",                                   // GXTevOp::Comp_RGB8_GT
                    "((tevin_a.a == tevin_b.a) ? tevin_c.a : 0)",                                   // GXTevOp::Comp_RGB8_EQ
                };

                int index = (int)tevStage.AlphaOp - 8;
                stream.AppendFormat("tevin_d.a + {0}", opTable[index]);
            }

            if (tevStage.AlphaClamp)
            {
                stream.AppendFormat(", 0, 1)");
            }
            else
            {
                stream.AppendFormat(", -1024, 1023)");
            }
            stream.AppendFormat(";\n");
            stream.AppendLine();
        }