2020-08-27 18:14:17 +00:00
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
|
|
|
|
namespace Kav
|
|
|
|
{
|
|
|
|
public class DeferredPBR_GBufferEffect : Effect, TransformEffect
|
|
|
|
{
|
|
|
|
EffectParameter worldParam;
|
2020-12-07 21:50:32 +00:00
|
|
|
EffectParameter viewProjectionParam;
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
EffectParameter albedoTextureParam;
|
|
|
|
EffectParameter normalTextureParam;
|
|
|
|
EffectParameter metallicRoughnessTextureParam;
|
|
|
|
|
|
|
|
EffectParameter albedoParam;
|
|
|
|
EffectParameter metallicParam;
|
|
|
|
EffectParameter roughnessParam;
|
|
|
|
|
2020-12-12 08:17:10 +00:00
|
|
|
EffectParameter uvOffsetAndDimensionsParam;
|
|
|
|
|
2020-12-09 06:20:54 +00:00
|
|
|
EffectParameter numTextureRowsParam;
|
|
|
|
EffectParameter numTextureColumnsParam;
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
EffectParameter vertexShaderIndexParam;
|
2020-08-27 18:14:17 +00:00
|
|
|
EffectParameter shaderIndexParam;
|
|
|
|
|
|
|
|
Matrix world = Matrix.Identity;
|
|
|
|
Matrix view = Matrix.Identity;
|
|
|
|
Matrix projection = Matrix.Identity;
|
|
|
|
|
|
|
|
Vector3 albedo;
|
|
|
|
float metallic;
|
|
|
|
float roughness;
|
|
|
|
|
2020-12-12 08:17:10 +00:00
|
|
|
Vector2 uvOffset;
|
|
|
|
Vector2 subTextureDimensions;
|
|
|
|
|
2020-12-09 06:20:54 +00:00
|
|
|
int numTextureRows = 1;
|
|
|
|
int numTextureColumns = 1;
|
|
|
|
|
2020-08-27 18:14:17 +00:00
|
|
|
bool albedoTextureEnabled = false;
|
|
|
|
bool metallicRoughnessMapEnabled = false;
|
|
|
|
bool normalMapEnabled = false;
|
2020-12-07 09:30:09 +00:00
|
|
|
bool hardwareInstancingEnabled = false;
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
|
|
|
|
|
|
|
public Matrix World
|
|
|
|
{
|
|
|
|
get { return world; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
world = value;
|
2020-12-07 21:50:32 +00:00
|
|
|
dirtyFlags |= EffectDirtyFlags.World;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Matrix View
|
|
|
|
{
|
|
|
|
get { return view; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
view = value;
|
2020-12-07 21:50:32 +00:00
|
|
|
dirtyFlags |= EffectDirtyFlags.ViewProj | EffectDirtyFlags.EyePosition;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Matrix Projection
|
|
|
|
{
|
|
|
|
get { return projection; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
projection = value;
|
2020-12-07 21:50:32 +00:00
|
|
|
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3 Albedo
|
|
|
|
{
|
|
|
|
get { return albedo; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
albedo = value;
|
|
|
|
albedoParam.SetValue(albedo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public float Metallic
|
|
|
|
{
|
|
|
|
get { return metallic; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
metallic = value;
|
|
|
|
metallicParam.SetValue(metallic);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public float Roughness
|
|
|
|
{
|
|
|
|
get { return roughness; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
roughness = value;
|
|
|
|
roughnessParam.SetValue(roughness);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Texture2D AlbedoTexture
|
|
|
|
{
|
|
|
|
get { return albedoTextureParam.GetValueTexture2D(); }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
albedoTextureParam.SetValue(value);
|
|
|
|
albedoTextureEnabled = value != null;
|
2020-12-07 09:30:09 +00:00
|
|
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Texture2D NormalTexture
|
|
|
|
{
|
|
|
|
get { return normalTextureParam.GetValueTexture2D(); }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
normalTextureParam.SetValue(value);
|
|
|
|
normalMapEnabled = value != null;
|
2020-12-07 09:30:09 +00:00
|
|
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Texture2D MetallicRoughnessTexture
|
|
|
|
{
|
|
|
|
get { return metallicRoughnessTextureParam.GetValueTexture2D(); }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
metallicRoughnessTextureParam.SetValue(value);
|
|
|
|
metallicRoughnessMapEnabled = value != null;
|
2020-12-07 09:30:09 +00:00
|
|
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-09 06:20:54 +00:00
|
|
|
public int NumTextureRows
|
|
|
|
{
|
|
|
|
get { return numTextureRows; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
numTextureRows = value;
|
|
|
|
numTextureRowsParam.SetValue(numTextureRows);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int NumTextureColumns
|
|
|
|
{
|
|
|
|
get { return numTextureColumns; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
numTextureColumns = value;
|
|
|
|
numTextureColumnsParam.SetValue(numTextureColumns);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-12 08:17:10 +00:00
|
|
|
public Vector2 UVOffset
|
|
|
|
{
|
|
|
|
get { return uvOffset; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
uvOffset = value;
|
|
|
|
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector2 SubTextureDimensions
|
|
|
|
{
|
|
|
|
get { return subTextureDimensions; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
subTextureDimensions = value;
|
|
|
|
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
public bool HardwareInstancingEnabled
|
|
|
|
{
|
|
|
|
get { return hardwareInstancingEnabled; }
|
|
|
|
set
|
|
|
|
{
|
|
|
|
if (value != hardwareInstancingEnabled)
|
|
|
|
{
|
|
|
|
hardwareInstancingEnabled = value;
|
|
|
|
dirtyFlags |= EffectDirtyFlags.VertexShaderIndex;
|
|
|
|
}
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public DeferredPBR_GBufferEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_GBufferEffect)
|
|
|
|
{
|
|
|
|
CacheEffectParameters();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected DeferredPBR_GBufferEffect(DeferredPBR_GBufferEffect cloneSource) : base(cloneSource)
|
|
|
|
{
|
|
|
|
CacheEffectParameters();
|
|
|
|
|
|
|
|
World = cloneSource.World;
|
|
|
|
View = cloneSource.View;
|
|
|
|
Projection = cloneSource.Projection;
|
|
|
|
|
|
|
|
AlbedoTexture = cloneSource.AlbedoTexture;
|
|
|
|
NormalTexture = cloneSource.NormalTexture;
|
|
|
|
MetallicRoughnessTexture = cloneSource.MetallicRoughnessTexture;
|
|
|
|
|
|
|
|
Albedo = cloneSource.Albedo;
|
|
|
|
Metallic = cloneSource.Metallic;
|
|
|
|
Roughness = cloneSource.Roughness;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override Effect Clone()
|
|
|
|
{
|
|
|
|
return new DeferredPBR_GBufferEffect(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void OnApply()
|
|
|
|
{
|
|
|
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
|
|
|
{
|
|
|
|
worldParam.SetValue(world);
|
|
|
|
|
|
|
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
|
|
|
}
|
|
|
|
|
2020-12-07 21:50:32 +00:00
|
|
|
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
2020-08-27 18:14:17 +00:00
|
|
|
{
|
2020-12-07 21:50:32 +00:00
|
|
|
Matrix.Multiply(ref view, ref projection, out Matrix viewProj);
|
|
|
|
viewProjectionParam.SetValue(viewProj);
|
2020-08-27 18:14:17 +00:00
|
|
|
|
2020-12-07 21:50:32 +00:00
|
|
|
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
2020-12-12 08:17:10 +00:00
|
|
|
if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0)
|
|
|
|
{
|
|
|
|
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
|
|
|
UVOffset.X, UVOffset.Y,
|
|
|
|
SubTextureDimensions.X, SubTextureDimensions.Y
|
|
|
|
));
|
|
|
|
|
|
|
|
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
|
|
|
}
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
|
2020-08-27 18:14:17 +00:00
|
|
|
{
|
2020-12-07 09:30:09 +00:00
|
|
|
int vertexShaderIndex = 0;
|
|
|
|
|
|
|
|
if (hardwareInstancingEnabled)
|
|
|
|
{
|
|
|
|
vertexShaderIndex = 1;
|
|
|
|
}
|
2020-08-27 18:14:17 +00:00
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
vertexShaderIndexParam.SetValue(vertexShaderIndex);
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
2020-08-27 18:14:17 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CacheEffectParameters()
|
|
|
|
{
|
|
|
|
worldParam = Parameters["World"];
|
2020-12-07 21:50:32 +00:00
|
|
|
viewProjectionParam = Parameters["ViewProjection"];
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
albedoTextureParam = Parameters["AlbedoTexture"];
|
|
|
|
normalTextureParam = Parameters["NormalTexture"];
|
|
|
|
metallicRoughnessTextureParam = Parameters["MetallicRoughnessTexture"];
|
|
|
|
|
|
|
|
albedoParam = Parameters["AlbedoValue"];
|
|
|
|
metallicParam = Parameters["MetallicValue"];
|
|
|
|
roughnessParam = Parameters["RoughnessValue"];
|
|
|
|
|
2020-12-09 06:20:54 +00:00
|
|
|
numTextureRowsParam = Parameters["NumTextureRows"];
|
|
|
|
numTextureColumnsParam = Parameters["NumTextureColumns"];
|
|
|
|
|
2020-12-12 08:17:10 +00:00
|
|
|
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
shaderIndexParam = Parameters["PixelShaderIndex"];
|
|
|
|
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|