Skip to content

Commit

Permalink
Investigating fixed function pipelines, how RASC/RASA are set.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeltyPlayer committed Oct 14, 2021
1 parent 4d51df2 commit 34220d2
Show file tree
Hide file tree
Showing 11 changed files with 1,272 additions and 26 deletions.
129 changes: 110 additions & 19 deletions FinModelUtility/Bmd2Fbx/src/Exporter/BmdFixedFunctionMaterial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ public BmdFixedFunctionMaterial(

var colorManager = new ColorManager(equations);

// TODO: Where are colors set inside the materials?
// TODO: Where are color constants set inside the materials?
// TODO: Need to support registers
// TODO: Need to support multiple vertex colors
// TODO: Colors should just be RGB in the fixed function library

for (var i = 0; i < materialEntry.TevStageInfo.Length; ++i) {
var tevStageIndex = materialEntry.TevStageInfo[i];
Expand All @@ -66,6 +69,7 @@ public BmdFixedFunctionMaterial(
var tevOrderIndex = materialEntry.TevOrderInfo[i];
var tevOrder = bmd.MAT3.Tevorders[tevOrderIndex];

// Updates which texture is referred to by TEXC
var texStageIndex = tevOrder.TexMap;
if (texStageIndex == 255) {
colorManager.UpdateTextureColor(null);
Expand All @@ -85,11 +89,14 @@ public BmdFixedFunctionMaterial(
var texCoordIndex = materialEntry.Unknown1[tevOrder.TexcoordID];
texture.UvIndex = texCoordIndex;

colorManager.UpdateTextureColor(texCoordIndex);
material.SetTextureSource(texCoordIndex, texture);
}

// TODO: This seems to update which color RASC is referring to
//tevOrder.ChannelID;
// Updates which color is referred to by RASC
var colorChannel = tevOrder.ChannelID;
colorManager.UpdateRascColor(colorChannel);


// Set up color logic
{
Expand Down Expand Up @@ -121,7 +128,19 @@ public BmdFixedFunctionMaterial(

if (ccB != TevStage.GxCc.GX_CC_ZERO &&
ccC != TevStage.GxCc.GX_CC_ZERO) {
var term = colorB.Multiply(colorC);
IColorValue? term = null;

var isBOne = ccB == TevStage.GxCc.GX_CC_ONE;

if (!isBOne && isCOne) {
term = colorB;
} else if (isBOne && !isCOne) {
term = colorC;
} else {
term = colorB.Multiply(colorC);
}

Asserts.Nonnull(term);
colorValue = colorValue == null ? term : colorValue.Add(term);
}

Expand Down Expand Up @@ -212,51 +231,123 @@ public BmdFixedFunctionMaterial(
public IMaterial Material { get; }

private class ColorManager {
private readonly IFixedFunctionEquations<FixedFunctionSource> equations_;

private readonly IColorValue?[] textureColors_ = new IColorValue?[8];

private readonly Dictionary<TevOrder.ColorChannel, IColorValue>
colorChannelsColors_ = new();

private readonly Dictionary<TevStage.GxCc, IColorValue>
colorValues_ = new();

private readonly Dictionary<TevStage.GxCc, IScalarValue>
alphaValues_ = new();

private readonly IFixedFunctionEquations<FixedFunctionSource> equations_;

public ColorManager(
IFixedFunctionEquations<FixedFunctionSource> equations) {
this.equations_ = equations;

var colorZero = equations.CreateColorConstant(0, 0);
var colorOne = equations.CreateColorConstant(1);

this.colorValues_[TevStage.GxCc.GX_CC_TEXC] =
equations.CreateColorInput(FixedFunctionSource.TEXTURE, colorZero);
this.colorValues_[TevStage.GxCc.GX_CC_RASC] =
equations.CreateColorInput(FixedFunctionSource.VERTEX_COLOR,
colorZero);
this.colorValues_[TevStage.GxCc.GX_CC_RASA] =
equations.CreateColorInput(FixedFunctionSource.VERTEX_ALPHA,
colorZero);
this.colorValues_[TevStage.GxCc.GX_CC_ZERO] = colorZero;
this.colorValues_[TevStage.GxCc.GX_CC_ONE] = colorOne;
}

public void UpdateColorPrevious(IColorValue colorValue)
=> this.colorValues_[TevStage.GxCc.GX_CC_CPREV] = colorValue;

public void UpdateTextureColor(
/*public void UpdateTextureColor(
IColorNamedValue<FixedFunctionSource>? colorValue) {
if (colorValue != null) {
this.colorValues_[TevStage.GxCc.GX_CC_TEXC] = colorValue;
} else {
this.colorValues_.Remove(TevStage.GxCc.GX_CC_TEXC);
}
}*/

private int? textureIndex_ = null;

public void UpdateTextureColor(int? index) {
if (this.textureIndex_ != index) {
this.textureIndex_ = index;
this.colorValues_.Remove(TevStage.GxCc.GX_CC_TEXC);
this.colorValues_.Remove(TevStage.GxCc.GX_CC_TEXA);
}

if (index != null) {
Asserts.True(index >= 0 && index < 8);
}
}

private TevOrder.ColorChannel? colorChannel_;

public IColorValue GetColor(TevStage.GxCc colorSource)
=> this.colorValues_[colorSource];
public void UpdateRascColor(TevOrder.ColorChannel? colorChannel) {
if (this.colorChannel_ != colorChannel) {
this.colorChannel_ = colorChannel;
this.colorValues_.Remove(TevStage.GxCc.GX_CC_RASC);
this.colorValues_.Remove(TevStage.GxCc.GX_CC_RASA);
}
}

public IScalarValue GetAlpha(TevStage.GxCc alphaSource)
=> this.alphaValues_[alphaSource];
private IColorValue GetTextureColorChannel_() {
var indexOrNull = this.textureIndex_;
Asserts.Nonnull(indexOrNull);

var index = indexOrNull.Value;
Asserts.True(index >= 0 && index < 8);

var texture = this.textureColors_[index];
if (texture == null) {
this.textureColors_[index] =
texture = this.equations_.CreateColorInput(
(FixedFunctionSource) (FixedFunctionSource.TEXTURE_0 + index),
this.equations_.CreateColorConstant(0));
}

return this.colorValues_[TevStage.GxCc.GX_CC_TEXC] = texture;
}

private IColorValue GetVertexColorChannel_() {
var channelOrNull = this.colorChannel_;
Asserts.Nonnull(channelOrNull);

var channel = channelOrNull.Value;

if (!this.colorChannelsColors_.TryGetValue(channel, out var color)) {
var source = channel switch {
TevOrder.ColorChannel.GX_COLOR0A0 => FixedFunctionSource
.VERTEX_COLOR_ALPHA_0,
TevOrder.ColorChannel.GX_COLOR1A1 => FixedFunctionSource
.VERTEX_COLOR_ALPHA_1,
_ => throw new NotImplementedException()
};

this.colorChannelsColors_[channel] =
color = this.equations_.CreateColorInput(
source,
this.equations_.CreateColorConstant(0));
}

return this.colorValues_[TevStage.GxCc.GX_CC_RASC] = color;
}

public IColorValue GetColor(TevStage.GxCc colorSource) {
if (this.colorValues_.TryGetValue(colorSource, out var colorValue)) {
return colorValue;
}

if (colorSource == TevStage.GxCc.GX_CC_TEXC) {
return this.GetTextureColorChannel_();
}

if (colorSource == TevStage.GxCc.GX_CC_RASC) {
return this.GetVertexColorChannel_();
}

throw new NotImplementedException();
}
}
}
}
17 changes: 15 additions & 2 deletions FinModelUtility/Bmd2Fbx/src/misc/GCN/BMD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2358,16 +2358,29 @@ public class TevOrder
{
public byte TexcoordID;
public byte TexMap;
public byte ChannelID;
public ColorChannel ChannelID;
public byte Unknown;

public TevOrder(EndianBinaryReader er)
{
this.TexcoordID = er.ReadByte();
this.TexMap = er.ReadByte();
this.ChannelID = er.ReadByte();
this.ChannelID = (ColorChannel) er.ReadByte();
this.Unknown = er.ReadByte();
}

public enum ColorChannel {
GX_COLOR0,
GX_COLOR1,
GX_ALPHA0,
GX_ALPHA1,
GX_COLOR0A0,
GX_COLOR1A1,
GX_COLORZERO,
GX_BUMP,
GX_BUMPN,
GX_COLORNULL,
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Collections.Generic;

namespace fin.language.equations.fixedFunctionOld {
public interface IColorNamedValue<TIdentifier> : INamedValue<TIdentifier>,
IColorFactor {
IColorValue ColorValue { get; }
}

public interface IColorInput<TIdentifier> : IColorNamedValue<TIdentifier> {
IColorConstant DefaultValue { get; }
IColorConstant? CustomValue { get; set; }
}

public interface IColorOutput<TIdentifier> : IColorNamedValue<TIdentifier> {}

public enum ColorSwizzle {
R,
G,
B,
A,
}

public interface IColorNamedValueSwizzle<TIdentifier> : IScalarFactor {
IColorNamedValue<TIdentifier> Source { get; }
ColorSwizzle SwizzleType { get; }
}


public interface IColorValue {
IColorExpression Add(IColorValue term1, params IColorValue[] terms);
IColorExpression Subtract(IColorValue term1, params IColorValue[] terms);
IColorTerm Multiply(IColorValue factor1, params IColorValue[] factors);
IColorTerm Divide(IColorValue factor1, params IColorValue[] factors);

IColorExpression Add(IScalarValue term1, params IScalarValue[] terms);
IColorExpression Subtract(IScalarValue term1, params IScalarValue[] terms);
IColorTerm Multiply(IScalarValue factor1, params IScalarValue[] factors);
IColorTerm Divide(IScalarValue factor1, params IScalarValue[] factors);

IScalarValue? Intensity { get; }
IScalarValue R { get; }
IScalarValue G { get; }
IScalarValue B { get; }
IScalarValue A { get; }
IScalarValue? AOrNull { get; }
}

public interface IColorExpression : IColorValue {
IReadOnlyList<IColorValue> Terms { get; }
}

public interface IColorTerm : IColorValue {
IReadOnlyList<IColorValue> NumeratorFactors { get; }
IReadOnlyList<IColorValue>? DenominatorFactors { get; }
}

public interface IColorFactor : IColorValue {}

public interface IColorConstant : IColorFactor {
double? IntensityValue { get; }
double RValue { get; }
double GValue { get; }
double BValue { get; }
double? AValue { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Collections.Generic;

namespace fin.language.equations.fixedFunctionOld {
public interface IFixedFunctionEquations<TIdentifier> {
IScalarConstant CreateScalarConstant(double v);

IColorConstant CreateColorConstant(
double r,
double g,
double b,
double? a = null);

IColorConstant CreateColorConstant(
double intensity,
double? a = null);

IColorFactor CreateColor(IScalarValue r,
IScalarValue g,
IScalarValue b,
IScalarValue? a = null);

IColorFactor CreateColor(IScalarValue intensity,
IScalarValue? a = null);


IReadOnlyDictionary<TIdentifier, IScalarInput<TIdentifier>>
ScalarInputs { get; }

IScalarInput<TIdentifier> CreateScalarInput(
TIdentifier identifier,
IScalarConstant defaultValue);


IReadOnlyDictionary<TIdentifier, IScalarOutput<TIdentifier>>
ScalarOutputs { get; }

IScalarOutput<TIdentifier> CreateScalarOutput(
TIdentifier identifier,
IScalarValue value);


IReadOnlyDictionary<TIdentifier, IColorInput<TIdentifier>>
ColorInputs { get; }

IColorInput<TIdentifier> CreateColorInput(
TIdentifier identifier,
IColorConstant value);

IReadOnlyDictionary<TIdentifier, IColorOutput<TIdentifier>>
ColorOutputs { get; }

IColorOutput<TIdentifier> CreateColorOutput(
TIdentifier identifier,
IColorValue value);
}

public interface INamedValue<TIdentifier> {
TIdentifier Identifier { get; }
}
}
Loading

0 comments on commit 34220d2

Please sign in to comment.