diff --git a/Effects/EffectHelpers.cs b/Effects/EffectHelpers.cs new file mode 100644 index 0000000..e2618cb --- /dev/null +++ b/Effects/EffectHelpers.cs @@ -0,0 +1,14 @@ +using System; + +namespace Smuggler +{ + [Flags] + internal enum EffectDirtyFlags + { + WorldViewProj = 1, + World = 2, + EyePosition = 4, + ShaderIndex = 8, + All = -1 + } +} \ No newline at end of file diff --git a/Effects/PBREffect.cs b/Effects/PBREffect.cs index 025d05c..eec2796 100644 --- a/Effects/PBREffect.cs +++ b/Effects/PBREffect.cs @@ -83,6 +83,8 @@ namespace Smuggler bool metallicRoughnessMapEnabled = false; bool normalMapEnabled = false; + EffectDirtyFlags dirtyFlags= EffectDirtyFlags.All; + // FIXME: lazily set properties for performance public Matrix World @@ -91,15 +93,7 @@ namespace Smuggler set { world = value; - worldParam.SetValue(world); - - Matrix.Multiply(ref world, ref view, out Matrix worldView); - Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj); - worldViewProjectionParam.SetValue(worldViewProj); - - Matrix.Invert(ref world, out Matrix worldInverse); - Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose); - worldInverseTransposeParam.SetValue(worldInverseTranspose); + dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj; } } @@ -109,13 +103,7 @@ namespace Smuggler set { view = value; - - Matrix.Multiply(ref world, ref view, out Matrix worldView); - Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj); - worldViewProjectionParam.SetValue(worldViewProj); - - Matrix.Invert(ref view, out Matrix inverseView); - eyePositionParam.SetValue(inverseView.Translation); + dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition; } } @@ -125,10 +113,7 @@ namespace Smuggler set { projection = value; - - Matrix.Multiply(ref world, ref view, out Matrix worldView); - Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj); - worldViewProjectionParam.SetValue(worldViewProj); + dirtyFlags |= EffectDirtyFlags.WorldViewProj; } } @@ -185,7 +170,7 @@ namespace Smuggler { albedoTextureParam.SetValue(value); albedoTextureEnabled = value != null; - System.Console.WriteLine(albedoTextureEnabled); + dirtyFlags |= EffectDirtyFlags.ShaderIndex; } } @@ -196,6 +181,7 @@ namespace Smuggler { normalTextureParam.SetValue(value); normalMapEnabled = value != null; + dirtyFlags |= EffectDirtyFlags.ShaderIndex; } } @@ -218,6 +204,7 @@ namespace Smuggler { metallicRoughnessTextureParam.SetValue(value); metallicRoughnessMapEnabled = value != null; + dirtyFlags |= EffectDirtyFlags.ShaderIndex; } } @@ -287,41 +274,73 @@ namespace Smuggler return new PBREffect(this); } - // FIXME: do param applications here for performance protected override void OnApply() { - int shaderIndex = 0; + if ((dirtyFlags & EffectDirtyFlags.World) != 0) + { + worldParam.SetValue(world); - if (albedoTextureEnabled && metallicRoughnessMapEnabled && normalMapEnabled) - { - shaderIndex = 7; - } - else if (metallicRoughnessMapEnabled && normalMapEnabled) - { - shaderIndex = 6; - } - else if (albedoTextureEnabled && normalMapEnabled) - { - shaderIndex = 5; - } - else if (albedoTextureEnabled && metallicRoughnessMapEnabled) - { - shaderIndex = 4; - } - else if (normalMapEnabled) - { - shaderIndex = 3; - } - else if (metallicRoughnessMapEnabled) - { - shaderIndex = 2; - } - else if (albedoTextureEnabled) - { - shaderIndex = 1; + Matrix.Invert(ref world, out Matrix worldInverse); + Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose); + worldInverseTransposeParam.SetValue(worldInverseTranspose); + + dirtyFlags &= ~EffectDirtyFlags.World; } - shaderIndexParam.SetValue(shaderIndex); + if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0) + { + Matrix.Multiply(ref world, ref view, out Matrix worldView); + Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj); + worldViewProjectionParam.SetValue(worldViewProj); + + dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; + } + + if ((dirtyFlags & EffectDirtyFlags.EyePosition) != 0) + { + Matrix.Invert(ref view, out Matrix inverseView); + eyePositionParam.SetValue(inverseView.Translation); + + dirtyFlags &= ~EffectDirtyFlags.EyePosition; + } + + if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0) + { + int shaderIndex = 0; + + if (albedoTextureEnabled && metallicRoughnessMapEnabled && normalMapEnabled) + { + shaderIndex = 7; + } + else if (metallicRoughnessMapEnabled && normalMapEnabled) + { + shaderIndex = 6; + } + else if (albedoTextureEnabled && normalMapEnabled) + { + shaderIndex = 5; + } + else if (albedoTextureEnabled && metallicRoughnessMapEnabled) + { + shaderIndex = 4; + } + else if (normalMapEnabled) + { + shaderIndex = 3; + } + else if (metallicRoughnessMapEnabled) + { + shaderIndex = 2; + } + else if (albedoTextureEnabled) + { + shaderIndex = 1; + } + + shaderIndexParam.SetValue(shaderIndex); + + dirtyFlags &= ~EffectDirtyFlags.ShaderIndex; + } } void CacheEffectParameters(PBREffect cloneSource)