private static string GetModString(byte outputRegIndex, GXTevBias bias, GXTevScale scale, bool clamp, bool isAlpha) { float biasVal = 0f; float scaleVal = 1f; switch (bias) { case GXTevBias.Zero: biasVal = 0f; break; case GXTevBias.AddHalf: biasVal = 0.5f; break; case GXTevBias.SubHalf: biasVal = -0.5f; break; } switch (scale) { case GXTevScale.Scale_1: scaleVal = 1f; break; case GXTevScale.Scale_2: scaleVal = 2f; break; case GXTevScale.Scale_4: scaleVal = 4f; break; case GXTevScale.Divide_2: scaleVal = 0.5f; break; } // If we're not modifying it, early out. if (scaleVal == 1f && biasVal == 0f && !clamp) { return(""); } string channelSelect = isAlpha ? ".a" : ".rgb"; string dest = m_tevOutputRegs[outputRegIndex] + channelSelect; StringBuilder sb = new StringBuilder(); if (scaleVal == 1f && biasVal == 0f) { // result = saturate(result) sb.AppendLine(string.Format("{0} = clamp({0},0.0,1.0);", dest)); } else { // result = saturate(result * scale + bias * scale) sb.AppendLine(string.Format("{0} = clamp({0} * {1} + {2} * {1},0.0, 1.0);", dest, scaleVal, biasVal)); } return(sb.ToString()); }
private static string GetAlphaOpString(GXTevOp op, GXTevBias bias, GXTevScale scale, bool clamp, byte outputRegIndex, string[] alphaInputs) { string channelSelect = ".a"; string dest = m_tevOutputRegs[outputRegIndex] + channelSelect; StringBuilder sb = new StringBuilder(); switch (op) { case GXTevOp.Add: case GXTevOp.Sub: { // out_color = (d + lerp(a, b, c)); - Add // out_color = (d - lerp(a, b, c)); - Sub string compareOp = (op == GXTevOp.Add) ? "+" : "-"; sb.AppendLine(string.Format("{0} = ({1} {5} mix({2}, {3}, {4}));", dest, alphaInputs[3], alphaInputs[0], alphaInputs[1], alphaInputs[2], compareOp)); sb.AppendLine(GetModString(outputRegIndex, bias, scale, clamp, true)); } break; case GXTevOp.Comp_A8_EQ: case GXTevOp.Comp_A8_GT: { // out_color = (d + ((a.a > b.a) ? c : 0)) string compareOp = (op == GXTevOp.Comp_R8_GT) ? ">" : "=="; sb.AppendLine(string.Format("{0} = ({1} + (({2} {5} {3}) ? {4} : 0))", dest, alphaInputs[3], alphaInputs[0], alphaInputs[1], alphaInputs[2], compareOp)); } break; default: WLog.Warning(LogCategory.TEVShaderGenerator, null, "Unsupported op in GetAlphaOpString: {0}", op); sb.AppendLine("// Invalid Alpha op for TEV broke here."); break; } if (op == GXTevOp.Comp_A8_GT || op == GXTevOp.Comp_A8_EQ) { // if(bias != 3 || scale != 1 || clamp != 1) // warn unexpected bias/scale/etc } return(sb.ToString()); }
public TevStage(GXCombineColorInput[] colInput, GXTevOp colOp, GXTevBias colBias, GXTevScale colScale, bool colClamp, byte colRegID, GXCombineAlphaInput[] alphIn, GXTevOp alphOp, GXTevBias alphBias, GXTevScale alphScale, bool alphClamp, byte alphRegID) { ColorIn = colInput; ColorOp = colOp; ColorBias = colBias; ColorScale = colScale; ColorClamp = colClamp; ColorRegId = colRegID; AlphaIn = alphIn; AlphaOp = alphOp; AlphaBias = alphBias; AlphaScale = alphScale; AlphaClamp = alphClamp; AlphaRegId = alphRegID; Unknown0 = 0xFF; Unknown1 = 0xFF; }
private static string GetColorOpString(GXTevOp op, GXTevBias bias, GXTevScale scale, bool clamp, byte outputRegIndex, string[] colorInputs) { string channelSelect = ".rgb"; string dest = m_tevOutputRegs[outputRegIndex] + channelSelect; StringBuilder sb = new StringBuilder(); switch (op) { case GXTevOp.Add: case GXTevOp.Sub: { // out_color = (d + lerp(a, b, c)); - Add // out_color = (d - lerp(a, b, c)); - Sub string compareOp = (op == GXTevOp.Add) ? "+" : "-"; sb.AppendLine(string.Format("{0} = ({1} {5} mix({2}, {3}, {4}));", dest, colorInputs[3], colorInputs[0], colorInputs[2], colorInputs[1], compareOp)); sb.AppendLine(GetModString(outputRegIndex, bias, scale, clamp, false)); } break; case GXTevOp.Comp_R8_GT: case GXTevOp.Comp_R8_EQ: { // out_color = (d + ((a.r > b.r) ? c : 0)); string compareOp = (op == GXTevOp.Comp_R8_GT) ? ">" : "=="; sb.AppendLine(string.Format("{0} = ({1} + (({2}.r {5} {3}.r) ? {4} : 0))", dest, colorInputs[3], colorInputs[0], colorInputs[1], colorInputs[2], compareOp)); } break; case GXTevOp.Comp_GR16_GT: case GXTevOp.Comp_GR16_EQ: { // out_color = (d + (dot(a.gr, rgTo16Bit) > dot(b.gr, rgTo16Bit) ? c : 0)); string compareOp = (op == GXTevOp.Comp_GR16_GT) ? ">" : "=="; string rgTo16Bit = "vec2(255.0/65535.6, 255.0 * 256.0/65535.0)"; sb.AppendLine(string.Format("{0} = ({1} + (dot({2}.gr, {3}) {4} dot({5}.gr, {3}) ? {6} : 0));", dest, colorInputs[3], colorInputs[0], rgTo16Bit, compareOp, colorInputs[1], colorInputs[2])); } break; case GXTevOp.Comp_BGR24_GT: case GXTevOp.Comp_BGR24_EQ: { // out_color = (d + (dot(a.bgr, bgrTo24Bit) > dot(b.bgr, bgrTo24Bit) ? c : 0)); string compareOp = (op == GXTevOp.Comp_BGR24_GT) ? ">" : "=="; string bgrTo24Bit = "vec3(255.0/16777215.0, 255.0 * 256.0/16777215.0, 255.0*65536.0/16777215.0)"; sb.AppendLine(string.Format("{0} = ({1} + (dot({2}.bgr, {5}) {6} dot({3}.bgr, {5}) ? {4} : 0));", dest, colorInputs[3], colorInputs[0], colorInputs[1], colorInputs[2], bgrTo24Bit, compareOp)); } break; case GXTevOp.Comp_RGB8_GT: case GXTevOp.Comp_RGB8_EQ: { // out_color.r = d.r + ((a.r > b.r) ? c.r : 0); // out_color.g = d.g + ((a.g > b.g) ? c.g : 0); // out_color.b = d.b + ((a.b > b.b) ? c.b : 0); string compareOp = (op == GXTevOp.Comp_RGB8_GT) ? ">" : "=="; string format = "{0}.{6} = {1}.{6} + (({2}.{6} {5} {3}.{6}) ? {4}.{6} : 0);"; sb.AppendLine(string.Format(format, dest, colorInputs[3], colorInputs[0], colorInputs[1], colorInputs[2], compareOp, "r")); sb.AppendLine(string.Format(format, dest, colorInputs[3], colorInputs[0], colorInputs[1], colorInputs[2], compareOp, "g")); sb.AppendLine(string.Format(format, dest, colorInputs[3], colorInputs[0], colorInputs[1], colorInputs[2], compareOp, "b")); } break; default: WLog.Warning(LogCategory.TEVShaderGenerator, null, "Unsupported Color Op: {0}!", op); sb.AppendLine("// Invalid Color op for TEV broke here."); break; } if (op > GXTevOp.Sub) { //if(bias != 3 || scale != 0 || clamp != 1) // warn(unexpected bias, scale, clamp)...? } return(sb.ToString()); }
private static void WriteTevRegular(StringBuilder stream, string components, GXTevBias bias, GXTevOp op, GXTevScale scale, bool clamp) { string[] tevScale = new[] { " * 1", // GXTevScale::Scale_1 " * 2", // GXTevScale::Scale_2 " * 4", // GXTevScale::Scale_4 " * 0.5" // GXTevScale::Divide_2 }; string[] tevBias = new[] { "", // GXTevBias::Zero " + 0.5", // GXTevBias::AddHalf " - 0.5", // GXTevBias::SubHalf "" }; string[] tevOpTable = new[] { "+", // GXTevOp::Add "-", // GXTevOp::Sub }; // Regular TEV stage: ((d + bias) + lerp(a,b,c)) *scale // lerp(a, b, c) op (d + bias) * scale //stream.AppendFormat("(mix(tevin_b.{0}, tevin_a.{0}, tevin_c.{0})", components); // lerp(a, b, c) stream.AppendFormat("(((tevin_a.{0} * (vec4(1,1,1,1).{0} - tevin_c.{0}) + tevin_b.{0} * tevin_c.{0})", components); stream.AppendFormat(" {0} ", tevOpTable[(int)op]); // "+/-" (op) stream.AppendFormat("(tevin_d.{0}{1})", components, tevBias[(int)bias]); // (d + bias) stream.AppendFormat("){0})", tevScale[(int)scale]); }