optimize PBR effect setters

PBR
cosmonaut 2020-08-04 01:14:45 -07:00
parent 4a5f0d4461
commit 39fec5062c
2 changed files with 84 additions and 51 deletions

14
Effects/EffectHelpers.cs Normal file
View File

@ -0,0 +1,14 @@
using System;
namespace Smuggler
{
[Flags]
internal enum EffectDirtyFlags
{
WorldViewProj = 1,
World = 2,
EyePosition = 4,
ShaderIndex = 8,
All = -1
}
}

View File

@ -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)