Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
cosmonaut | 3a89e9a091 | |
cosmonaut | 28bc8c79e7 |
|
@ -1 +0,0 @@
|
|||
*.fxb filter=lfs diff=lfs merge=lfs -text
|
|
@ -2,41 +2,22 @@ using Microsoft.Xna.Framework;
|
|||
|
||||
namespace Kav
|
||||
{
|
||||
public struct PerspectiveCamera
|
||||
public struct Camera
|
||||
{
|
||||
public Matrix View { get; }
|
||||
public Matrix Transform { get; }
|
||||
public Matrix View
|
||||
{
|
||||
get
|
||||
{
|
||||
return Matrix.CreateLookAt(Transform.Translation, Transform.Translation + Transform.Forward, Transform.Up);
|
||||
}
|
||||
}
|
||||
public Matrix Projection { get; }
|
||||
|
||||
public Vector3 Position { get; }
|
||||
public Vector3 Forward { get; }
|
||||
public Vector3 Up { get; }
|
||||
public Vector3 Right { get; }
|
||||
|
||||
public float FieldOfView { get; }
|
||||
public float AspectRatio { get; }
|
||||
public float NearPlane { get; }
|
||||
public float FarPlane { get; }
|
||||
|
||||
public PerspectiveCamera(
|
||||
Vector3 position,
|
||||
Vector3 forward,
|
||||
Vector3 up,
|
||||
float fieldOfView,
|
||||
float aspectRatio,
|
||||
float nearPlane,
|
||||
float farPlane
|
||||
) {
|
||||
Position = position;
|
||||
Forward = forward;
|
||||
Up = up;
|
||||
Right = Vector3.Cross(forward, up);
|
||||
View = Matrix.CreateLookAt(Position, Position + Forward, Up);
|
||||
|
||||
FieldOfView = fieldOfView;
|
||||
AspectRatio = aspectRatio;
|
||||
NearPlane = nearPlane;
|
||||
FarPlane = farPlane;
|
||||
Projection = Matrix.CreatePerspectiveFieldOfView(FieldOfView, AspectRatio, NearPlane, FarPlane);
|
||||
public Camera(Matrix transform, Matrix projection)
|
||||
{
|
||||
Transform = transform;
|
||||
Projection = projection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
namespace Kav
|
||||
{
|
||||
public struct AtlasAnimation
|
||||
{
|
||||
public UVData[] Frames { get; }
|
||||
public int Framerate { get; }
|
||||
|
||||
public AtlasAnimation(UVData[] frames, int framerate)
|
||||
{
|
||||
Frames = frames;
|
||||
Framerate = framerate;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class InstanceData<T> where T : struct, IVertexType
|
||||
{
|
||||
public T[] InstanceDataArray { get; }
|
||||
public DynamicVertexBuffer VertexBuffer { get; }
|
||||
public int InstanceCount { get; private set; }
|
||||
|
||||
public InstanceData(GraphicsDevice graphicsDevice, int size)
|
||||
{
|
||||
InstanceDataArray = new T[size];
|
||||
|
||||
VertexBuffer = new DynamicVertexBuffer(
|
||||
graphicsDevice,
|
||||
typeof(T),
|
||||
size,
|
||||
BufferUsage.WriteOnly
|
||||
);
|
||||
|
||||
InstanceCount = 0;
|
||||
}
|
||||
|
||||
public void AddAndSetData(IEnumerable<T> data)
|
||||
{
|
||||
InstanceCount = 0;
|
||||
foreach (var datum in data)
|
||||
{
|
||||
AddData(datum);
|
||||
}
|
||||
|
||||
if (InstanceCount == 0) { throw new System.Exception(); }
|
||||
|
||||
SetData();
|
||||
}
|
||||
|
||||
public void AddData(T datum)
|
||||
{
|
||||
InstanceDataArray[InstanceCount] = datum;
|
||||
InstanceCount += 1;
|
||||
}
|
||||
|
||||
public void SetData()
|
||||
{
|
||||
if (InstanceCount > 0)
|
||||
{
|
||||
VertexBuffer.SetData(
|
||||
InstanceDataArray,
|
||||
0,
|
||||
InstanceCount,
|
||||
SetDataOptions.NoOverwrite
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
InstanceCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav.Data
|
||||
{
|
||||
public struct MeshSpriteDrawData : IIndexDrawable, ICullable, ITransformable
|
||||
{
|
||||
public SpriteMesh MeshSprite { get; }
|
||||
public Texture2D Texture { get; }
|
||||
public Texture2D Normal { get; }
|
||||
public SpriteBillboardConstraint BillboardConstraint { get; }
|
||||
public Matrix TransformMatrix { get; }
|
||||
public UVData UVOffset { get; }
|
||||
|
||||
public IndexBuffer IndexBuffer => MeshSprite.IndexBuffer;
|
||||
public VertexBuffer VertexBuffer => MeshSprite.VertexBuffer;
|
||||
public BoundingBox BoundingBox => MeshSprite.BoundingBox;
|
||||
|
||||
public MeshSpriteDrawData(
|
||||
SpriteMesh meshSprite,
|
||||
Texture2D texture,
|
||||
Texture2D normal,
|
||||
SpriteBillboardConstraint billboardConstraint,
|
||||
Matrix transformMatrix,
|
||||
UVData offset
|
||||
) {
|
||||
MeshSprite = meshSprite;
|
||||
Texture = texture;
|
||||
Normal = normal;
|
||||
BillboardConstraint = billboardConstraint;
|
||||
TransformMatrix = transformMatrix;
|
||||
UVOffset = offset;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
using Kav.Data;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public struct TextureAtlasSlice
|
||||
{
|
||||
public int X { get; }
|
||||
public int Y { get; }
|
||||
public int W { get; }
|
||||
public int H { get; }
|
||||
|
||||
public UVData UVData { get; }
|
||||
|
||||
// for use with tiling
|
||||
public Vector2 TiledUVOffset { get; }
|
||||
|
||||
public TextureAtlasSlice(int x, int y, int w, int h, int totalW, int totalH)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
W = w;
|
||||
H = h;
|
||||
|
||||
UVData = new UVData(new Vector2(x, y), new Vector2(w, h), new Vector2(totalW, totalH));
|
||||
|
||||
TiledUVOffset = new Vector2(x / (float)totalW, y / (float)totalH);
|
||||
}
|
||||
}
|
||||
|
||||
public class TextureAtlas
|
||||
{
|
||||
public Texture2D Texture { get; }
|
||||
protected List<string> Names { get; } = new List<string>();
|
||||
protected Dictionary<string, TextureAtlasSlice> Slices { get; } = new Dictionary<string, TextureAtlasSlice>();
|
||||
|
||||
public TextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile)
|
||||
{
|
||||
var atlasData = CrunchAtlasReader.ReadTextureAtlas(atlasMetadataFile);
|
||||
|
||||
var textureData = atlasData.Textures[0];
|
||||
|
||||
using var stream = File.OpenRead(Path.Combine(atlasMetadataFile.DirectoryName, textureData.Name + ".png"));
|
||||
Texture = Texture2D.FromStream(graphicsDevice, stream);
|
||||
|
||||
foreach (var slice in textureData.Images)
|
||||
{
|
||||
Names.Add(slice.N);
|
||||
|
||||
Slices.Add(
|
||||
slice.N,
|
||||
new TextureAtlasSlice(
|
||||
slice.X,
|
||||
slice.Y,
|
||||
slice.W,
|
||||
slice.H,
|
||||
Texture.Width,
|
||||
Texture.Height
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public TextureAtlasSlice Lookup(string name)
|
||||
{
|
||||
return Slices[name];
|
||||
}
|
||||
|
||||
public string Name(int index)
|
||||
{
|
||||
return Names[index];
|
||||
}
|
||||
|
||||
public int Count()
|
||||
{
|
||||
return Names.Count;
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes all subimages are the same size
|
||||
public class TiledTextureAtlas : TextureAtlas
|
||||
{
|
||||
public int NumRows { get; }
|
||||
public int NumColumns { get; }
|
||||
|
||||
public TiledTextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile) : base(graphicsDevice, atlasMetadataFile)
|
||||
{
|
||||
var subImageSlice = Slices[Names[0]];
|
||||
NumRows = Texture.Height / subImageSlice.H;
|
||||
NumColumns = Texture.Width / subImageSlice.W;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public struct UVData
|
||||
{
|
||||
public Vector2 Offset { get; }
|
||||
public Vector2 Percentage { get; }
|
||||
|
||||
public UVData(
|
||||
Vector2 positionInAtlas,
|
||||
Vector2 subTextureDimensions,
|
||||
Vector2 atlasDimensions
|
||||
) {
|
||||
Percentage = subTextureDimensions / atlasDimensions;
|
||||
Offset = positionInAtlas / atlasDimensions;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class DirectionalShadowMapData
|
||||
{
|
||||
public static readonly int MAX_SHADOW_CASCADES = 4;
|
||||
|
||||
public RenderTarget2D[] ShadowMaps { get; }
|
||||
|
||||
public Matrix[] LightSpaceViews { get; }
|
||||
public Matrix[] LightSpaceProjections { get; }
|
||||
|
||||
public float[] CascadeFarPlanes { get; }
|
||||
|
||||
public int ShadowMapSize { get; }
|
||||
public int NumShadowCascades { get; }
|
||||
|
||||
internal DirectionalShadowMapData(
|
||||
GraphicsDevice graphicsDevice,
|
||||
int shadowMapSize,
|
||||
int numCascades
|
||||
) {
|
||||
ShadowMapSize = shadowMapSize;
|
||||
NumShadowCascades = (int)MathHelper.Clamp(numCascades, 1, MAX_SHADOW_CASCADES);
|
||||
|
||||
LightSpaceViews = new Matrix[4];
|
||||
LightSpaceProjections = new Matrix[4];
|
||||
|
||||
ShadowMaps = new RenderTarget2D[NumShadowCascades];
|
||||
|
||||
for (var i = 0; i < NumShadowCascades; i++)
|
||||
{
|
||||
ShadowMaps[i] = new RenderTarget2D(
|
||||
graphicsDevice,
|
||||
shadowMapSize,
|
||||
shadowMapSize,
|
||||
false,
|
||||
SurfaceFormat.Single,
|
||||
DepthFormat.Depth24,
|
||||
0,
|
||||
RenderTargetUsage.PreserveContents
|
||||
);
|
||||
}
|
||||
|
||||
CascadeFarPlanes = new float[MAX_SHADOW_CASCADES];
|
||||
}
|
||||
|
||||
public void Clear(GraphicsDevice graphicsDevice)
|
||||
{
|
||||
foreach (var shadowMap in ShadowMaps)
|
||||
{
|
||||
graphicsDevice.SetRenderTarget(shadowMap);
|
||||
graphicsDevice.Clear(Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Kav
|
||||
{
|
||||
public interface DirectionalLightEffect
|
||||
{
|
||||
int MaxDirectionalLights { get; }
|
||||
DirectionalLightCollection DirectionalLights { get; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface IHasTranslation
|
||||
{
|
||||
Vector3 Translation { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface IHasWorldMatrix
|
||||
{
|
||||
Matrix World { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface ShadowCascadeEffect
|
||||
{
|
||||
Matrix LightSpaceMatrixOne { get; set; }
|
||||
Matrix LightSpaceMatrixTwo { get; set; }
|
||||
Matrix LightSpaceMatrixThree { get; set; }
|
||||
Matrix LightSpaceMatrixFour { get; set; }
|
||||
|
||||
float[] CascadeFarPlanes { get; }
|
||||
}
|
||||
}
|
|
@ -9,47 +9,18 @@ namespace Kav
|
|||
EffectParameter gAlbedoParam;
|
||||
EffectParameter gNormalParam;
|
||||
EffectParameter gMetallicRoughnessParam;
|
||||
|
||||
EffectParameter shadowMapOneParam;
|
||||
EffectParameter shadowMapTwoParam;
|
||||
EffectParameter shadowMapThreeParam;
|
||||
EffectParameter shadowMapFourParam;
|
||||
|
||||
EffectParameter lightSpaceMatrixOneParam;
|
||||
EffectParameter lightSpaceMatrixTwoParam;
|
||||
EffectParameter lightSpaceMatrixThreeParam;
|
||||
EffectParameter lightSpaceMatrixFourParam;
|
||||
|
||||
EffectParameter viewMatrixParam;
|
||||
EffectParameter cascadeFarPlanesParam;
|
||||
|
||||
EffectParameter directionalLightColorParam;
|
||||
EffectParameter directionalLightDirectionParam;
|
||||
EffectParameter shadowMapParam;
|
||||
|
||||
EffectParameter eyePositionParam;
|
||||
|
||||
PointLightCollection pointLightCollection;
|
||||
DirectionalLightCollection directionalLightCollection;
|
||||
|
||||
public Texture2D GPosition { get; set; }
|
||||
public Texture2D GAlbedo { get; set; }
|
||||
public Texture2D GNormal { get; set; }
|
||||
public Texture2D GMetallicRoughness { get; set; }
|
||||
|
||||
public Texture2D ShadowMapOne { get; set; }
|
||||
public Texture2D ShadowMapTwo { get; set; }
|
||||
public Texture2D ShadowMapThree { get; set; }
|
||||
public Texture2D ShadowMapFour { get; set; }
|
||||
|
||||
public Matrix LightSpaceMatrixOne { get; set; }
|
||||
public Matrix LightSpaceMatrixTwo { get; set; }
|
||||
public Matrix LightSpaceMatrixThree { get; set; }
|
||||
public Matrix LightSpaceMatrixFour { get; set; }
|
||||
|
||||
public Matrix ViewMatrix { get; set; }
|
||||
public readonly float[] CascadeFarPlanes;
|
||||
|
||||
public Vector3 DirectionalLightColor { get; set; }
|
||||
public Vector3 DirectionalLightDirection { get; set; }
|
||||
public TextureCube DirectionalShadowMap { get; set; }
|
||||
|
||||
public Vector3 EyePosition { get; set; }
|
||||
|
||||
|
@ -61,10 +32,16 @@ namespace Kav
|
|||
private set { pointLightCollection = value; }
|
||||
}
|
||||
|
||||
public int MaxDirectionalLights { get; } = 4;
|
||||
|
||||
public DirectionalLightCollection DirectionalLights
|
||||
{
|
||||
get { return directionalLightCollection; }
|
||||
private set { directionalLightCollection = value; }
|
||||
}
|
||||
|
||||
public DeferredPBREffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBREffect)
|
||||
{
|
||||
CascadeFarPlanes = new float[4];
|
||||
|
||||
CacheEffectParameters();
|
||||
|
||||
pointLightCollection = new PointLightCollection(
|
||||
|
@ -72,6 +49,49 @@ namespace Kav
|
|||
Parameters["PointLightColors"],
|
||||
MaxPointLights
|
||||
);
|
||||
|
||||
DirectionalLights = new DirectionalLightCollection(
|
||||
Parameters["DirectionalLightDirections"],
|
||||
Parameters["DirectionalLightColors"],
|
||||
Parameters["DirectionalLightMatrices"]
|
||||
);
|
||||
}
|
||||
|
||||
protected DeferredPBREffect(DeferredPBREffect cloneSource) : base(cloneSource)
|
||||
{
|
||||
GPosition = cloneSource.GPosition;
|
||||
GAlbedo = cloneSource.GAlbedo;
|
||||
GNormal = cloneSource.GNormal;
|
||||
GMetallicRoughness = cloneSource.GMetallicRoughness;
|
||||
|
||||
EyePosition = cloneSource.EyePosition;
|
||||
|
||||
PointLights = new PointLightCollection(
|
||||
Parameters["LightPositions"],
|
||||
Parameters["PositionLightColors"],
|
||||
MaxPointLights
|
||||
);
|
||||
|
||||
for (int i = 0; i < MaxPointLights; i++)
|
||||
{
|
||||
PointLights[i] = cloneSource.PointLights[i];
|
||||
}
|
||||
|
||||
DirectionalLights = new DirectionalLightCollection(
|
||||
Parameters["DirectionalLightDirections"],
|
||||
Parameters["DirectionalLightColors"],
|
||||
Parameters["DirectionalLightMatrices"]
|
||||
);
|
||||
|
||||
for (int i = 0; i < MaxDirectionalLights; i++)
|
||||
{
|
||||
DirectionalLights[i] = cloneSource.DirectionalLights[i];
|
||||
}
|
||||
}
|
||||
|
||||
public override Effect Clone()
|
||||
{
|
||||
return new DeferredPBREffect(this);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
|
@ -80,50 +100,20 @@ namespace Kav
|
|||
gAlbedoParam.SetValue(GAlbedo);
|
||||
gNormalParam.SetValue(GNormal);
|
||||
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
||||
|
||||
shadowMapOneParam.SetValue(ShadowMapOne);
|
||||
shadowMapTwoParam.SetValue(ShadowMapTwo);
|
||||
shadowMapThreeParam.SetValue(ShadowMapThree);
|
||||
shadowMapFourParam.SetValue(ShadowMapFour);
|
||||
|
||||
lightSpaceMatrixOneParam.SetValue(LightSpaceMatrixOne);
|
||||
lightSpaceMatrixTwoParam.SetValue(LightSpaceMatrixTwo);
|
||||
lightSpaceMatrixThreeParam.SetValue(LightSpaceMatrixThree);
|
||||
lightSpaceMatrixFourParam.SetValue(LightSpaceMatrixFour);
|
||||
|
||||
viewMatrixParam.SetValue(ViewMatrix);
|
||||
cascadeFarPlanesParam.SetValue(CascadeFarPlanes);
|
||||
|
||||
directionalLightColorParam.SetValue(DirectionalLightColor);
|
||||
directionalLightDirectionParam.SetValue(DirectionalLightDirection);
|
||||
shadowMapParam.SetValue(DirectionalShadowMap);
|
||||
|
||||
eyePositionParam.SetValue(EyePosition);
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
gPositionParam = Parameters["gPosition"];
|
||||
gAlbedoParam = Parameters["gAlbedo"];
|
||||
gNormalParam = Parameters["gNormal"];
|
||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||
gPositionParam = Parameters["gPosition"];
|
||||
gAlbedoParam = Parameters["gAlbedo"];
|
||||
gNormalParam = Parameters["gNormal"];
|
||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||
shadowMapParam = Parameters["shadowMap"];
|
||||
|
||||
shadowMapOneParam = Parameters["shadowMapOne"];
|
||||
shadowMapTwoParam = Parameters["shadowMapTwo"];
|
||||
shadowMapThreeParam = Parameters["shadowMapThree"];
|
||||
shadowMapFourParam = Parameters["shadowMapFour"];
|
||||
|
||||
lightSpaceMatrixOneParam = Parameters["LightSpaceMatrixOne"];
|
||||
lightSpaceMatrixTwoParam = Parameters["LightSpaceMatrixTwo"];
|
||||
lightSpaceMatrixThreeParam = Parameters["LightSpaceMatrixThree"];
|
||||
lightSpaceMatrixFourParam = Parameters["LightSpaceMatrixFour"];
|
||||
|
||||
viewMatrixParam = Parameters["ViewMatrix"];
|
||||
cascadeFarPlanesParam = Parameters["CascadeFarPlanes"];
|
||||
|
||||
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
||||
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
||||
|
||||
eyePositionParam = Parameters["EyePosition"];
|
||||
eyePositionParam = Parameters["EyePosition"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
|
||||
public class DeferredPBR_AmbientLightEffect : Effect
|
||||
{
|
||||
EffectParameter gPositionParam;
|
||||
EffectParameter gAlbedoParam;
|
||||
|
||||
EffectParameter ambientColorParam;
|
||||
|
||||
public Texture2D GPosition { get; set; }
|
||||
public Texture2D GAlbedo { get; set; }
|
||||
|
||||
public Vector3 AmbientColor { get; set; }
|
||||
|
||||
public DeferredPBR_AmbientLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_AmbientLightEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
gPositionParam.SetValue(GPosition);
|
||||
gAlbedoParam.SetValue(GAlbedo);
|
||||
ambientColorParam.SetValue(AmbientColor);
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
gPositionParam = Parameters["gPosition"];
|
||||
gAlbedoParam = Parameters["gAlbedo"];
|
||||
ambientColorParam = Parameters["AmbientLightColor"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class DeferredPBR_DirectionalLightEffect : Effect, ShadowCascadeEffect
|
||||
{
|
||||
EffectParameter gPositionParam;
|
||||
EffectParameter gAlbedoParam;
|
||||
EffectParameter gNormalParam;
|
||||
EffectParameter gMetallicRoughnessParam;
|
||||
|
||||
EffectParameter shadowMapOneParam;
|
||||
EffectParameter shadowMapTwoParam;
|
||||
EffectParameter shadowMapThreeParam;
|
||||
EffectParameter shadowMapFourParam;
|
||||
|
||||
EffectParameter eyePositionParam;
|
||||
|
||||
EffectParameter directionalLightColorParam;
|
||||
EffectParameter directionalLightDirectionParam;
|
||||
|
||||
EffectParameter cascadeFarPlanesParam;
|
||||
|
||||
EffectParameter shadowMapSizeParam;
|
||||
|
||||
EffectParameter lightSpaceMatrixOneParam;
|
||||
EffectParameter lightSpaceMatrixTwoParam;
|
||||
EffectParameter lightSpaceMatrixThreeParam;
|
||||
EffectParameter lightSpaceMatrixFourParam;
|
||||
|
||||
EffectParameter viewMatrixParam;
|
||||
|
||||
public Texture2D GPosition { get; set; }
|
||||
public Texture2D GAlbedo { get; set; }
|
||||
public Texture2D GNormal { get; set; }
|
||||
public Texture2D GMetallicRoughness { get; set; }
|
||||
|
||||
public Texture2D ShadowMapOne { get; set; }
|
||||
public Texture2D ShadowMapTwo { get; set; }
|
||||
public Texture2D ShadowMapThree { get; set; }
|
||||
public Texture2D ShadowMapFour { get; set; }
|
||||
|
||||
public Vector3 EyePosition { get; set; }
|
||||
|
||||
public Vector3 DirectionalLightDirection { get; set; }
|
||||
public Vector3 DirectionalLightColor { get; set; }
|
||||
|
||||
public float[] CascadeFarPlanes { get; }
|
||||
|
||||
public int ShadowMapSize { get; set; }
|
||||
|
||||
public Matrix LightSpaceMatrixOne { get; set; }
|
||||
public Matrix LightSpaceMatrixTwo { get; set; }
|
||||
public Matrix LightSpaceMatrixThree { get; set; }
|
||||
public Matrix LightSpaceMatrixFour { get; set; }
|
||||
|
||||
public Matrix ViewMatrix { get; set; }
|
||||
|
||||
public DeferredPBR_DirectionalLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_DirectionalLightEffect)
|
||||
{
|
||||
CascadeFarPlanes = new float[4];
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
public DeferredPBR_DirectionalLightEffect(DeferredPBR_DirectionalLightEffect cloneSource) : base(cloneSource)
|
||||
{
|
||||
GPosition = cloneSource.GPosition;
|
||||
GAlbedo = cloneSource.GAlbedo;
|
||||
GNormal = cloneSource.GNormal;
|
||||
GMetallicRoughness = cloneSource.GMetallicRoughness;
|
||||
|
||||
ShadowMapOne = cloneSource.ShadowMapOne;
|
||||
ShadowMapTwo = cloneSource.ShadowMapTwo;
|
||||
ShadowMapThree = cloneSource.ShadowMapThree;
|
||||
ShadowMapFour = cloneSource.ShadowMapFour;
|
||||
|
||||
EyePosition = cloneSource.EyePosition;
|
||||
|
||||
DirectionalLightDirection = cloneSource.DirectionalLightDirection;
|
||||
DirectionalLightColor = cloneSource.DirectionalLightColor;
|
||||
|
||||
CascadeFarPlanes = new float[4];
|
||||
for (int i = 0 ; i < 4; i++)
|
||||
{
|
||||
CascadeFarPlanes[i] = cloneSource.CascadeFarPlanes[i];
|
||||
}
|
||||
|
||||
ShadowMapSize = cloneSource.ShadowMapSize;
|
||||
|
||||
LightSpaceMatrixOne = cloneSource.LightSpaceMatrixOne;
|
||||
LightSpaceMatrixTwo = cloneSource.LightSpaceMatrixTwo;
|
||||
LightSpaceMatrixThree = cloneSource.LightSpaceMatrixThree;
|
||||
LightSpaceMatrixFour = cloneSource.LightSpaceMatrixFour;
|
||||
|
||||
ViewMatrix = cloneSource.ViewMatrix;
|
||||
}
|
||||
|
||||
public override Effect Clone()
|
||||
{
|
||||
return new DeferredPBR_DirectionalLightEffect(this);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
gPositionParam.SetValue(GPosition);
|
||||
gAlbedoParam.SetValue(GAlbedo);
|
||||
gNormalParam.SetValue(GNormal);
|
||||
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
||||
|
||||
shadowMapOneParam.SetValue(ShadowMapOne);
|
||||
shadowMapTwoParam.SetValue(ShadowMapTwo);
|
||||
shadowMapThreeParam.SetValue(ShadowMapThree);
|
||||
shadowMapFourParam.SetValue(ShadowMapFour);
|
||||
|
||||
eyePositionParam.SetValue(EyePosition);
|
||||
|
||||
directionalLightDirectionParam.SetValue(DirectionalLightDirection);
|
||||
directionalLightColorParam.SetValue(DirectionalLightColor);
|
||||
|
||||
cascadeFarPlanesParam.SetValue(CascadeFarPlanes);
|
||||
shadowMapSizeParam.SetValue(ShadowMapSize);
|
||||
|
||||
lightSpaceMatrixOneParam.SetValue(LightSpaceMatrixOne);
|
||||
lightSpaceMatrixTwoParam.SetValue(LightSpaceMatrixTwo);
|
||||
lightSpaceMatrixThreeParam.SetValue(LightSpaceMatrixThree);
|
||||
lightSpaceMatrixFourParam.SetValue(LightSpaceMatrixFour);
|
||||
|
||||
viewMatrixParam.SetValue(ViewMatrix);
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
gPositionParam = Parameters["gPosition"];
|
||||
gAlbedoParam = Parameters["gAlbedo"];
|
||||
gNormalParam = Parameters["gNormal"];
|
||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||
|
||||
shadowMapOneParam = Parameters["shadowMapOne"];
|
||||
shadowMapTwoParam = Parameters["shadowMapTwo"];
|
||||
shadowMapThreeParam = Parameters["shadowMapThree"];
|
||||
shadowMapFourParam = Parameters["shadowMapFour"];
|
||||
|
||||
eyePositionParam = Parameters["EyePosition"];
|
||||
|
||||
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
||||
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
||||
|
||||
cascadeFarPlanesParam = Parameters["CascadeFarPlanes"];
|
||||
shadowMapSizeParam = Parameters["ShadowMapSize"];
|
||||
|
||||
lightSpaceMatrixOneParam = Parameters["LightSpaceMatrixOne"];
|
||||
lightSpaceMatrixTwoParam = Parameters["LightSpaceMatrixTwo"];
|
||||
lightSpaceMatrixThreeParam = Parameters["LightSpaceMatrixThree"];
|
||||
lightSpaceMatrixFourParam = Parameters["LightSpaceMatrixFour"];
|
||||
|
||||
viewMatrixParam = Parameters["ViewMatrix"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,8 @@ namespace Kav
|
|||
public class DeferredPBR_GBufferEffect : Effect, TransformEffect
|
||||
{
|
||||
EffectParameter worldParam;
|
||||
EffectParameter viewProjectionParam;
|
||||
EffectParameter worldViewProjectionParam;
|
||||
EffectParameter worldInverseTransposeParam;
|
||||
|
||||
EffectParameter albedoTextureParam;
|
||||
EffectParameter normalTextureParam;
|
||||
|
@ -16,13 +17,6 @@ namespace Kav
|
|||
EffectParameter metallicParam;
|
||||
EffectParameter roughnessParam;
|
||||
|
||||
EffectParameter uvOffsetAndDimensionsParam;
|
||||
EffectParameter isSpriteParam;
|
||||
|
||||
EffectParameter numTextureRowsParam;
|
||||
EffectParameter numTextureColumnsParam;
|
||||
|
||||
EffectParameter vertexShaderIndexParam;
|
||||
EffectParameter shaderIndexParam;
|
||||
|
||||
Matrix world = Matrix.Identity;
|
||||
|
@ -33,18 +27,9 @@ namespace Kav
|
|||
float metallic;
|
||||
float roughness;
|
||||
|
||||
Vector2 uvOffset;
|
||||
Vector2 subTextureDimensions;
|
||||
|
||||
bool isSprite = false;
|
||||
|
||||
int numTextureRows = 1;
|
||||
int numTextureColumns = 1;
|
||||
|
||||
bool albedoTextureEnabled = false;
|
||||
bool metallicRoughnessMapEnabled = false;
|
||||
bool normalMapEnabled = false;
|
||||
bool hardwareInstancingEnabled = false;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
|
@ -54,7 +39,7 @@ namespace Kav
|
|||
set
|
||||
{
|
||||
world = value;
|
||||
dirtyFlags |= EffectDirtyFlags.World;
|
||||
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +49,7 @@ namespace Kav
|
|||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj | EffectDirtyFlags.EyePosition;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +59,7 @@ namespace Kav
|
|||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +100,7 @@ namespace Kav
|
|||
{
|
||||
albedoTextureParam.SetValue(value);
|
||||
albedoTextureEnabled = value != null;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +111,7 @@ namespace Kav
|
|||
{
|
||||
normalTextureParam.SetValue(value);
|
||||
normalMapEnabled = value != null;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,70 +122,7 @@ namespace Kav
|
|||
{
|
||||
metallicRoughnessTextureParam.SetValue(value);
|
||||
metallicRoughnessMapEnabled = value != null;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public int NumTextureRows
|
||||
{
|
||||
get { return numTextureRows; }
|
||||
set
|
||||
{
|
||||
numTextureRows = value;
|
||||
numTextureRowsParam.SetValue(numTextureRows);
|
||||
}
|
||||
}
|
||||
|
||||
public int NumTextureColumns
|
||||
{
|
||||
get { return numTextureColumns; }
|
||||
set
|
||||
{
|
||||
numTextureColumns = value;
|
||||
numTextureColumnsParam.SetValue(numTextureColumns);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 UVOffset
|
||||
{
|
||||
get { return uvOffset; }
|
||||
set
|
||||
{
|
||||
uvOffset = value;
|
||||
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 SubTextureDimensions
|
||||
{
|
||||
get { return subTextureDimensions; }
|
||||
set
|
||||
{
|
||||
subTextureDimensions = value;
|
||||
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSprite
|
||||
{
|
||||
get { return isSprite; }
|
||||
set
|
||||
{
|
||||
isSprite = value;
|
||||
isSpriteParam.SetValue(isSprite ? 1f : 0f);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HardwareInstancingEnabled
|
||||
{
|
||||
get { return hardwareInstancingEnabled; }
|
||||
set
|
||||
{
|
||||
if (value != hardwareInstancingEnabled)
|
||||
{
|
||||
hardwareInstancingEnabled = value;
|
||||
dirtyFlags |= EffectDirtyFlags.VertexShaderIndex;
|
||||
}
|
||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,40 +159,30 @@ namespace Kav
|
|||
{
|
||||
worldParam.SetValue(world);
|
||||
|
||||
Matrix.Invert(ref world, out Matrix worldInverse);
|
||||
Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose);
|
||||
worldInverseTransposeParam.SetValue(worldInverseTranspose);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProj);
|
||||
viewProjectionParam.SetValue(viewProj);
|
||||
Matrix.Multiply(ref world, ref view, out Matrix worldView);
|
||||
Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj);
|
||||
worldViewProjectionParam.SetValue(worldViewProj);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0)
|
||||
if ((dirtyFlags & EffectDirtyFlags.EyePosition) != 0)
|
||||
{
|
||||
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
||||
UVOffset.X, UVOffset.Y,
|
||||
SubTextureDimensions.X, SubTextureDimensions.Y
|
||||
));
|
||||
Matrix.Invert(ref view, out Matrix inverseView);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
||||
dirtyFlags &= ~EffectDirtyFlags.EyePosition;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
|
||||
{
|
||||
int vertexShaderIndex = 0;
|
||||
|
||||
if (hardwareInstancingEnabled)
|
||||
{
|
||||
vertexShaderIndex = 1;
|
||||
}
|
||||
|
||||
vertexShaderIndexParam.SetValue(vertexShaderIndex);
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
|
||||
{
|
||||
int shaderIndex = 0;
|
||||
|
||||
|
@ -305,14 +217,15 @@ namespace Kav
|
|||
|
||||
shaderIndexParam.SetValue(shaderIndex);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
worldParam = Parameters["World"];
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
||||
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
|
||||
|
||||
albedoTextureParam = Parameters["AlbedoTexture"];
|
||||
normalTextureParam = Parameters["NormalTexture"];
|
||||
|
@ -322,14 +235,7 @@ namespace Kav
|
|||
metallicParam = Parameters["MetallicValue"];
|
||||
roughnessParam = Parameters["RoughnessValue"];
|
||||
|
||||
numTextureRowsParam = Parameters["NumTextureRows"];
|
||||
numTextureColumnsParam = Parameters["NumTextureColumns"];
|
||||
|
||||
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
||||
isSpriteParam = Parameters["IsSprite"];
|
||||
|
||||
shaderIndexParam = Parameters["PixelShaderIndex"];
|
||||
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
||||
shaderIndexParam = Parameters["ShaderIndex"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class DeferredPBR_PointLightEffect : Effect
|
||||
{
|
||||
EffectParameter gPositionParam;
|
||||
EffectParameter gAlbedoParam;
|
||||
EffectParameter gNormalParam;
|
||||
EffectParameter gMetallicRoughnessParam;
|
||||
EffectParameter shadowMapParam;
|
||||
|
||||
EffectParameter eyePositionParam;
|
||||
|
||||
EffectParameter pointLightColorParam;
|
||||
EffectParameter pointLightPositionParam;
|
||||
|
||||
EffectParameter farPlaneParam;
|
||||
|
||||
EffectParameter worldViewProjectionParam;
|
||||
|
||||
public Texture2D GPosition { get; set; }
|
||||
public Texture2D GAlbedo { get; set; }
|
||||
public Texture2D GNormal { get; set; }
|
||||
public Texture2D GMetallicRoughness { get; set; }
|
||||
public TextureCube ShadowMap { get; set; }
|
||||
|
||||
public Vector3 EyePosition { get; set; }
|
||||
|
||||
public Vector3 PointLightPosition { get; set; }
|
||||
public Vector3 PointLightColor { get; set; }
|
||||
|
||||
public float FarPlane { get; set; }
|
||||
|
||||
Matrix world = Matrix.Identity;
|
||||
Matrix view = Matrix.Identity;
|
||||
Matrix projection = Matrix.Identity;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
public Matrix World
|
||||
{
|
||||
get { return world; }
|
||||
set
|
||||
{
|
||||
world = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
public DeferredPBR_PointLightEffect(DeferredPBR_PointLightEffect cloneSource) : base(cloneSource)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
|
||||
GPosition = cloneSource.GPosition;
|
||||
GAlbedo = cloneSource.GAlbedo;
|
||||
GNormal = cloneSource.GNormal;
|
||||
GMetallicRoughness = cloneSource.GMetallicRoughness;
|
||||
ShadowMap = cloneSource.ShadowMap;
|
||||
|
||||
EyePosition = cloneSource.EyePosition;
|
||||
|
||||
PointLightPosition = cloneSource.PointLightPosition;
|
||||
PointLightColor = cloneSource.PointLightColor;
|
||||
|
||||
FarPlane = cloneSource.FarPlane;
|
||||
}
|
||||
|
||||
public override Effect Clone()
|
||||
{
|
||||
return new DeferredPBR_PointLightEffect(this);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
gPositionParam.SetValue(GPosition);
|
||||
gAlbedoParam.SetValue(GAlbedo);
|
||||
gNormalParam.SetValue(GNormal);
|
||||
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
||||
shadowMapParam.SetValue(ShadowMap);
|
||||
|
||||
eyePositionParam.SetValue(EyePosition);
|
||||
|
||||
pointLightPositionParam.SetValue(PointLightPosition);
|
||||
pointLightColorParam.SetValue(PointLightColor);
|
||||
|
||||
farPlaneParam.SetValue(FarPlane);
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||
{
|
||||
worldViewProjectionParam.SetValue(world * view * projection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
gPositionParam = Parameters["gPosition"];
|
||||
gAlbedoParam = Parameters["gAlbedo"];
|
||||
gNormalParam = Parameters["gNormal"];
|
||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||
shadowMapParam = Parameters["shadowMap"];
|
||||
|
||||
eyePositionParam = Parameters["EyePosition"];
|
||||
|
||||
pointLightPositionParam = Parameters["PointLightPosition"];
|
||||
pointLightColorParam = Parameters["PointLightColor"];
|
||||
|
||||
farPlaneParam = Parameters["FarPlane"];
|
||||
|
||||
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class Deferred_ToonEffect : Effect, ShadowCascadeEffect
|
||||
{
|
||||
EffectParameter gPositionParam;
|
||||
EffectParameter gAlbedoParam;
|
||||
EffectParameter gNormalParam;
|
||||
EffectParameter gMetallicRoughnessParam;
|
||||
|
||||
EffectParameter shadowMapOneParam;
|
||||
EffectParameter shadowMapTwoParam;
|
||||
EffectParameter shadowMapThreeParam;
|
||||
EffectParameter shadowMapFourParam;
|
||||
|
||||
EffectParameter eyePositionParam;
|
||||
EffectParameter directionalLightDirectionParam;
|
||||
EffectParameter directionalLightColorParam;
|
||||
|
||||
EffectParameter cascadeFarPlanesParam;
|
||||
EffectParameter shadowMapSizeParam;
|
||||
|
||||
EffectParameter lightSpaceMatrixOneParam;
|
||||
EffectParameter lightSpaceMatrixTwoParam;
|
||||
EffectParameter lightSpaceMatrixThreeParam;
|
||||
EffectParameter lightSpaceMatrixFourParam;
|
||||
|
||||
EffectParameter viewMatrixParam;
|
||||
|
||||
EffectParameter shaderIndexParam;
|
||||
|
||||
public Texture2D GPosition { get; set; }
|
||||
public Texture2D GAlbedo { get; set; }
|
||||
public Texture2D GNormal { get; set; }
|
||||
public Texture2D GMetallicRoughness { get; set; }
|
||||
|
||||
public Texture2D ShadowMapOne { get; set; }
|
||||
public Texture2D ShadowMapTwo { get; set; }
|
||||
public Texture2D ShadowMapThree { get; set; }
|
||||
public Texture2D ShadowMapFour { get; set; }
|
||||
|
||||
public Vector3 EyePosition { get; set; }
|
||||
public Vector3 DirectionalLightDirection { get; set; }
|
||||
public Vector3 DirectionalLightColor { get; set; }
|
||||
|
||||
public float[] CascadeFarPlanes { get; }
|
||||
public float ShadowMapSize { get; set; }
|
||||
|
||||
public Matrix LightSpaceMatrixOne { get; set; }
|
||||
public Matrix LightSpaceMatrixTwo { get; set; }
|
||||
public Matrix LightSpaceMatrixThree { get; set; }
|
||||
public Matrix LightSpaceMatrixFour { get; set; }
|
||||
|
||||
public Matrix ViewMatrix { get; set; }
|
||||
|
||||
private bool ditheredShadowValue = false;
|
||||
public bool DitheredShadows
|
||||
{
|
||||
get { return ditheredShadowValue; }
|
||||
set
|
||||
{
|
||||
ditheredShadowValue = value;
|
||||
CalculateShaderIndex();
|
||||
}
|
||||
}
|
||||
|
||||
private int shaderIndex = 0;
|
||||
|
||||
public Deferred_ToonEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.Deferred_ToonEffect)
|
||||
{
|
||||
CascadeFarPlanes = new float[4];
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
gPositionParam.SetValue(GPosition);
|
||||
gAlbedoParam.SetValue(GAlbedo);
|
||||
gNormalParam.SetValue(GNormal);
|
||||
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
||||
|
||||
shadowMapOneParam.SetValue(ShadowMapOne);
|
||||
shadowMapTwoParam.SetValue(ShadowMapTwo);
|
||||
shadowMapThreeParam.SetValue(ShadowMapThree);
|
||||
shadowMapFourParam.SetValue(ShadowMapFour);
|
||||
|
||||
eyePositionParam.SetValue(EyePosition);
|
||||
directionalLightDirectionParam.SetValue(DirectionalLightDirection);
|
||||
directionalLightColorParam.SetValue(DirectionalLightColor);
|
||||
|
||||
cascadeFarPlanesParam.SetValue(CascadeFarPlanes);
|
||||
shadowMapSizeParam.SetValue(ShadowMapSize);
|
||||
|
||||
lightSpaceMatrixOneParam.SetValue(LightSpaceMatrixOne);
|
||||
lightSpaceMatrixTwoParam.SetValue(LightSpaceMatrixTwo);
|
||||
lightSpaceMatrixThreeParam.SetValue(LightSpaceMatrixThree);
|
||||
lightSpaceMatrixFourParam.SetValue(LightSpaceMatrixFour);
|
||||
|
||||
viewMatrixParam.SetValue(ViewMatrix);
|
||||
|
||||
shaderIndexParam.SetValue(shaderIndex);
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
gPositionParam = Parameters["gPosition"];
|
||||
gAlbedoParam = Parameters["gAlbedo"];
|
||||
gNormalParam = Parameters["gNormal"];
|
||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||
|
||||
shadowMapOneParam = Parameters["shadowMapOne"];
|
||||
shadowMapTwoParam = Parameters["shadowMapTwo"];
|
||||
shadowMapThreeParam = Parameters["shadowMapThree"];
|
||||
shadowMapFourParam = Parameters["shadowMapFour"];
|
||||
|
||||
eyePositionParam = Parameters["EyePosition"];
|
||||
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
||||
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
||||
|
||||
cascadeFarPlanesParam = Parameters["CascadeFarPlanes"];
|
||||
shadowMapSizeParam = Parameters["ShadowMapSize"];
|
||||
|
||||
lightSpaceMatrixOneParam = Parameters["LightSpaceMatrixOne"];
|
||||
lightSpaceMatrixTwoParam = Parameters["LightSpaceMatrixTwo"];
|
||||
lightSpaceMatrixThreeParam = Parameters["LightSpaceMatrixThree"];
|
||||
lightSpaceMatrixFourParam = Parameters["LightSpaceMatrixFour"];
|
||||
|
||||
viewMatrixParam = Parameters["ViewMatrix"];
|
||||
|
||||
shaderIndexParam = Parameters["ShaderIndex"];
|
||||
}
|
||||
|
||||
private void CalculateShaderIndex()
|
||||
{
|
||||
if (ditheredShadowValue)
|
||||
{
|
||||
shaderIndex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
using Kav.Data;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class DiffuseLitSpriteEffect : Effect
|
||||
{
|
||||
EffectParameter ambientColorParam;
|
||||
|
||||
EffectParameter directionalLightDirectionParam;
|
||||
EffectParameter directionalLightColorParam;
|
||||
|
||||
EffectParameter uvOffsetAndDimensionsParam;
|
||||
|
||||
EffectParameter worldParam;
|
||||
EffectParameter worldViewProjectionParam;
|
||||
EffectParameter worldInverseTransposeParam;
|
||||
|
||||
EffectParameter shaderIndexParam;
|
||||
|
||||
Texture2D texture;
|
||||
Texture2D normal;
|
||||
|
||||
bool normalMapEnabled = false;
|
||||
|
||||
Vector3 ambientColor;
|
||||
|
||||
Vector3 directionalLightDirection;
|
||||
Vector3 directionalLightColor;
|
||||
|
||||
Matrix world = Matrix.Identity;
|
||||
Matrix view = Matrix.Identity;
|
||||
Matrix projection = Matrix.Identity;
|
||||
|
||||
Vector2 uvOffset;
|
||||
Vector2 subTextureDimensions;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
public bool NormalMapEnabled
|
||||
{
|
||||
get { return normalMapEnabled; }
|
||||
set
|
||||
{
|
||||
if (normalMapEnabled != value)
|
||||
{
|
||||
normalMapEnabled = value;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix World
|
||||
{
|
||||
get { return world; }
|
||||
set
|
||||
{
|
||||
world = value;
|
||||
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxPointLights { get; } = 8;
|
||||
|
||||
public Vector3 AmbientColor
|
||||
{
|
||||
get { return ambientColor; }
|
||||
set
|
||||
{
|
||||
ambientColor = value;
|
||||
ambientColorParam.SetValue(ambientColor);
|
||||
}
|
||||
}
|
||||
|
||||
public PointLightCollection PointLights { get; private set; }
|
||||
|
||||
public Vector3 DirectionalLightDirection
|
||||
{
|
||||
get { return directionalLightDirection; }
|
||||
set
|
||||
{
|
||||
directionalLightDirection = value;
|
||||
directionalLightDirectionParam.SetValue(directionalLightDirection);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 DirectionalLightColor
|
||||
{
|
||||
get { return directionalLightColor; }
|
||||
set
|
||||
{
|
||||
directionalLightColor = value;
|
||||
directionalLightColorParam.SetValue(directionalLightColor);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 UVOffset
|
||||
{
|
||||
get { return uvOffset; }
|
||||
set
|
||||
{
|
||||
uvOffset = value;
|
||||
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 SubTextureDimensions
|
||||
{
|
||||
get { return subTextureDimensions; }
|
||||
set
|
||||
{
|
||||
subTextureDimensions = value;
|
||||
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
public DiffuseLitSpriteEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DiffuseLitSpriteEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
|
||||
PointLights = new PointLightCollection(
|
||||
Parameters["PointLightPositions"],
|
||||
Parameters["PointLightColors"],
|
||||
MaxPointLights
|
||||
);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||
{
|
||||
worldParam.SetValue(world);
|
||||
|
||||
Matrix.Invert(ref world, out Matrix worldInverse);
|
||||
Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose);
|
||||
worldInverseTransposeParam.SetValue(worldInverseTranspose);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||
}
|
||||
|
||||
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.UVOrDimensions) != 0)
|
||||
{
|
||||
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
||||
UVOffset.X, UVOffset.Y,
|
||||
SubTextureDimensions.X, SubTextureDimensions.Y
|
||||
));
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||
{
|
||||
int shaderIndex = 0;
|
||||
|
||||
if (normalMapEnabled)
|
||||
{
|
||||
shaderIndex = 1;
|
||||
}
|
||||
|
||||
shaderIndexParam.SetValue(shaderIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
worldParam = Parameters["World"];
|
||||
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
||||
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
|
||||
|
||||
ambientColorParam = Parameters["AmbientColor"];
|
||||
|
||||
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
||||
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
||||
|
||||
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
||||
|
||||
shaderIndexParam = Parameters["ShaderIndex"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class DirectionalLightCollection
|
||||
{
|
||||
private readonly Vector3[] directions = new Vector3[4];
|
||||
private readonly Vector3[] colors = new Vector3[4];
|
||||
private readonly float[] intensities = new float[4];
|
||||
private readonly Matrix[] lightSpaceMatrices = new Matrix[4];
|
||||
|
||||
readonly EffectParameter lightDirectionsParam;
|
||||
readonly EffectParameter lightColorsParam;
|
||||
readonly EffectParameter lightSpaceMatricesParam;
|
||||
|
||||
public DirectionalLightCollection(
|
||||
EffectParameter lightDirectionsParam,
|
||||
EffectParameter lightColorsParam,
|
||||
EffectParameter lightSpaceMatricesParam
|
||||
) {
|
||||
this.lightDirectionsParam = lightDirectionsParam;
|
||||
this.lightColorsParam = lightColorsParam;
|
||||
this.lightSpaceMatricesParam = lightSpaceMatricesParam;
|
||||
}
|
||||
|
||||
public DirectionalLight this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
var color = colors[i] / intensities[i];
|
||||
return new DirectionalLight(
|
||||
directions[i],
|
||||
new Color(
|
||||
color.X,
|
||||
color.Y,
|
||||
color.Z,
|
||||
1f
|
||||
),
|
||||
intensities[i]
|
||||
);
|
||||
}
|
||||
set
|
||||
{
|
||||
directions[i] = value.Direction;
|
||||
colors[i] = value.Color.ToVector3() * value.Intensity;
|
||||
intensities[i] = value.Intensity;
|
||||
lightSpaceMatrices[i] = value.View * value.Projection;
|
||||
lightDirectionsParam.SetValue(directions);
|
||||
lightColorsParam.SetValue(colors);
|
||||
lightSpaceMatricesParam.SetValue(lightSpaceMatrices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,10 +8,7 @@ namespace Kav
|
|||
WorldViewProj = 1,
|
||||
World = 2,
|
||||
EyePosition = 4,
|
||||
VertexShaderIndex = 8,
|
||||
PixelShaderIndex = 16,
|
||||
ViewProj = 32,
|
||||
UVOrDimensions = 64,
|
||||
ShaderIndex = 8,
|
||||
All = -1
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
BIN
Effects/FXB/DeferredPBR_AmbientLightEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_AmbientLightEffect.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/DeferredPBR_DirectionalLightEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_DirectionalLightEffect.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/Deferred_ToonEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/Deferred_ToonEffect.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/DiffuseLitSpriteEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DiffuseLitSpriteEffect.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Effects/FXB/LinearDepthEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/LinearDepthEffect.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/LinearDepthEffectInstanced.fxb (Stored with Git LFS)
BIN
Effects/FXB/LinearDepthEffectInstanced.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Effects/FXB/PaletteCrushEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/PaletteCrushEffect.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Effects/FXB/SimpleDepthEffectInstanced.fxb (Stored with Git LFS)
BIN
Effects/FXB/SimpleDepthEffectInstanced.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/SkyboxEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/SkyboxEffect.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/ToneMapEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/ToneMapEffect.fxb (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
|||
float3 HUEtoRGB(in float H)
|
||||
{
|
||||
float R = abs(H * 6 - 3) - 1;
|
||||
float G = 2 - abs(H * 6 - 2);
|
||||
float B = 2 - abs(H * 6 - 4);
|
||||
return saturate(float3(R,G,B));
|
||||
}
|
||||
|
||||
float Epsilon = 1e-10;
|
||||
|
||||
float3 RGBtoHCV(in float3 RGB)
|
||||
{
|
||||
// Based on work by Sam Hocevar and Emil Persson
|
||||
float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0/3.0) : float4(RGB.gb, 0.0, -1.0/3.0);
|
||||
float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
|
||||
float C = Q.x - min(Q.w, Q.y);
|
||||
float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
|
||||
return float3(H, C, Q.x);
|
||||
}
|
||||
|
||||
float3 RGBtoHSL(float3 RGB)
|
||||
{
|
||||
float3 HCV = RGBtoHCV(RGB);
|
||||
float L = HCV.z - HCV.y * 0.5;
|
||||
float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
|
||||
return float3(HCV.x, S, L);
|
||||
}
|
||||
|
||||
float3 HSLtoRGB(float3 HSL)
|
||||
{
|
||||
float3 RGB = HUEtoRGB(HSL.x);
|
||||
float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
|
||||
return (RGB - 0.5) * C + HSL.z;
|
||||
}
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
static const float PI = 3.141592653589793;
|
||||
static const int MAX_POINT_LIGHTS = 64;
|
||||
static const int NUM_SHADOW_CASCADES = 4;
|
||||
static const int MAX_DIRECTIONAL_LIGHTS = 4;
|
||||
|
||||
DECLARE_TEXTURE(gPosition, 0);
|
||||
DECLARE_TEXTURE(gAlbedo, 1);
|
||||
DECLARE_TEXTURE(gNormal, 2);
|
||||
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
||||
DECLARE_TEXTURE(shadowMapOne, 4);
|
||||
DECLARE_TEXTURE(shadowMapTwo, 5);
|
||||
DECLARE_TEXTURE(shadowMapThree, 6);
|
||||
DECLARE_TEXTURE(shadowMapFour, 7);
|
||||
DECLARE_CUBEMAP(shadowMap, 4);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
|
@ -20,45 +17,21 @@ BEGIN_CONSTANTS
|
|||
float3 PointLightPositions[MAX_POINT_LIGHTS] _ps(c1) _cb(c1);
|
||||
float3 PointLightColors[MAX_POINT_LIGHTS] _ps(c65) _cb(c65);
|
||||
|
||||
float3 DirectionalLightDirection _ps(c129) _cb(c129);
|
||||
float3 DirectionalLightColor _ps(c130) _cb(c130);
|
||||
|
||||
float CascadeFarPlanes[NUM_SHADOW_CASCADES] _ps(c131) _cb(c131);
|
||||
float3 DirectionalLightDirections[MAX_DIRECTIONAL_LIGHTS] _ps(c129) _cb(c129);
|
||||
float3 DirectionalLightColors[MAX_DIRECTIONAL_LIGHTS] _ps(c133) _cb(c133);
|
||||
|
||||
MATRIX_CONSTANTS
|
||||
|
||||
float4x4 LightSpaceMatrixOne _ps(c135) _cb(c135);
|
||||
float4x4 LightSpaceMatrixTwo _ps(c139) _cb(c139);
|
||||
float4x4 LightSpaceMatrixThree _ps(c143) _cb(c143);
|
||||
float4x4 LightSpaceMatrixFour _ps(c147) _cb(c147);
|
||||
|
||||
// used to select shadow cascade
|
||||
float4x4 ViewMatrix _ps(c151) _cb(c151);
|
||||
float4x4 DirectionalLightMatrices[MAX_DIRECTIONAL_LIGHTS] _ps(c137) _cb(c137);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = input.Position;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
|
||||
float3 FresnelSchlick(float cosTheta, float3 F0)
|
||||
|
@ -101,110 +74,65 @@ float GeometrySmith(float3 N, float3 V, float3 L, float roughness)
|
|||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
float ComputeShadow(float3 positionWorldSpace, float3 N, float L)
|
||||
float3 ConvertCubeUVToXYZ(int index, float u, float v)
|
||||
{
|
||||
float bias = 0.005 * tan(acos(dot(N, L)));
|
||||
bias = clamp(bias, 0, 0.01);
|
||||
float uc = 2.0 * u - 1.0;
|
||||
float vc = 2.0 * v - 1.0;
|
||||
|
||||
float4 positionCameraSpace = mul(float4(positionWorldSpace, 1.0), ViewMatrix);
|
||||
if (index == 0) { return float3(1.0, vc, -uc); }
|
||||
if (index == 1) { return float3(-1.0, vc, uc); }
|
||||
if (index == 2) { return float3(uc, 1.0, -vc); }
|
||||
if (index == 3) { return float3(uc, -1.0, vc); }
|
||||
if (index == 4) { return float3(uc, vc, -1.0); }
|
||||
if (index == 5) { return float3(-uc, vc, 1.0); }
|
||||
|
||||
int shadowCascadeIndex = 0; // 0 is closest
|
||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++)
|
||||
{
|
||||
if (abs(positionCameraSpace.z) < CascadeFarPlanes[i])
|
||||
{
|
||||
shadowCascadeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return float3(1.0, 0.0, 0.5);
|
||||
}
|
||||
|
||||
float4x4 lightSpaceMatrix;
|
||||
float ComputeShadow(float4 positionLightSpace, int directionalLightIndex)
|
||||
{
|
||||
float bias = 0.001;
|
||||
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixOne;
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixTwo;
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixThree;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixFour;
|
||||
}
|
||||
|
||||
float4 positionLightSpace = mul(float4(positionWorldSpace, 1.0), lightSpaceMatrix);
|
||||
|
||||
// maps to [-1, 1]
|
||||
float3 projectionCoords = positionLightSpace.xyz / positionLightSpace.w;
|
||||
|
||||
// maps to [0, 1]
|
||||
projectionCoords.x = (projectionCoords.x * 0.5) + 0.5;
|
||||
projectionCoords.y = (projectionCoords.y * 0.5) + 0.5;
|
||||
projectionCoords.y *= -1;
|
||||
// in XNA clip z is 0 to 1 already
|
||||
float3 cubeMapSampleVector;
|
||||
|
||||
float inc = 1.0 / 1024.0;
|
||||
|
||||
float shadowFactor = 0;
|
||||
for (int row = -1; row <= 1; row++)
|
||||
if (directionalLightIndex == 0)
|
||||
{
|
||||
for (int col = -1; col <= 1; col++)
|
||||
{
|
||||
float closestDepth;
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapOne, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapTwo, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapThree, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
else
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapFour, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
shadowFactor += projectionCoords.z - bias > closestDepth ? 1.0 : 0.0;
|
||||
}
|
||||
cubeMapSampleVector = float3(1.0f, projectionCoords.y, -projectionCoords.x);
|
||||
}
|
||||
else if (directionalLightIndex == 1)
|
||||
{
|
||||
cubeMapSampleVector = float3(-1.0f, projectionCoords.y, projectionCoords.x);
|
||||
}
|
||||
else if (directionalLightIndex == 2)
|
||||
{
|
||||
cubeMapSampleVector = float3(projectionCoords.x, 1.0f, projectionCoords.y);
|
||||
}
|
||||
else if (directionalLightIndex == 3)
|
||||
{
|
||||
cubeMapSampleVector = float3(projectionCoords.x, -1.0f, -projectionCoords.y);
|
||||
}
|
||||
else if (directionalLightIndex == 4)
|
||||
{
|
||||
cubeMapSampleVector = float3(projectionCoords.x, projectionCoords.y, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
cubeMapSampleVector = float3(-projectionCoords.x, projectionCoords.y, -1.0);
|
||||
}
|
||||
|
||||
shadowFactor /= 9.0;
|
||||
float closestDepth = SAMPLE_CUBEMAP(shadowMap, cubeMapSampleVector).r;
|
||||
float currentDepth = projectionCoords.z;
|
||||
|
||||
if (projectionCoords.z > 1.0)
|
||||
{
|
||||
shadowFactor = 1.0;
|
||||
}
|
||||
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
return shadowFactor;
|
||||
|
||||
|
||||
// float currentDepth = projectionCoords.z;
|
||||
|
||||
// if (currentDepth > 1.0)
|
||||
// {
|
||||
// return 0.0;
|
||||
// }
|
||||
|
||||
// if (currentDepth - bias > closestDepth)
|
||||
// {
|
||||
// return 1.0;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return 0.0;
|
||||
// }
|
||||
return shadow;
|
||||
}
|
||||
|
||||
float3 ComputeLight(
|
||||
float3 L,
|
||||
float3 lightDir,
|
||||
float3 radiance,
|
||||
float3 F0,
|
||||
float3 V,
|
||||
|
@ -214,6 +142,7 @@ float3 ComputeLight(
|
|||
float roughness,
|
||||
float shadow
|
||||
) {
|
||||
float3 L = normalize(lightDir);
|
||||
float3 H = normalize(V + L);
|
||||
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
|
@ -252,20 +181,24 @@ float4 ComputeColor(
|
|||
for (int i = 0; i < MAX_POINT_LIGHTS; i++)
|
||||
{
|
||||
float3 lightDir = PointLightPositions[i] - worldPosition;
|
||||
float3 L = normalize(lightDir);
|
||||
float distance = length(lightDir);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
float3 radiance = PointLightColors[i] * attenuation;
|
||||
|
||||
Lo += ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, 1.0);
|
||||
Lo += ComputeLight(lightDir, radiance, F0, V, N, albedo, metallic, roughness, 1.0);
|
||||
}
|
||||
|
||||
// directional light
|
||||
float3 L = normalize(DirectionalLightDirection);
|
||||
float3 radiance = DirectionalLightColor;
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
float4 positionLightSpace = mul(float4(worldPosition, 1.0), DirectionalLightMatrices[i]);
|
||||
float shadow = ComputeShadow(positionLightSpace, i);
|
||||
|
||||
float shadow = ComputeShadow(worldPosition, N, L);
|
||||
Lo += ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, (1.0 - shadow));
|
||||
float3 lightDir = DirectionalLightDirections[i];
|
||||
float3 radiance = DirectionalLightColors[i];
|
||||
|
||||
Lo += ComputeLight(lightDir, radiance, F0, V, N, albedo, metallic, roughness, (1.0 - shadow));
|
||||
}
|
||||
|
||||
float3 ambient = float3(0.03, 0.03, 0.03) * albedo; // * AO;
|
||||
float3 color = ambient + Lo;
|
||||
|
@ -297,7 +230,6 @@ Technique DeferredPBR
|
|||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#include "Macros.fxh" // from FNA
|
||||
|
||||
DECLARE_TEXTURE(gPosition, 0);
|
||||
DECLARE_TEXTURE(gAlbedo, 1);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float3 AmbientLightColor _ps(c0) _cb(c0);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = input.Position;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 ComputeColor(
|
||||
float3 worldPosition,
|
||||
float3 albedo
|
||||
) {
|
||||
float3 color = AmbientLightColor * albedo;
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
|
||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
|
||||
float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb;
|
||||
|
||||
return ComputeColor(
|
||||
worldPosition,
|
||||
albedo
|
||||
);
|
||||
}
|
||||
|
||||
Technique DeferredPBR_Ambient
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
#include "Macros.fxh" //from FNA
|
||||
#include "Lighting.fxh"
|
||||
#include "Shadow.fxh"
|
||||
|
||||
static const int NUM_SHADOW_CASCADES = 4;
|
||||
|
||||
DECLARE_TEXTURE(gPosition, 0);
|
||||
DECLARE_TEXTURE(gAlbedo, 1);
|
||||
DECLARE_TEXTURE(gNormal, 2);
|
||||
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
||||
DECLARE_TEXTURE(shadowMapOne, 4);
|
||||
DECLARE_TEXTURE(shadowMapTwo, 5);
|
||||
DECLARE_TEXTURE(shadowMapThree, 6);
|
||||
DECLARE_TEXTURE(shadowMapFour, 7);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float3 EyePosition _ps(c0) _cb(c0);
|
||||
|
||||
float3 DirectionalLightDirection _ps(c1) _cb(c1);
|
||||
float3 DirectionalLightColor _ps(c2) _cb(c2);
|
||||
|
||||
float CascadeFarPlanes[NUM_SHADOW_CASCADES] _ps(c3) _cb(c3);
|
||||
|
||||
float ShadowMapSize _ps(c7) _cb(c7);
|
||||
|
||||
MATRIX_CONSTANTS
|
||||
|
||||
float4x4 LightSpaceMatrixOne _ps(c8) _cb(c8);
|
||||
float4x4 LightSpaceMatrixTwo _ps(c12) _cb(c12);
|
||||
float4x4 LightSpaceMatrixThree _ps(c16) _cb(c16);
|
||||
float4x4 LightSpaceMatrixFour _ps(c20) _cb(c20);
|
||||
|
||||
// used to select shadow cascade
|
||||
float4x4 ViewMatrix _ps(c24) _cb(c24);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = input.Position;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
|
||||
float ComputeShadow(float3 positionWorldSpace, float3 N, float3 L)
|
||||
{
|
||||
float4 positionCameraSpace = mul(float4(positionWorldSpace, 1.0), ViewMatrix);
|
||||
|
||||
int shadowCascadeIndex = 0; // 0 is closest
|
||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++)
|
||||
{
|
||||
if (abs(positionCameraSpace.z) < CascadeFarPlanes[i])
|
||||
{
|
||||
shadowCascadeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float4x4 lightSpaceMatrix;
|
||||
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixOne;
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixTwo;
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixThree;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixFour;
|
||||
}
|
||||
|
||||
// PCF + Poisson soft shadows
|
||||
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
return PoissonShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapOne),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
return PoissonShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapTwo),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
return PoissonShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapThree),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PoissonShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapFour),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
float4 ComputeColor(
|
||||
float3 worldPosition,
|
||||
float3 worldNormal,
|
||||
float3 albedo,
|
||||
float metallic,
|
||||
float roughness
|
||||
) {
|
||||
float3 V = normalize(EyePosition - worldPosition);
|
||||
float3 N = normalize(worldNormal);
|
||||
|
||||
float3 F0 = float3(0.04, 0.04, 0.04);
|
||||
F0 = lerp(F0, albedo, metallic);
|
||||
|
||||
float3 L = normalize(DirectionalLightDirection);
|
||||
float3 radiance = DirectionalLightColor;
|
||||
|
||||
float shadow = ComputeShadow(worldPosition, N, L);
|
||||
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow);
|
||||
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
|
||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
|
||||
float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz;
|
||||
float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb;
|
||||
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, input.TexCoord).rg;
|
||||
|
||||
return ComputeColor(
|
||||
worldPosition,
|
||||
normal,
|
||||
albedo,
|
||||
metallicRoughness.r,
|
||||
metallicRoughness.g
|
||||
);
|
||||
}
|
||||
|
||||
Technique DeferredPBR_Directional
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -4,22 +4,17 @@ DECLARE_TEXTURE(AlbedoTexture, 0);
|
|||
DECLARE_TEXTURE(NormalTexture, 1);
|
||||
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
||||
|
||||
float4 UVOffsetAndDimensions;
|
||||
float IsSprite;
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float3 AlbedoValue _ps(c0) _cb(c0);
|
||||
float MetallicValue _ps(c1) _cb(c1);
|
||||
float RoughnessValue _ps(c2) _cb(c2);
|
||||
|
||||
int NumTextureRows _vs(c9) _cb(c3);
|
||||
int NumTextureColumns _vs(c10) _cb(c4);
|
||||
|
||||
MATRIX_CONSTANTS
|
||||
|
||||
float4x4 World _vs(c0) _cb(c7);
|
||||
float4x4 ViewProjection _vs(c4) _cb(c11);
|
||||
float4x4 WorldInverseTranspose _vs(c4) _cb(c11);
|
||||
float4x4 WorldViewProjection _vs(c8) _cb(c15);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
|
@ -27,7 +22,7 @@ struct VertexInput
|
|||
{
|
||||
float4 Position : POSITION;
|
||||
float3 Normal : NORMAL;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
|
@ -53,44 +48,9 @@ PixelInput main_vs(VertexInput input)
|
|||
PixelInput output;
|
||||
|
||||
output.PositionWorld = mul(input.Position, World).xyz;
|
||||
output.NormalWorld = normalize(mul(input.Normal, World));
|
||||
|
||||
float2 texCoord;
|
||||
texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
||||
texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
||||
output.TexCoord = texCoord;
|
||||
|
||||
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
PixelInput instanced_vs(
|
||||
VertexInput input,
|
||||
float3 Translation : TEXCOORD2,
|
||||
float2 UVOffset : TEXCOORD5
|
||||
) {
|
||||
PixelInput output;
|
||||
|
||||
float4x4 world = float4x4(
|
||||
float4(1, 0, 0, 0),
|
||||
float4(0, 1, 0, 0),
|
||||
float4(0, 0, 1, 0),
|
||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||
);
|
||||
|
||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||
|
||||
output.PositionWorld = mul(input.Position, world);
|
||||
output.NormalWorld = mul(input.Normal, world);
|
||||
|
||||
float2 texCoord;
|
||||
texCoord.x = (input.TexCoord.x / NumTextureColumns + UVOffset.x);
|
||||
texCoord.y = (input.TexCoord.y / NumTextureRows + UVOffset.y);
|
||||
output.TexCoord = texCoord;
|
||||
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
output.NormalWorld = mul(input.Normal, (float3x3)WorldInverseTranspose).xyz;
|
||||
output.TexCoord = input.TexCoord;
|
||||
output.Position = mul(input.Position, WorldViewProjection);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -119,10 +79,10 @@ PixelOutput NonePS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), 0.0);
|
||||
output.gAlbedo = float4(AlbedoValue, 1.0);
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 0.0);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -131,12 +91,10 @@ PixelOutput AlbedoPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), 0.0);
|
||||
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||
|
||||
if (output.gAlbedo.a == 0.0) { discard; }
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 0.0);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -145,8 +103,8 @@ PixelOutput MetallicRoughnessPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), 0.0);
|
||||
output.gAlbedo = float4(AlbedoValue, 1.0);
|
||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||
|
||||
|
@ -157,10 +115,10 @@ PixelOutput NormalPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 0.0);
|
||||
output.gAlbedo = float4(AlbedoValue, 1.0);
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 0.0);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -169,13 +127,11 @@ PixelOutput AlbedoMetallicRoughnessPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(normalize(input.NormalWorld), 0.0);
|
||||
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||
|
||||
if (output.gAlbedo.a == 0.0) { discard; }
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -183,12 +139,10 @@ PixelOutput AlbedoNormalPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 0.0);
|
||||
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||
|
||||
if (output.gAlbedo.a == 0.0) { discard; }
|
||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 0.0);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -197,8 +151,8 @@ PixelOutput MetallicRoughnessNormalPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 0.0);
|
||||
output.gAlbedo = float4(AlbedoValue, 1.0);
|
||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||
|
||||
|
@ -209,29 +163,14 @@ PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input)
|
|||
{
|
||||
PixelOutput output;
|
||||
|
||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||
output.gPosition = float4(input.PositionWorld, 0.0);
|
||||
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 0.0);
|
||||
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||
|
||||
if (output.gAlbedo.a == 0.0) { discard; }
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
VertexShader VSArray[2] =
|
||||
{
|
||||
compile vs_3_0 main_vs(),
|
||||
compile vs_3_0 instanced_vs()
|
||||
};
|
||||
|
||||
int VSIndices[2] =
|
||||
{
|
||||
0, 1
|
||||
};
|
||||
|
||||
int VertexShaderIndex = 0;
|
||||
|
||||
PixelShader PSArray[8] =
|
||||
{
|
||||
compile ps_3_0 NonePS(),
|
||||
|
@ -252,13 +191,13 @@ int PSIndices[8] =
|
|||
0, 1, 2, 3, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
int PixelShaderIndex = 0;
|
||||
int ShaderIndex = 0;
|
||||
|
||||
Technique GBuffer
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = (VSArray[VSIndices[VertexShaderIndex]]);
|
||||
PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
// Assumes you are drawing a sphere!!
|
||||
|
||||
#include "Macros.fxh" //from FNA
|
||||
#include "Lighting.fxh"
|
||||
#include "Shadow.fxh"
|
||||
|
||||
DECLARE_TEXTURE(gPosition, 0);
|
||||
DECLARE_TEXTURE(gAlbedo, 1);
|
||||
DECLARE_TEXTURE(gNormal, 2);
|
||||
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
||||
DECLARE_CUBEMAP(shadowMap, 4);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float3 EyePosition _ps(c0) _cb(c0);
|
||||
|
||||
float3 PointLightPosition _ps(c1) _cb(c1);
|
||||
float3 PointLightColor _ps(c2) _cb(c2);
|
||||
|
||||
float FarPlane _ps(c3) _cb(c3);
|
||||
|
||||
MATRIX_CONSTANTS
|
||||
|
||||
float4x4 WorldViewProjection _vs(c0) _cb(c4);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 ScreenPosition : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = mul(input.Position, WorldViewProjection);
|
||||
output.ScreenPosition = output.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
|
||||
float4 ComputeColor(
|
||||
float3 worldPosition,
|
||||
float3 worldNormal,
|
||||
float3 albedo,
|
||||
float metallic,
|
||||
float roughness
|
||||
) {
|
||||
float3 V = normalize(EyePosition - worldPosition);
|
||||
float3 N = normalize(worldNormal);
|
||||
|
||||
float3 F0 = float3(0.04, 0.04, 0.04);
|
||||
F0 = lerp(F0, albedo, metallic);
|
||||
|
||||
float3 lightDir = PointLightPosition - worldPosition;
|
||||
float3 L = normalize(lightDir);
|
||||
float distance = length(lightDir);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
float3 radiance = PointLightColor * attenuation;
|
||||
|
||||
float shadow = HardPointShadow(worldPosition, N, L, PointLightPosition, SAMPLER(shadowMap), FarPlane);
|
||||
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow);
|
||||
|
||||
return float4(color, 1.0);
|
||||
//return float4(shadow, shadow, shadow, 1.0);
|
||||
}
|
||||
|
||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
input.ScreenPosition.xy /= input.ScreenPosition.w;
|
||||
float2 texCoord = 0.5f * float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 0.5f;
|
||||
|
||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, texCoord).rgb;
|
||||
float4 normalSample = SAMPLE_TEXTURE(gNormal, texCoord);
|
||||
float3 normal = normalSample.xyz;
|
||||
float isSprite = normalSample.a;
|
||||
float3 albedo = SAMPLE_TEXTURE(gAlbedo, texCoord).rgb;
|
||||
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, texCoord).rg;
|
||||
|
||||
if (isSprite == 1.0)
|
||||
{
|
||||
float3 lightDir = PointLightPosition - worldPosition;
|
||||
float3 L = normalize(lightDir);
|
||||
float distance = length(lightDir);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
float3 radiance = PointLightColor * attenuation;
|
||||
|
||||
return float4(albedo * radiance * 0.1, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ComputeColor(
|
||||
worldPosition,
|
||||
normal,
|
||||
albedo,
|
||||
metallicRoughness.r,
|
||||
metallicRoughness.g
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Technique DeferredPBR_Point
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,285 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
#include "Shadow.fxh"
|
||||
#include "Dither.fxh"
|
||||
|
||||
static const int NUM_SHADOW_CASCADES = 4;
|
||||
|
||||
DECLARE_TEXTURE(gPosition, 0);
|
||||
DECLARE_TEXTURE(gAlbedo, 1);
|
||||
DECLARE_TEXTURE(gNormal, 2);
|
||||
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
||||
DECLARE_TEXTURE(shadowMapOne, 4);
|
||||
DECLARE_TEXTURE(shadowMapTwo, 5);
|
||||
DECLARE_TEXTURE(shadowMapThree, 6);
|
||||
DECLARE_TEXTURE(shadowMapFour, 7);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float3 EyePosition _ps(c0) _cb(c0);
|
||||
|
||||
float3 DirectionalLightDirection _ps(c1) _cb(c1);
|
||||
float3 DirectionalLightColor _ps(c2) _cb(c2);
|
||||
|
||||
float CascadeFarPlanes[NUM_SHADOW_CASCADES] _ps(c4) _cb(c4);
|
||||
|
||||
float ShadowMapSize _ps(c8) _cb(c8);
|
||||
|
||||
MATRIX_CONSTANTS
|
||||
|
||||
float4x4 LightSpaceMatrixOne _ps(c9) _cb(c9);
|
||||
float4x4 LightSpaceMatrixTwo _ps(c13) _cb(c13);
|
||||
float4x4 LightSpaceMatrixThree _ps(c17) _cb(c17);
|
||||
float4x4 LightSpaceMatrixFour _ps(c21) _cb(c21);
|
||||
|
||||
float4x4 ViewMatrix _ps(c25) _cb(c25);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = input.Position;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float ComputeShadow(float3 positionWorldSpace, float3 N, float3 L)
|
||||
{
|
||||
float4 positionCameraSpace = mul(float4(positionWorldSpace, 1.0), ViewMatrix);
|
||||
|
||||
int shadowCascadeIndex = 0; // 0 is closest
|
||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++)
|
||||
{
|
||||
if (abs(positionCameraSpace.z) < CascadeFarPlanes[i])
|
||||
{
|
||||
shadowCascadeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float4x4 lightSpaceMatrix;
|
||||
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixOne;
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixTwo;
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixThree;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightSpaceMatrix = LightSpaceMatrixFour;
|
||||
}
|
||||
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
return HardShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapOne),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
return HardShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapTwo),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
return HardShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapThree),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HardShadow(
|
||||
positionWorldSpace,
|
||||
N,
|
||||
L,
|
||||
lightSpaceMatrix,
|
||||
SAMPLER(shadowMapFour),
|
||||
ShadowMapSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
float IntensityBanding(float NdotL)
|
||||
{
|
||||
// if (NdotL > 0.5)
|
||||
// {
|
||||
// return 1.0;
|
||||
// }
|
||||
// else if (NdotL > 0.25)
|
||||
// {
|
||||
// return 0.5;
|
||||
// }
|
||||
// else if (NdotL > 0.0)
|
||||
// {
|
||||
// return 0.25;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return 0.0;
|
||||
// }
|
||||
if (NdotL > 0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
float4 FlatShadow(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
float2 screenPosition = input.Position.xy;
|
||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
|
||||
float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz;
|
||||
float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb;
|
||||
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, input.TexCoord).rg;
|
||||
|
||||
// the lower the glossiness, the sharper the specular highlight
|
||||
float glossiness = lerp(64, 16, 1.0 - metallicRoughness.r);
|
||||
|
||||
float3 V = normalize(EyePosition - worldPosition);
|
||||
float3 L = normalize(DirectionalLightDirection);
|
||||
float3 N = normalize(normal);
|
||||
float3 H = normalize(V + L);
|
||||
|
||||
float NdotL = dot(N, L);
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
|
||||
float lightIntensity = IntensityBanding(NdotL);
|
||||
float3 light = lightIntensity * DirectionalLightColor;
|
||||
|
||||
float specularIntensity = pow(NdotH * lightIntensity, glossiness * glossiness);
|
||||
float specularSmooth = smoothstep(0.005, 0.01, specularIntensity);
|
||||
|
||||
float3 specular = specularSmooth * float3(1.0, 1.0, 1.0);
|
||||
|
||||
if (metallicRoughness.r == 0.0) { specular = float3(0.0, 0.0, 0.0); }
|
||||
|
||||
float3 rimColor = float3(1.0, 1.0, 1.0);
|
||||
float rimThreshold = 0.1;
|
||||
float rimAmount = 1 - metallicRoughness.g;
|
||||
float rimDot = 1 - dot(V, N);
|
||||
float rimIntensity = rimDot * pow(max(NdotL, 0.0), rimThreshold);
|
||||
rimIntensity = smoothstep(rimAmount - 0.01, rimAmount + 0.01, rimIntensity);
|
||||
float3 rim = rimIntensity * rimColor;
|
||||
|
||||
float shadow = ComputeShadow(worldPosition, N, L);
|
||||
float3 color = albedo * (light + specular + rim) * shadow;
|
||||
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
|
||||
// FIXME: organize this
|
||||
float4 DitheredShadow(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
float2 screenPosition = input.Position.xy;
|
||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
|
||||
float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz;
|
||||
float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb;
|
||||
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, input.TexCoord).rg;
|
||||
|
||||
// the lower the glossiness, the sharper the specular highlight
|
||||
float glossiness = lerp(64, 16, 1.0 - metallicRoughness.r);
|
||||
|
||||
float3 V = normalize(EyePosition - worldPosition);
|
||||
float3 L = normalize(DirectionalLightDirection);
|
||||
float3 N = normalize(normal);
|
||||
float3 H = normalize(V + L);
|
||||
|
||||
float NdotL = dot(N, L);
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
|
||||
float lightIntensity = IntensityBanding(NdotL);
|
||||
//float3 light = lightIntensity * DirectionalLightColor;
|
||||
float3 light = DirectionalLightColor;
|
||||
|
||||
if (lightIntensity < 1)
|
||||
{
|
||||
light *= dither(lightIntensity, screenPosition);
|
||||
}
|
||||
|
||||
float specularIntensity = pow(NdotH * lightIntensity, glossiness * glossiness);
|
||||
float specularSmooth = smoothstep(0.005, 0.01, specularIntensity);
|
||||
|
||||
float3 specular = specularSmooth * float3(1.0, 1.0, 1.0);
|
||||
|
||||
if (metallicRoughness.r == 0.0) { specular = float3(0.0, 0.0, 0.0); }
|
||||
|
||||
float3 rimColor = float3(1.0, 1.0, 1.0);
|
||||
float rimThreshold = 0.1;
|
||||
float rimAmount = 1 - metallicRoughness.g;
|
||||
float rimDot = 1 - dot(V, N);
|
||||
float rimIntensity = rimDot * pow(max(NdotL, 0.0), rimThreshold);
|
||||
rimIntensity = smoothstep(rimAmount - 0.01, rimAmount + 0.01, rimIntensity);
|
||||
float3 rim = rimIntensity * rimColor;
|
||||
|
||||
float shadow = ComputeShadow(worldPosition, N, L);
|
||||
float3 color = albedo * (light + specular + rim); // * shadow;
|
||||
|
||||
if (shadow < 1)
|
||||
{
|
||||
color *= dither(shadow, screenPosition);
|
||||
}
|
||||
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
|
||||
PixelShader PSArray[2] =
|
||||
{
|
||||
compile ps_3_0 FlatShadow(),
|
||||
compile ps_3_0 DitheredShadow()
|
||||
};
|
||||
|
||||
int PSIndices[2] =
|
||||
{
|
||||
0, 1
|
||||
};
|
||||
|
||||
int ShaderIndex = 0;
|
||||
|
||||
Technique Deferred_Toon
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
#include "Macros.fxh" //from FNA
|
||||
|
||||
// Effect applies normalmapped lighting to a 2D sprite.
|
||||
|
||||
DECLARE_TEXTURE(Texture, 0);
|
||||
DECLARE_TEXTURE(Normal, 1);
|
||||
|
||||
float3 AmbientColor;
|
||||
|
||||
float3 PointLightPositions[8];
|
||||
float3 PointLightColors[8];
|
||||
|
||||
float3 DirectionalLightDirection;
|
||||
float3 DirectionalLightColor;
|
||||
|
||||
float4 UVOffsetAndDimensions;
|
||||
|
||||
float4x4 WorldInverseTranspose;
|
||||
float4x4 World;
|
||||
float4x4 WorldViewProjection;
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float3 Normal : NORMAL;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float3 NormalWS : TEXCOORD1;
|
||||
float3 PositionWS : TEXCOORD2;
|
||||
};
|
||||
|
||||
PixelShaderInput main_vs(VertexShaderInput input)
|
||||
{
|
||||
PixelShaderInput output;
|
||||
|
||||
output.Position = mul(input.Position, WorldViewProjection);
|
||||
output.NormalWS = normalize(mul(input.Normal, (float3x3)WorldInverseTranspose));
|
||||
output.PositionWS = mul(input.Position, World).xyz;
|
||||
|
||||
float2 texCoord;
|
||||
texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
||||
texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
||||
output.TexCoord = texCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Easy trick to get tangent-normals to world-space to keep PBR code simplified.
|
||||
float3 GetNormalFromMap(float3 worldPos, float2 texCoords, float3 normal)
|
||||
{
|
||||
float3 tangentNormal = SAMPLE_TEXTURE(Normal, texCoords).xyz * 2.0 - 1.0;
|
||||
|
||||
float3 Q1 = ddx(worldPos);
|
||||
float3 Q2 = ddy(worldPos);
|
||||
float2 st1 = ddx(texCoords);
|
||||
float2 st2 = ddy(texCoords);
|
||||
|
||||
float3 N = normalize(normal);
|
||||
float3 T = normalize(Q1*st2.y - Q2*st1.y);
|
||||
float3 B = -normalize(cross(N, T));
|
||||
float3x3 TBN = float3x3(T, B, N);
|
||||
|
||||
return normalize(mul(tangentNormal, TBN));
|
||||
}
|
||||
|
||||
float4 LightColor(float3 worldPosition, float3 worldNormal)
|
||||
{
|
||||
float3 lightColor = float3(0.0, 0.0, 0.0);
|
||||
|
||||
// point lights
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
float3 lightVec = PointLightPositions[i] - worldPosition;
|
||||
float distance = length(lightVec);
|
||||
|
||||
float3 lightDir = normalize(lightVec);
|
||||
float diffuse = max(dot(worldNormal, lightDir), 0.0);
|
||||
float3 attenuation = 1.0 / (distance * distance);
|
||||
|
||||
lightColor += diffuse * attenuation * PointLightColors[i];
|
||||
}
|
||||
|
||||
// directional light
|
||||
float directionalDiffuse = max(dot(worldNormal, DirectionalLightDirection), 0.0);
|
||||
lightColor += directionalDiffuse * DirectionalLightColor;
|
||||
|
||||
// ambient light
|
||||
lightColor += AmbientColor;
|
||||
|
||||
return float4(lightColor, 1.0);
|
||||
}
|
||||
|
||||
float4 WithoutNormalMap(PixelShaderInput input) : COLOR0
|
||||
{
|
||||
float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
||||
|
||||
if (tex.a == 0.0) { discard; }
|
||||
|
||||
float3 normalWS = normalize(input.NormalWS);
|
||||
|
||||
return tex * LightColor(input.PositionWS, normalWS);
|
||||
}
|
||||
|
||||
float4 WithNormalMap(PixelShaderInput input) : COLOR0
|
||||
{
|
||||
float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
||||
|
||||
if (tex.a == 0.0) { discard; }
|
||||
|
||||
float3 normalWS = GetNormalFromMap(input.PositionWS, input.TexCoord, input.NormalWS);
|
||||
|
||||
return tex * LightColor(input.PositionWS, normalWS);
|
||||
}
|
||||
|
||||
PixelShader PSArray[2] =
|
||||
{
|
||||
compile ps_3_0 WithoutNormalMap(),
|
||||
compile ps_3_0 WithNormalMap()
|
||||
};
|
||||
|
||||
int PSIndices[2] =
|
||||
{
|
||||
0, 1
|
||||
};
|
||||
|
||||
int ShaderIndex = 0;
|
||||
|
||||
Technique DiffuseLitSprite
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
#include "Conversion.fxh"
|
||||
|
||||
// technique from http://alex-charlton.com/posts/Dithering_on_the_GPU/
|
||||
|
||||
uniform float3 palette[8];
|
||||
static const int paletteSize = 8;
|
||||
|
||||
static const int indexMatrix4x4[16] =
|
||||
{
|
||||
0, 8, 2, 10,
|
||||
12, 4, 14, 6,
|
||||
3, 11, 1, 9,
|
||||
15, 7, 13, 5
|
||||
};
|
||||
|
||||
float indexValue(float2 screenCoords)
|
||||
{
|
||||
int x = int(screenCoords.x % 4);
|
||||
int y = int(screenCoords.y % 4);
|
||||
|
||||
return indexMatrix4x4[(x + y * 4)] / 16.0;
|
||||
}
|
||||
|
||||
float hueDistance(float h1, float h2)
|
||||
{
|
||||
float diff = abs(h1 - h2);
|
||||
return min(abs(1.0 - diff), diff);
|
||||
}
|
||||
|
||||
void closestColors(float hue, out float3 ret[2])
|
||||
{
|
||||
float3 closest = float3(-2, 0, 0);
|
||||
float3 secondClosest = float3(-2, 0, 0);
|
||||
float3 temp;
|
||||
|
||||
for (int i = 0; i < paletteSize; i++)
|
||||
{
|
||||
temp = palette[i];
|
||||
float tempDistance = hueDistance(temp.x, hue);
|
||||
if (tempDistance < hueDistance(closest.x, hue))
|
||||
{
|
||||
secondClosest = closest;
|
||||
closest = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tempDistance < hueDistance(secondClosest.x, hue))
|
||||
{
|
||||
secondClosest = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret[0] = closest;
|
||||
ret[1] = secondClosest;
|
||||
}
|
||||
|
||||
float3 dither(float3 color, float2 screenCoords)
|
||||
{
|
||||
float3 colors[2];
|
||||
float3 hsl = RGBtoHSL(color);
|
||||
closestColors(hsl.x, colors);
|
||||
float3 closestColor = colors[0];
|
||||
float3 secondClosestColor = colors[1];
|
||||
float d = indexValue(screenCoords);
|
||||
float hueDiff = hueDistance(hsl.x, closestColor.x) / hueDistance(secondClosestColor.x, secondClosestColor.x);
|
||||
return HSLtoRGB(hueDiff < d ? closestColor : secondClosestColor);
|
||||
}
|
||||
|
||||
// brightColor refers to undithered max color
|
||||
// float3 dither(float3 color, float3 brightColor, float2 screenCoords)
|
||||
// {
|
||||
// float brightHue = RGBtoHSL(brightColor.x);
|
||||
// float colorHue = RGBtoHSL(color.x);
|
||||
// float halfDistance = hueDistance(0.0, brightHue) / 2.0;
|
||||
// float3 closestColor = (colorHue < halfDistance) ? float3(0.0, 0.0, 0.0) : brightColor;
|
||||
// float3 secondClosestColor = brightColor - closestColor;
|
||||
// float d = indexValue(screenCoords);
|
||||
// float distance = abs(closestColor - color);
|
||||
// return (distance < d) ? closestColor : secondClosestColor;
|
||||
// }
|
||||
|
||||
float3 dither(float color, float2 screenCoords) {
|
||||
float closestColor = (color < 0.5) ? 0 : 1;
|
||||
float secondClosestColor = 1 - closestColor;
|
||||
float d = indexValue(screenCoords);
|
||||
float distance = abs(closestColor - color);
|
||||
return (distance < d) ? closestColor : secondClosestColor;
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
static const float PI = 3.141592653589793;
|
||||
|
||||
float3 FresnelSchlick(float cosTheta, float3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
float DistributionGGX(float3 N, float3 H, float roughness)
|
||||
{
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH * NdotH;
|
||||
|
||||
float num = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
{
|
||||
float r = (roughness + 1.0);
|
||||
float k = (r * r) / 8.0;
|
||||
|
||||
float num = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
|
||||
float GeometrySmith(float3 N, float3 V, float3 L, float roughness)
|
||||
{
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
float3 ComputeLight(
|
||||
float3 L,
|
||||
float3 radiance,
|
||||
float3 F0,
|
||||
float3 V,
|
||||
float3 N,
|
||||
float3 albedo,
|
||||
float metallic,
|
||||
float roughness,
|
||||
float visibility
|
||||
) {
|
||||
float3 H = normalize(V + L);
|
||||
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float3 F = FresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
float3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
|
||||
float3 specular = numerator / max(denominator, 0.001);
|
||||
|
||||
float3 kS = F;
|
||||
float3 kD = float3(1.0, 1.0, 1.0) - kS;
|
||||
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
return (kD * albedo / PI + specular) * radiance * NdotL * visibility;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float4x4 Model _vs(c0) _cb(c0);
|
||||
float4x4 ModelViewProjection _vs(c4) _cb(c4);
|
||||
|
||||
float3 LightPosition _ps(c0) _cb(c8);
|
||||
float FarPlane _ps(c1) _cb(c9);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 PositionWorld : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexShaderOutput main_vs(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
output.Position = mul(input.Position, ModelViewProjection);
|
||||
output.Position.x *= -1; // otherwise cube map render will be horizontally flipped
|
||||
output.PositionWorld = mul(input.Position, Model);
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(VertexShaderOutput input) : SV_TARGET0
|
||||
{
|
||||
float lightDistance = length(input.PositionWorld - LightPosition);
|
||||
lightDistance /= FarPlane;
|
||||
return float4(lightDistance, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
Technique SimpleDepth
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float4x4 ViewProjection _vs(c4) _cb(c4);
|
||||
|
||||
float3 LightPosition _ps(c0) _cb(c8);
|
||||
float FarPlane _ps(c1) _cb(c9);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 PositionWorld : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexShaderOutput instanced_vs(VertexShaderInput input, float3 Translation : TEXCOORD2)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
float4x4 world = float4x4(
|
||||
float4(1, 0, 0, 0),
|
||||
float4(0, 1, 0, 0),
|
||||
float4(0, 0, 1, 0),
|
||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||
);
|
||||
|
||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
output.Position.x *= -1; // otherwise cube map render will be horizontally flipped
|
||||
output.PositionWorld = mul(input.Position, world);
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(VertexShaderOutput input) : SV_TARGET0
|
||||
{
|
||||
float lightDistance = length(input.PositionWorld - LightPosition);
|
||||
lightDistance /= FarPlane;
|
||||
return float4(lightDistance, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
Technique SimpleDepth
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 instanced_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -54,5 +54,4 @@
|
|||
#define SAMPLE_TEXTURE(Name, texCoord) tex2D(Name##Sampler, texCoord)
|
||||
#define SAMPLE_CUBEMAP(Name, texCoord) texCUBE(Name##Sampler, texCoord)
|
||||
#define SAMPLE_CUBEMAP_LOD(Name, texCoord) texCUBElod(Name##Sampler, texCoord)
|
||||
#define SAMPLER(Name) Name##Sampler
|
||||
#endif
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
DECLARE_TEXTURE(Texture, 0);
|
||||
DECLARE_TEXTURE(Palette, 1);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
int PaletteWidth _ps(c0) _cb(c0);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = input.Position;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
float4 sampled = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
||||
|
||||
float3 sampled_color = sampled.rgb;
|
||||
|
||||
float3 closest_color = float3(0, 0, 0);
|
||||
float closest_dist = 100000;
|
||||
|
||||
for (int i = 0; i < PaletteWidth; i++)
|
||||
{
|
||||
float texX = (i / (float)PaletteWidth);
|
||||
float3 palette_color = SAMPLE_TEXTURE(Palette, float2(texX, 0));
|
||||
float dist = distance(palette_color, sampled_color);
|
||||
if (dist < closest_dist)
|
||||
{
|
||||
closest_dist = dist;
|
||||
closest_color = palette_color;
|
||||
}
|
||||
}
|
||||
|
||||
return float4(closest_color, sampled.a);
|
||||
}
|
||||
|
||||
Technique PaletteCrush
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
static float2 poissonDisk[16] =
|
||||
{
|
||||
float2( -0.94201624, -0.39906216 ),
|
||||
float2( 0.94558609, -0.76890725 ),
|
||||
float2( -0.094184101, -0.92938870 ),
|
||||
float2( 0.34495938, 0.29387760 ),
|
||||
float2( -0.91588581, 0.45771432 ),
|
||||
float2( -0.81544232, -0.87912464 ),
|
||||
float2( -0.38277543, 0.27676845 ),
|
||||
float2( 0.97484398, 0.75648379 ),
|
||||
float2( 0.44323325, -0.97511554 ),
|
||||
float2( 0.53742981, -0.47373420 ),
|
||||
float2( -0.26496911, -0.41893023 ),
|
||||
float2( 0.79197514, 0.19090188 ),
|
||||
float2( -0.24188840, 0.99706507 ),
|
||||
float2( -0.81409955, 0.91437590 ),
|
||||
float2( 0.19984126, 0.78641367 ),
|
||||
float2( 0.14383161, -0.14100790 )
|
||||
};
|
||||
|
||||
// TODO: this should probably sample a noise texture instead
|
||||
// Returns a random number based on a vec3 and an int.
|
||||
float random(float3 seed, int i){
|
||||
float4 seed4 = float4(seed, i);
|
||||
float dot_product = dot(seed4, float4(12.9898,78.233,45.164,94.673));
|
||||
return frac(sin(dot_product) * 43758.5453);
|
||||
}
|
||||
|
||||
float PoissonCoord(sampler shadowMap, float3 worldPosition, float2 texCoord, float fragmentDepth, float bias)
|
||||
{
|
||||
float visibility = 1.0;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int index = int(16.0 * random(floor(worldPosition * 1000.0), i)) % 16;
|
||||
|
||||
if (tex2D(shadowMap, texCoord + poissonDisk[index] / 1024.0).r < fragmentDepth - bias)
|
||||
{
|
||||
visibility -= 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
float PoissonShadow(
|
||||
float3 positionWorldSpace,
|
||||
float3 N,
|
||||
float3 L,
|
||||
float4x4 lightSpaceMatrix,
|
||||
sampler shadowMap,
|
||||
int shadowMapSize
|
||||
) {
|
||||
float bias = 0.005 * tan(acos(dot(N, L)));
|
||||
bias = clamp(bias, 0, 0.01);
|
||||
|
||||
float4 positionLightSpace = mul(float4(positionWorldSpace, 1.0), lightSpaceMatrix);
|
||||
|
||||
// maps to [-1, 1]
|
||||
float3 projectionCoords = positionLightSpace.xyz / positionLightSpace.w;
|
||||
|
||||
// maps to [0, 1]
|
||||
// NOTE: In XNA, clip space z is [0, 1] range
|
||||
projectionCoords.x = (projectionCoords.x * 0.5) + 0.5;
|
||||
projectionCoords.y = (projectionCoords.y * 0.5) + 0.5;
|
||||
projectionCoords.y *= -1;
|
||||
|
||||
if (projectionCoords.z > 1.0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float inc = 1.0 / shadowMapSize;
|
||||
|
||||
// Poisson soft shadows
|
||||
float visibility = 0.0;
|
||||
|
||||
visibility = PoissonCoord(
|
||||
shadowMap,
|
||||
positionWorldSpace,
|
||||
projectionCoords.xy,
|
||||
projectionCoords.z,
|
||||
bias
|
||||
);
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
float HardShadow(
|
||||
float3 positionWorldSpace,
|
||||
float3 N,
|
||||
float3 L,
|
||||
float4x4 lightSpaceMatrix,
|
||||
sampler shadowMap,
|
||||
int shadowMapSize
|
||||
) {
|
||||
// float bias = 0.005 * tan(acos(dot(N, L)));
|
||||
// bias = clamp(bias, 0, 0.01);
|
||||
|
||||
float bias = max(0.05 * (1.0 - dot(N, L)), 0.005);
|
||||
|
||||
float4 positionLightSpace = mul(float4(positionWorldSpace, 1.0), lightSpaceMatrix);
|
||||
|
||||
// maps to [-1, 1]
|
||||
float3 projectionCoords = positionLightSpace.xyz / positionLightSpace.w;
|
||||
|
||||
// maps to [0, 1]
|
||||
// NOTE: In XNA, clip space z is [0, 1] range
|
||||
projectionCoords.x = (projectionCoords.x * 0.5) + 0.5;
|
||||
projectionCoords.y = (projectionCoords.y * 0.5) + 0.5;
|
||||
projectionCoords.y *= -1;
|
||||
|
||||
if (projectionCoords.z > 1.0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float closestDepth = tex2D(shadowMap, projectionCoords.xy);
|
||||
float currentDepth = projectionCoords.z;
|
||||
|
||||
return (currentDepth - bias > closestDepth ? 0.25 : 1.0);
|
||||
}
|
||||
|
||||
float HardPointShadow(
|
||||
float3 positionWorldSpace,
|
||||
float3 N,
|
||||
float3 L,
|
||||
float3 lightPosition,
|
||||
sampler shadowMap,
|
||||
float farPlane
|
||||
) {
|
||||
float3 lightToFrag = positionWorldSpace - lightPosition;
|
||||
float closestDepth = texCUBE(shadowMap, lightToFrag).r;
|
||||
closestDepth *= farPlane;
|
||||
|
||||
float currentDepth = length(lightToFrag);
|
||||
|
||||
float bias = max(0.05 * (1.0 - dot(N, L)), 0.005);
|
||||
|
||||
return (currentDepth - bias > closestDepth ? 0 : 1.0);
|
||||
}
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
MATRIX_CONSTANTS
|
||||
float4x4 ModelViewProjection _vs(c0) _cb(c0);
|
||||
float near _vs(c4) _cb(c4);
|
||||
float far _vs(c5) _cb(c5);
|
||||
|
||||
float4x4 World _vs(c0) _cb(c0);
|
||||
float4x4 ViewProjection _vs(c4) _cb(c4);
|
||||
MATRIX_CONSTANTS
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
|
@ -16,7 +17,7 @@ struct VertexShaderInput
|
|||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Position : SV_Position;
|
||||
float Depth : TEXCOORD0;
|
||||
};
|
||||
|
||||
|
@ -24,9 +25,10 @@ VertexShaderOutput main_vs(VertexShaderInput input)
|
|||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
output.Position = mul(input.Position, ModelViewProjection);
|
||||
|
||||
output.Depth = output.Position.z / output.Position.w;
|
||||
output.Depth = (output.Depth * 0.5) + 0.5;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
float4x4 ViewProjection;
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : POSITION0;
|
||||
float4 ProjectedPosition : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexShaderOutput instanced_vs(VertexShaderInput input, float3 Translation : TEXCOORD2)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
float4x4 world = float4x4(
|
||||
float4(1, 0, 0, 0),
|
||||
float4(0, 1, 0, 0),
|
||||
float4(0, 0, 1, 0),
|
||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||
);
|
||||
|
||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
output.ProjectedPosition = output.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(VertexShaderOutput input) : COLOR0
|
||||
{
|
||||
return float4(input.ProjectedPosition.z / input.ProjectedPosition.w, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
Technique SimpleDepth
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 instanced_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
DECLARE_CUBEMAP(skybox, 0);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float4x4 ViewProjection _vs(c0) _cb(c0);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
VertexShaderOutput main_vs(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
output.Position = mul(float4(input.Position, 1.0), ViewProjection);
|
||||
output.Position = output.Position.xyww;
|
||||
output.TexCoord = input.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(VertexShaderOutput input) : SV_TARGET0
|
||||
{
|
||||
return SAMPLE_CUBEMAP(skybox, input.TexCoord);
|
||||
}
|
||||
|
||||
Technique Skybox
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
sampler TextureSampler : register(s0);
|
||||
|
||||
float4 main_ps(float2 texCoord : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float3 color = tex2D(TextureSampler, texCoord).xyz;
|
||||
|
||||
color = color / (color + float3(1.0, 1.0, 1.0));
|
||||
float exposureConstant = 1.0 / 2.2;
|
||||
color = pow(color, float3(exposureConstant, exposureConstant, exposureConstant));
|
||||
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
|
||||
Technique DeferredPBR
|
||||
{
|
||||
Pass
|
||||
{
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class LinearDepthEffect : Effect, IHasWorldMatrix
|
||||
{
|
||||
EffectParameter worldParam;
|
||||
EffectParameter worldViewProjectionParam;
|
||||
EffectParameter lightPositionParam;
|
||||
EffectParameter farPlaneParam;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
Matrix world;
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
|
||||
public Vector3 LightPosition { get; set; }
|
||||
public float FarPlane { get; set; }
|
||||
|
||||
public Matrix World
|
||||
{
|
||||
get { return world; }
|
||||
set
|
||||
{
|
||||
world = value;
|
||||
dirtyFlags |= EffectDirtyFlags.World;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public LinearDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.LinearDepthEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
Matrix.Multiply(ref world, ref viewProjection, out Matrix worldViewProj);
|
||||
|
||||
worldViewProjectionParam.SetValue(worldViewProj);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||
{
|
||||
worldParam.SetValue(world);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||
}
|
||||
|
||||
lightPositionParam.SetValue(LightPosition);
|
||||
farPlaneParam.SetValue(FarPlane);
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
worldParam = Parameters["Model"];
|
||||
worldViewProjectionParam = Parameters["ModelViewProjection"];
|
||||
|
||||
lightPositionParam = Parameters["LightPosition"];
|
||||
farPlaneParam = Parameters["FarPlane"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class LinearDepthEffectInstanced : Effect
|
||||
{
|
||||
EffectParameter viewProjectionParam;
|
||||
EffectParameter lightPositionParam;
|
||||
EffectParameter farPlaneParam;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
|
||||
public Vector3 LightPosition { get; set; }
|
||||
public float FarPlane { get; set; }
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public LinearDepthEffectInstanced(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.LinearDepthEffectInstanced)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
viewProjectionParam.SetValue(viewProjection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
|
||||
lightPositionParam.SetValue(LightPosition);
|
||||
farPlaneParam.SetValue(FarPlane);
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
|
||||
lightPositionParam = Parameters["LightPosition"];
|
||||
farPlaneParam = Parameters["FarPlane"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
|
|||
|
||||
namespace Kav
|
||||
{
|
||||
public class PBREffect : Effect, TransformEffect, PointLightEffect
|
||||
public class PBREffect : Effect, TransformEffect, PointLightEffect, DirectionalLightEffect
|
||||
{
|
||||
EffectParameter worldParam;
|
||||
EffectParameter worldViewProjectionParam;
|
||||
|
@ -31,6 +31,7 @@ namespace Kav
|
|||
Matrix view = Matrix.Identity;
|
||||
Matrix projection = Matrix.Identity;
|
||||
PointLightCollection pointLightCollection;
|
||||
DirectionalLightCollection directionalLightCollection;
|
||||
|
||||
Vector3 albedo;
|
||||
float metallic;
|
||||
|
@ -83,6 +84,14 @@ namespace Kav
|
|||
private set { pointLightCollection = value; }
|
||||
}
|
||||
|
||||
public int MaxDirectionalLights { get; } = 4;
|
||||
|
||||
public DirectionalLightCollection DirectionalLights
|
||||
{
|
||||
get { return directionalLightCollection; }
|
||||
private set { directionalLightCollection = value; }
|
||||
}
|
||||
|
||||
public Vector3 Albedo
|
||||
{
|
||||
get { return albedo; }
|
||||
|
@ -130,7 +139,7 @@ namespace Kav
|
|||
{
|
||||
albedoTextureParam.SetValue(value);
|
||||
albedoTextureEnabled = value != null;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +150,7 @@ namespace Kav
|
|||
{
|
||||
normalTextureParam.SetValue(value);
|
||||
normalMapEnabled = value != null;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +173,7 @@ namespace Kav
|
|||
{
|
||||
metallicRoughnessTextureParam.SetValue(value);
|
||||
metallicRoughnessMapEnabled = value != null;
|
||||
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +204,62 @@ namespace Kav
|
|||
Parameters["PositionLightColors"],
|
||||
MaxPointLights
|
||||
);
|
||||
|
||||
directionalLightCollection = new DirectionalLightCollection(
|
||||
Parameters["LightDirections"],
|
||||
Parameters["DirectionLightColors"],
|
||||
Parameters["DirectionalLightMatrices"]
|
||||
);
|
||||
}
|
||||
|
||||
protected PBREffect(PBREffect cloneSource) : base(cloneSource)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
|
||||
World = cloneSource.World;
|
||||
View = cloneSource.View;
|
||||
Projection = cloneSource.Projection;
|
||||
|
||||
PointLights = new PointLightCollection(
|
||||
Parameters["LightPositions"],
|
||||
Parameters["PositionLightColors"],
|
||||
MaxPointLights
|
||||
);
|
||||
|
||||
for (int i = 0; i < MaxPointLights; i++)
|
||||
{
|
||||
PointLights[i] = cloneSource.PointLights[i];
|
||||
}
|
||||
|
||||
DirectionalLights = new DirectionalLightCollection(
|
||||
Parameters["LightDirections"],
|
||||
Parameters["DirectionLightColors"],
|
||||
Parameters["DirectionalLightMatrices"]
|
||||
);
|
||||
|
||||
for (int i = 0; i < MaxDirectionalLights; i++)
|
||||
{
|
||||
DirectionalLights[i] = cloneSource.DirectionalLights[i];
|
||||
}
|
||||
|
||||
AlbedoTexture = cloneSource.AlbedoTexture;
|
||||
NormalTexture = cloneSource.NormalTexture;
|
||||
EmissionTexture = cloneSource.EmissionTexture;
|
||||
OcclusionTexture = cloneSource.OcclusionTexture;
|
||||
MetallicRoughnessTexture = cloneSource.MetallicRoughnessTexture;
|
||||
EnvDiffuseTexture = cloneSource.EnvDiffuseTexture;
|
||||
BRDFLutTexture = cloneSource.BRDFLutTexture;
|
||||
EnvSpecularTexture = cloneSource.EnvSpecularTexture;
|
||||
|
||||
Albedo = cloneSource.Albedo;
|
||||
Metallic = cloneSource.Metallic;
|
||||
Roughness = cloneSource.Roughness;
|
||||
AO = cloneSource.AO;
|
||||
}
|
||||
|
||||
public override Effect Clone()
|
||||
{
|
||||
return new PBREffect(this);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
|
@ -227,7 +292,7 @@ namespace Kav
|
|||
dirtyFlags &= ~EffectDirtyFlags.EyePosition;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
|
||||
{
|
||||
int shaderIndex = 0;
|
||||
|
||||
|
@ -262,7 +327,7 @@ namespace Kav
|
|||
|
||||
shaderIndexParam.SetValue(shaderIndex);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
|
||||
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class PaletteCrushEffect : Effect
|
||||
{
|
||||
EffectParameter textureParam;
|
||||
EffectParameter paletteParam;
|
||||
EffectParameter paletteWidthParam;
|
||||
|
||||
Texture2D texture;
|
||||
Texture2D palette;
|
||||
|
||||
int paletteWidth;
|
||||
|
||||
public Texture2D Texture
|
||||
{
|
||||
get { return texture; }
|
||||
set
|
||||
{
|
||||
texture = value;
|
||||
textureParam.SetValue(texture);
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2D Palette
|
||||
{
|
||||
get { return palette; }
|
||||
set
|
||||
{
|
||||
palette = value;
|
||||
paletteWidth = palette.Width;
|
||||
paletteParam.SetValue(palette);
|
||||
paletteWidthParam.SetValue(paletteWidth);
|
||||
}
|
||||
}
|
||||
|
||||
public PaletteCrushEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.PaletteCrushEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
textureParam = Parameters["Texture"];
|
||||
paletteParam = Parameters["Palette"];
|
||||
|
||||
paletteWidthParam = Parameters["PaletteWidth"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,24 +7,41 @@ namespace Kav
|
|||
{
|
||||
private readonly Vector3[] positions;
|
||||
private readonly Vector3[] colors;
|
||||
private readonly float[] intensities;
|
||||
|
||||
readonly EffectParameter lightPositionsParam;
|
||||
readonly EffectParameter lightColorsParam;
|
||||
|
||||
public PointLightCollection(EffectParameter lightPositionsParam, EffectParameter lightColorsParam, int maxLights)
|
||||
{
|
||||
positions = new Vector3[maxLights];
|
||||
colors = new Vector3[maxLights];
|
||||
this.positions = new Vector3[maxLights];
|
||||
this.colors = new Vector3[maxLights];
|
||||
this.intensities = new float[maxLights];
|
||||
this.lightPositionsParam = lightPositionsParam;
|
||||
this.lightColorsParam = lightColorsParam;
|
||||
}
|
||||
|
||||
public PointLight this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
var color = colors[i] / intensities[i];
|
||||
return new PointLight(
|
||||
positions[i],
|
||||
new Color(
|
||||
color.X,
|
||||
color.Y,
|
||||
color.Z,
|
||||
1f
|
||||
),
|
||||
intensities[i]
|
||||
);
|
||||
}
|
||||
set
|
||||
{
|
||||
positions[i] = value.Position;
|
||||
colors[i] = value.Color.ToVector3() * value.Radius;
|
||||
colors[i] = value.Color.ToVector3() * value.Intensity;
|
||||
intensities[i] = value.Intensity;
|
||||
lightPositionsParam.SetValue(positions);
|
||||
lightColorsParam.SetValue(colors);
|
||||
}
|
||||
|
|
|
@ -3,24 +3,25 @@ using Microsoft.Xna.Framework.Graphics;
|
|||
|
||||
namespace Kav
|
||||
{
|
||||
public class SimpleDepthEffect : Effect, IHasWorldMatrix
|
||||
public class SimpleDepthEffect : Effect
|
||||
{
|
||||
EffectParameter worldParam;
|
||||
EffectParameter viewProjectionParam;
|
||||
EffectParameter modelViewProjectionParam;
|
||||
EffectParameter nearParam;
|
||||
EffectParameter farParam;
|
||||
|
||||
Matrix world;
|
||||
Matrix model;
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
public Matrix World
|
||||
public Matrix Model
|
||||
{
|
||||
get { return world; }
|
||||
get { return model; }
|
||||
set
|
||||
{
|
||||
world = value;
|
||||
dirtyFlags |= EffectDirtyFlags.World;
|
||||
model = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +31,7 @@ namespace Kav
|
|||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,10 +41,13 @@ namespace Kav
|
|||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public float Near { get; set; }
|
||||
public float Far { get; set; }
|
||||
|
||||
public SimpleDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
|
@ -51,26 +55,25 @@ namespace Kav
|
|||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||
{
|
||||
worldParam.SetValue(world);
|
||||
Matrix.Multiply(ref model, ref view, out Matrix modelView);
|
||||
Matrix.Multiply(ref modelView, ref projection, out Matrix worldViewProj);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||
modelViewProjectionParam.SetValue(worldViewProj);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
viewProjectionParam.SetValue(viewProjection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
nearParam.SetValue(Near);
|
||||
farParam.SetValue(Far);
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
worldParam = Parameters["World"];
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
modelViewProjectionParam = Parameters["ModelViewProjection"];
|
||||
nearParam = Parameters["near"];
|
||||
farParam = Parameters["far"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class SimpleDepthEffectInstanced : Effect
|
||||
{
|
||||
EffectParameter viewProjectionParam;
|
||||
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleDepthEffectInstanced(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffectInstanced)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
viewProjectionParam.SetValue(viewProjection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class SkyboxEffect : Effect
|
||||
{
|
||||
EffectParameter viewProjectionParam;
|
||||
EffectParameter skyboxParam;
|
||||
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
TextureCube skybox;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public TextureCube Skybox
|
||||
{
|
||||
get { return skybox; }
|
||||
set
|
||||
{
|
||||
skybox = value;
|
||||
dirtyFlags |= EffectDirtyFlags.World; // hack flag but whatever
|
||||
}
|
||||
}
|
||||
|
||||
public SkyboxEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SkyboxEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
|
||||
viewProjectionParam.SetValue(viewProjection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||
{
|
||||
skyboxParam.SetValue(skybox);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
skyboxParam = Parameters["skybox"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
namespace Kav
|
||||
{
|
||||
public enum SpriteBillboardConstraint
|
||||
{
|
||||
None,
|
||||
Horizontal,
|
||||
Full
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface ICullable
|
||||
{
|
||||
BoundingBox BoundingBox { get; }
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface IGBufferDrawable
|
||||
{
|
||||
Vector3 Albedo { get; }
|
||||
float Metallic { get; }
|
||||
float Roughness { get; }
|
||||
|
||||
Texture2D AlbedoTexture { get; }
|
||||
Texture2D NormalTexture { get; }
|
||||
Texture2D MetallicRoughnessTexture { get; }
|
||||
|
||||
int NumTextureRows { get; }
|
||||
int NumTextureColumns { get; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface IHasVertexPositions
|
||||
{
|
||||
Vector3[] Positions { get; }
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface IIndexDrawable
|
||||
{
|
||||
VertexBuffer VertexBuffer { get; }
|
||||
IndexBuffer IndexBuffer { get; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public interface ITransformable
|
||||
{
|
||||
Matrix TransformMatrix { get; }
|
||||
}
|
||||
}
|
|
@ -1,23 +1,12 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class Mesh
|
||||
{
|
||||
public MeshPart[] MeshParts { get; }
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
public Mesh(MeshPart[] meshParts)
|
||||
{
|
||||
MeshParts = meshParts;
|
||||
|
||||
BoundingBox boundingBox = new BoundingBox();
|
||||
foreach (var meshPart in MeshParts)
|
||||
{
|
||||
boundingBox = BoundingBox.CreateMerged(boundingBox, meshPart.BoundingBox);
|
||||
}
|
||||
|
||||
BoundingBox = boundingBox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,60 +3,21 @@ using Microsoft.Xna.Framework.Graphics;
|
|||
|
||||
namespace Kav
|
||||
{
|
||||
public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable, IHasVertexPositions
|
||||
public class MeshPart
|
||||
{
|
||||
public IndexBuffer IndexBuffer { get; }
|
||||
public VertexBuffer VertexBuffer { get; }
|
||||
public Triangle[] Triangles { get; }
|
||||
public Vector3[] Positions { get; }
|
||||
public Effect Effect { get; }
|
||||
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
private Texture2D albedoTexture = null;
|
||||
private Texture2D normalTexture = null;
|
||||
private Texture2D metallicRoughnessTexture = null;
|
||||
|
||||
public Texture2D AlbedoTexture
|
||||
public MeshPart(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, Vector3[] positions, Triangle[] triangles, Effect effect)
|
||||
{
|
||||
get { return DisableAlbedoMap ? null : albedoTexture; }
|
||||
set { albedoTexture = value; }
|
||||
}
|
||||
|
||||
public Texture2D NormalTexture
|
||||
{
|
||||
get { return DisableNormalMap ? null : normalTexture; }
|
||||
set { normalTexture = value; }
|
||||
}
|
||||
|
||||
public Texture2D MetallicRoughnessTexture
|
||||
{
|
||||
get { return DisableMetallicRoughnessMap ? null : metallicRoughnessTexture; }
|
||||
set { metallicRoughnessTexture = value; }
|
||||
}
|
||||
|
||||
public Vector3 Albedo { get; set; } = Vector3.One;
|
||||
public float Metallic { get; set; } = 0.5f;
|
||||
public float Roughness { get; set; } = 0.5f;
|
||||
|
||||
public int NumTextureRows { get; set; } = 1;
|
||||
public int NumTextureColumns { get; set; } = 1;
|
||||
|
||||
public bool DisableAlbedoMap { get; set; } = false;
|
||||
public bool DisableNormalMap { get; set; } = false;
|
||||
public bool DisableMetallicRoughnessMap { get; set; } = false;
|
||||
|
||||
public MeshPart(
|
||||
VertexBuffer vertexBuffer,
|
||||
IndexBuffer indexBuffer,
|
||||
Vector3[] positions,
|
||||
Triangle[] triangles
|
||||
) {
|
||||
VertexBuffer = vertexBuffer;
|
||||
IndexBuffer = indexBuffer;
|
||||
Positions = positions;
|
||||
Triangles = triangles;
|
||||
|
||||
BoundingBox = BoundingBox.CreateFromPoints(Positions);
|
||||
Effect = effect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,97 +2,13 @@ using Microsoft.Xna.Framework;
|
|||
|
||||
namespace Kav
|
||||
{
|
||||
public class Model : ICullable
|
||||
public class Model
|
||||
{
|
||||
public Mesh[] Meshes { get; }
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
public Color Albedo
|
||||
{
|
||||
set
|
||||
{
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
meshPart.Albedo = value.ToVector3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float Metallic
|
||||
{
|
||||
set
|
||||
{
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
meshPart.Metallic = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float Roughness
|
||||
{
|
||||
set
|
||||
{
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
meshPart.Roughness = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Model(Mesh[] meshes)
|
||||
{
|
||||
Meshes = meshes;
|
||||
|
||||
BoundingBox boundingBox = new BoundingBox();
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
boundingBox = BoundingBox.CreateMerged(boundingBox, mesh.BoundingBox);
|
||||
}
|
||||
|
||||
BoundingBox = boundingBox;
|
||||
}
|
||||
|
||||
public void DisableAlbedoMaps()
|
||||
{
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
meshPart.DisableAlbedoMap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableNormalMaps()
|
||||
{
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
meshPart.DisableNormalMap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableMetallicRoughnessMaps()
|
||||
{
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
meshPart.DisableMetallicRoughnessMap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public struct Sprite
|
||||
{
|
||||
public Texture2D Texture { get; }
|
||||
public Vector3 Position { get; }
|
||||
public Vector2 Origin { get; }
|
||||
public float Rotation { get; }
|
||||
public Vector2 Scale { get; }
|
||||
public SpriteBillboardConstraint BillboardConstraint { get; }
|
||||
|
||||
public Matrix TransformMatrix { get; }
|
||||
|
||||
public Sprite(
|
||||
Texture2D texture,
|
||||
Vector3 position,
|
||||
Vector2 origin,
|
||||
float rotation,
|
||||
Vector2 scale,
|
||||
SpriteBillboardConstraint billboardConstraint = SpriteBillboardConstraint.None
|
||||
) {
|
||||
Texture = texture;
|
||||
Position = position;
|
||||
Origin = origin;
|
||||
Rotation = rotation;
|
||||
Scale = scale;
|
||||
BillboardConstraint = billboardConstraint;
|
||||
TransformMatrix = ConstructTransformMatrix(Position, Scale);
|
||||
}
|
||||
|
||||
public Sprite(
|
||||
Texture2D texture,
|
||||
Vector3 position,
|
||||
SpriteBillboardConstraint billboardConstraint = SpriteBillboardConstraint.None
|
||||
) {
|
||||
Texture = texture;
|
||||
Position = position;
|
||||
Origin = Vector2.Zero;
|
||||
Rotation = 0;
|
||||
Scale = Vector2.One;
|
||||
BillboardConstraint = billboardConstraint;
|
||||
TransformMatrix = ConstructTransformMatrix(Position, Scale);
|
||||
}
|
||||
|
||||
private static Matrix ConstructTransformMatrix(
|
||||
Vector3 position,
|
||||
Vector2 scale
|
||||
) {
|
||||
return
|
||||
Matrix.CreateTranslation(position) *
|
||||
Matrix.CreateScale(scale.X, scale.Y, 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class SpriteMesh : ICullable, IIndexDrawable
|
||||
{
|
||||
public enum FlipOptions
|
||||
{
|
||||
None,
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Both
|
||||
}
|
||||
|
||||
private static readonly short[] Indices = new short[]
|
||||
{
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
3,
|
||||
2
|
||||
};
|
||||
|
||||
public IndexBuffer IndexBuffer { get; }
|
||||
public VertexBuffer VertexBuffer { get; }
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
public SpriteMesh(
|
||||
GraphicsDevice graphicsDevice,
|
||||
int width,
|
||||
int height,
|
||||
FlipOptions flipOptions
|
||||
) {
|
||||
IndexBuffer = new IndexBuffer(
|
||||
graphicsDevice,
|
||||
IndexElementSize.SixteenBits,
|
||||
6,
|
||||
BufferUsage.WriteOnly
|
||||
);
|
||||
IndexBuffer.SetData(Indices);
|
||||
|
||||
var vertexArray = GenerateVertexArray(width, height, flipOptions);
|
||||
|
||||
VertexBuffer = new VertexBuffer(
|
||||
graphicsDevice,
|
||||
typeof(VertexPositionNormalTexture),
|
||||
4,
|
||||
BufferUsage.WriteOnly
|
||||
);
|
||||
VertexBuffer.SetData(vertexArray);
|
||||
|
||||
BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray));
|
||||
}
|
||||
|
||||
private static VertexPositionNormalTexture[] GenerateVertexArray(int pixelWidth, int pixelHeight, FlipOptions flipOptions)
|
||||
{
|
||||
var width = pixelWidth / (float)40;
|
||||
var height = pixelHeight / (float)40;
|
||||
|
||||
VertexPositionNormalTexture[] result = new VertexPositionNormalTexture[4];
|
||||
|
||||
var xLeft = 0;
|
||||
var xRight = 1;
|
||||
|
||||
var yTop = 0;
|
||||
var yBottom = 1;
|
||||
|
||||
if (flipOptions == FlipOptions.Horizontal || flipOptions == FlipOptions.Both)
|
||||
{
|
||||
xLeft = 1;
|
||||
xRight = 0;
|
||||
}
|
||||
if (flipOptions == FlipOptions.Vertical || flipOptions == FlipOptions.Both)
|
||||
{
|
||||
yTop = 1;
|
||||
yBottom = 0;
|
||||
}
|
||||
|
||||
result[0].Position = new Vector3(-width / 2, height / 2, 0);
|
||||
result[0].Normal = new Vector3(0, 0, -1);
|
||||
result[0].TextureCoordinate = new Vector2(xLeft, yTop);
|
||||
|
||||
result[1].Position = new Vector3(width / 2, height / 2, 0);
|
||||
result[1].Normal = new Vector3(0, 0, -1);
|
||||
result[1].TextureCoordinate = new Vector2(xRight, yTop);
|
||||
|
||||
result[2].Position = new Vector3(-width / 2, -height / 2, 0);
|
||||
result[2].Normal = new Vector3(0, 0, -1);
|
||||
result[2].TextureCoordinate = new Vector2(xLeft, yBottom);
|
||||
|
||||
result[3].Position = new Vector3(width / 2, -height / 2, 0);
|
||||
result[3].Normal = new Vector3(0, 0, -1);
|
||||
result[3].TextureCoordinate = new Vector2(xRight, yBottom);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<Vector3> Positions(IEnumerable<VertexPositionNormalTexture> vertices)
|
||||
{
|
||||
foreach (var vertex in vertices)
|
||||
{
|
||||
yield return vertex.Position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,13 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<RootNamespace>Kav</RootNamespace>
|
||||
<Authors>Evan Hemsley</Authors>
|
||||
<Copyright>Evan Hemsley 2020</Copyright>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<AssemblyName>Kav</AssemblyName>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -17,24 +15,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_AmbientLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_AmbientLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_PointLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_PointLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_DirectionalLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
||||
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\Deferred_ToonEffect.fxb">
|
||||
<LogicalName>Kav.Resources.Deferred_ToonEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBREffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBREffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
|
@ -44,30 +27,6 @@
|
|||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffectInstanced.fxb">
|
||||
<LogicalName>Kav.Resources.SimpleDepthEffectInstanced.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffectInstanced.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffectInstanced.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DiffuseLitSpriteEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DiffuseLitSpriteEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\PaletteCrushEffect.fxb">
|
||||
<LogicalName>Kav.Resources.PaletteCrushEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Models\UnitSphere.glb">
|
||||
<LogicalName>Kav.Resources.UnitSphere.glb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
22
Kav.Core.sln
22
Kav.Core.sln
|
@ -1,22 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26124.0
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav", "Kav.Core.csproj", "{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.Build.0 = Debug|x64
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.ActiveCfg = Release|x64
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,14 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<RootNamespace>Kav</RootNamespace>
|
||||
<Authors>Evan Hemsley</Authors>
|
||||
<Copyright>Evan Hemsley 2020</Copyright>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<AssemblyName>Kav</AssemblyName>
|
||||
<Platforms>x64;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -17,24 +15,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_AmbientLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_AmbientLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_PointLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_PointLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_DirectionalLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
||||
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\Deferred_ToonEffect.fxb">
|
||||
<LogicalName>Kav.Resources.Deferred_ToonEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBREffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBREffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
|
@ -44,30 +27,6 @@
|
|||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffectInstanced.fxb">
|
||||
<LogicalName>Kav.Resources.SimpleDepthEffectInstanced.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffectInstanced.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffectInstanced.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DiffuseLitSpriteEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DiffuseLitSpriteEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\PaletteCrushEffect.fxb">
|
||||
<LogicalName>Kav.Resources.PaletteCrushEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Models\UnitSphere.glb">
|
||||
<LogicalName>Kav.Resources.UnitSphere.glb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26124.0
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav.Framework", "Kav.Framework.csproj", "{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26124.0
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav", "Kav.csproj", "{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,14 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public struct AmbientLight
|
||||
{
|
||||
public Color Color { get; set; }
|
||||
|
||||
public AmbientLight(Color color)
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,15 +4,15 @@ namespace Kav
|
|||
{
|
||||
public struct DirectionalLight
|
||||
{
|
||||
public Vector3 Direction { get; }
|
||||
public Color Color { get; }
|
||||
public float Intensity { get; }
|
||||
public Vector3 Direction { get; set; }
|
||||
public Color Color { get; set; }
|
||||
public float Intensity { get; set; }
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get
|
||||
{
|
||||
return Matrix.CreateLookAt(Direction * 100f, Vector3.Zero, Vector3.Up);
|
||||
return Matrix.CreateLookAt(Direction * 4.5f, Vector3.Zero, Vector3.Up);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace Kav
|
|||
{
|
||||
get
|
||||
{
|
||||
return Matrix.CreateOrthographic(20f, 20f, 1f, 101f);
|
||||
return Matrix.CreateOrthographic(20f, 20f, 1f, 7.5f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,55 +1,18 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public sealed class PointLight : IDisposable
|
||||
public struct PointLight
|
||||
{
|
||||
public Vector3 Position { get; }
|
||||
public Color Color { get; }
|
||||
public float Radius { get; }
|
||||
public float Intensity { get; }
|
||||
|
||||
public BoundingSphere BoundingSphere { get; }
|
||||
|
||||
public RenderTargetCube ShadowMap { get; }
|
||||
|
||||
public PointLight(
|
||||
GraphicsDevice graphicsDevice,
|
||||
Vector3 position,
|
||||
Color color,
|
||||
float radius,
|
||||
int shadowMapSize
|
||||
) {
|
||||
public PointLight(Vector3 position, Color color, float intensity = 1f)
|
||||
{
|
||||
Position = position;
|
||||
Color = color;
|
||||
Radius = radius;
|
||||
|
||||
BoundingSphere = new BoundingSphere(position, Radius);
|
||||
|
||||
ShadowMap = new RenderTargetCube(
|
||||
graphicsDevice,
|
||||
shadowMapSize,
|
||||
false,
|
||||
SurfaceFormat.Single,
|
||||
DepthFormat.Depth24,
|
||||
0,
|
||||
RenderTargetUsage.PreserveContents
|
||||
);
|
||||
|
||||
var currentRTs = graphicsDevice.GetRenderTargets();
|
||||
foreach (CubeMapFace face in Enum.GetValues(typeof(CubeMapFace)))
|
||||
{
|
||||
graphicsDevice.SetRenderTarget(ShadowMap, face);
|
||||
graphicsDevice.Clear(Color.White);
|
||||
}
|
||||
|
||||
graphicsDevice.SetRenderTargets(currentRTs);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ShadowMap.Dispose();
|
||||
Intensity = intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public static class CrunchAtlasReader
|
||||
{
|
||||
static JsonSerializerOptions options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
public static CrunchTextureAtlasData ReadTextureAtlas(FileInfo file)
|
||||
{
|
||||
return JsonSerializer.Deserialize<CrunchTextureAtlasData>(File.ReadAllText(file.FullName), options);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
namespace Kav
|
||||
{
|
||||
public struct CrunchTextureAtlasData
|
||||
{
|
||||
public CrunchTextureAtlasTextureData[] Textures { get; set; }
|
||||
}
|
||||
|
||||
public struct CrunchTextureAtlasTextureData
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public CrunchTextureAtlasImageData[] Images { get; set; }
|
||||
}
|
||||
|
||||
public struct CrunchTextureAtlasImageData
|
||||
{
|
||||
public string N { get; set; }
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int W { get; set; }
|
||||
public int H { get; set; }
|
||||
}
|
||||
}
|
|
@ -15,6 +15,19 @@ namespace Kav
|
|||
|
||||
foreach (var meshPartData in meshData.MeshParts)
|
||||
{
|
||||
var effect = new Kav.DeferredPBR_GBufferEffect(
|
||||
graphicsDevice
|
||||
)
|
||||
{
|
||||
Albedo = meshPartData.Albedo,
|
||||
Metallic = meshPartData.Metallic,
|
||||
Roughness = meshPartData.Roughness,
|
||||
|
||||
AlbedoTexture = meshPartData.AlbedoTexture,
|
||||
NormalTexture = meshPartData.NormalTexture,
|
||||
MetallicRoughnessTexture = meshPartData.MetallicRoughnessTexture
|
||||
};
|
||||
|
||||
var triangles = new Kav.Triangle[meshPartData.Triangles.Length];
|
||||
for (int i = 0; i < meshPartData.Triangles.Length; i++)
|
||||
{
|
||||
|
@ -27,22 +40,13 @@ namespace Kav
|
|||
);
|
||||
}
|
||||
|
||||
var meshPart = new Kav.MeshPart(
|
||||
meshParts.Add(new Kav.MeshPart(
|
||||
meshPartData.VertexBuffer,
|
||||
meshPartData.IndexBuffer,
|
||||
meshPartData.Positions,
|
||||
triangles
|
||||
);
|
||||
|
||||
meshPart.Albedo = meshPartData.Albedo;
|
||||
meshPart.Metallic = meshPartData.Metallic;
|
||||
meshPart.Roughness = meshPartData.Roughness;
|
||||
|
||||
meshPart.AlbedoTexture = meshPartData.AlbedoTexture;
|
||||
meshPart.NormalTexture = meshPartData.NormalTexture;
|
||||
meshPart.MetallicRoughnessTexture = meshPartData.MetallicRoughnessTexture;
|
||||
|
||||
meshParts.Add(meshPart);
|
||||
triangles,
|
||||
effect
|
||||
));
|
||||
}
|
||||
|
||||
meshes.Add(new Kav.Mesh(meshParts.ToArray()));
|
||||
|
|
Binary file not shown.
Binary file not shown.
29
README.md
29
README.md
|
@ -1,29 +0,0 @@
|
|||
# Kav
|
||||
|
||||
A 3D renderer built on top of FNA.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Essential
|
||||
|
||||
- [x] PBR shading
|
||||
- [x] Deferred rendering
|
||||
- [x] Point lighting
|
||||
- [x] Directional lighting
|
||||
- [x] Directional shadow maps
|
||||
- [x] Cascading shadow maps
|
||||
- [x] Tone map shader
|
||||
- [x] Poisson soft shadowing
|
||||
- [x] Frustum culling
|
||||
- [x] Shadow-casting point lights
|
||||
- [ ] Parabolic lights
|
||||
- [x] Skyboxes
|
||||
- [ ] Screen-space reflection
|
||||
|
||||
Nice-To-Haves
|
||||
|
||||
- [ ] Anti-aliasing
|
||||
- [ ] Image-based lighting
|
||||
- [ ] Volumetric lighting
|
||||
- [ ] Volumetric smoke
|
||||
- [ ]
|
1245
Renderer.cs
1245
Renderer.cs
File diff suppressed because it is too large
Load Diff
179
Resources.cs
179
Resources.cs
|
@ -4,84 +4,25 @@ namespace Kav
|
|||
{
|
||||
internal class Resources
|
||||
{
|
||||
public static byte[] DeferredPBR_AmbientLightEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ambientLightEffect == null)
|
||||
{
|
||||
ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect.fxb");
|
||||
}
|
||||
return ambientLightEffect;
|
||||
}
|
||||
}
|
||||
public static byte[] DeferredPBR_PointLightEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (pointLightEffect == null)
|
||||
{
|
||||
pointLightEffect = GetResource("DeferredPBR_PointLightEffect.fxb");
|
||||
}
|
||||
return pointLightEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] DeferredPBR_DirectionalLightEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (directionalLightEffect == null)
|
||||
{
|
||||
directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect.fxb");
|
||||
}
|
||||
return directionalLightEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] DeferredPBR_GBufferEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (gBufferEffect == null)
|
||||
{
|
||||
gBufferEffect = GetResource("DeferredPBR_GBufferEffect.fxb");
|
||||
gBufferEffect = GetResource("DeferredPBR_GBufferEffect");
|
||||
}
|
||||
return gBufferEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ToneMapEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (toneMapEffect == null)
|
||||
{
|
||||
toneMapEffect = GetResource("ToneMapEffect.fxb");
|
||||
}
|
||||
return toneMapEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] Deferred_ToonEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (deferredToonEffect == null)
|
||||
{
|
||||
deferredToonEffect = GetResource("Deferred_ToonEffect.fxb");
|
||||
}
|
||||
return deferredToonEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] DeferredPBREffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (deferredPBREffect == null)
|
||||
{
|
||||
deferredPBREffect = GetResource("DeferredPBREffect.fxb");
|
||||
deferredPBREffect = GetResource("DeferredPBREffect");
|
||||
}
|
||||
return deferredPBREffect;
|
||||
}
|
||||
|
@ -93,7 +34,7 @@ namespace Kav
|
|||
{
|
||||
if (pbrEffect == null)
|
||||
{
|
||||
pbrEffect = GetResource("PBREffect.fxb");
|
||||
pbrEffect = GetResource("PBREffect");
|
||||
}
|
||||
return pbrEffect;
|
||||
}
|
||||
|
@ -105,131 +46,21 @@ namespace Kav
|
|||
{
|
||||
if (simpleDepthEffect == null)
|
||||
{
|
||||
simpleDepthEffect = GetResource("SimpleDepthEffect.fxb");
|
||||
simpleDepthEffect = GetResource("SimpleDepthEffect");
|
||||
}
|
||||
return simpleDepthEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] SimpleDepthEffectInstanced
|
||||
{
|
||||
get
|
||||
{
|
||||
if (simpleDepthEffectInstanced == null)
|
||||
{
|
||||
simpleDepthEffectInstanced = GetResource("SimpleDepthEffectInstanced.fxb");
|
||||
}
|
||||
return simpleDepthEffectInstanced;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] LinearDepthEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (linearDepthEffect == null)
|
||||
{
|
||||
linearDepthEffect = GetResource("LinearDepthEffect.fxb");
|
||||
}
|
||||
return linearDepthEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] LinearDepthEffectInstanced
|
||||
{
|
||||
get
|
||||
{
|
||||
if (linearDepthEffectInstanced == null)
|
||||
{
|
||||
linearDepthEffectInstanced = GetResource("LinearDepthEffectInstanced.fxb");
|
||||
}
|
||||
return linearDepthEffectInstanced;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] SkyboxEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skyboxEffect == null)
|
||||
{
|
||||
skyboxEffect = GetResource("SkyboxEffect.fxb");
|
||||
}
|
||||
return skyboxEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] DiffuseLitSpriteEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (diffuseLitSpriteEffect == null)
|
||||
{
|
||||
diffuseLitSpriteEffect = GetResource("DiffuseLitSpriteEffect.fxb");
|
||||
}
|
||||
return diffuseLitSpriteEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] PaletteCrushEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (paletteCrushEffect == null)
|
||||
{
|
||||
paletteCrushEffect = GetResource("PaletteCrushEffect.fxb");
|
||||
}
|
||||
return paletteCrushEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] UnitCubeModel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (unitCubeModel == null)
|
||||
{
|
||||
unitCubeModel = GetResource("UnitCube.glb");
|
||||
}
|
||||
return unitCubeModel;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] UnitSphereModel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (unitSphereModel == null)
|
||||
{
|
||||
unitSphereModel = GetResource("UnitSphere.glb");
|
||||
}
|
||||
return unitSphereModel;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] ambientLightEffect;
|
||||
private static byte[] pointLightEffect;
|
||||
private static byte[] directionalLightEffect;
|
||||
private static byte[] gBufferEffect;
|
||||
private static byte[] toneMapEffect;
|
||||
private static byte[] deferredToonEffect;
|
||||
private static byte[] deferredPBREffect;
|
||||
private static byte[] pbrEffect;
|
||||
private static byte[] simpleDepthEffect;
|
||||
private static byte[] simpleDepthEffectInstanced;
|
||||
private static byte[] linearDepthEffect;
|
||||
private static byte[] linearDepthEffectInstanced;
|
||||
private static byte[] skyboxEffect;
|
||||
private static byte[] diffuseLitSpriteEffect;
|
||||
private static byte[] paletteCrushEffect;
|
||||
|
||||
private static byte[] unitCubeModel;
|
||||
private static byte[] unitSphereModel;
|
||||
|
||||
private static byte[] GetResource(string name)
|
||||
{
|
||||
Stream stream = typeof(Resources).Assembly.GetManifestResourceStream(
|
||||
"Kav.Resources." + name
|
||||
"Kav.Resources." + name + ".fxb"
|
||||
);
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav.Utils
|
||||
{
|
||||
public static class QuaternionUtils
|
||||
{
|
||||
// assumes that the input vectors are normalized and orthogonal
|
||||
public static Quaternion LookAt(in Vector3 forward, in Vector3 up)
|
||||
{
|
||||
Matrix orientation = Matrix.Identity;
|
||||
orientation.Forward = forward;
|
||||
orientation.Right = Vector3.Normalize(Vector3.Cross(forward, up));
|
||||
orientation.Up = Vector3.Cross(orientation.Right, forward);
|
||||
|
||||
return Quaternion.CreateFromRotationMatrix(orientation);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public static class VertexDeclarations
|
||||
{
|
||||
public static VertexDeclaration PositionInstanceDeclaration = new VertexDeclaration
|
||||
(
|
||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2)
|
||||
);
|
||||
|
||||
public static VertexDeclaration PositionTextureOffsetInstanceDeclaration = new VertexDeclaration
|
||||
(
|
||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2),
|
||||
new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 5)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct PositionTextureOffsetInstanceVertex : IVertexType
|
||||
{
|
||||
VertexDeclaration IVertexType.VertexDeclaration
|
||||
{
|
||||
get
|
||||
{
|
||||
return VertexDeclarations.PositionTextureOffsetInstanceDeclaration;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Translation { get; set; }
|
||||
public Vector2 UVOffset { get; set; }
|
||||
|
||||
public static readonly VertexDeclaration VertexDeclaration;
|
||||
|
||||
public PositionTextureOffsetInstanceVertex(
|
||||
Vector3 translation,
|
||||
Vector2 uvOffset
|
||||
) {
|
||||
Translation = translation;
|
||||
UVOffset = uvOffset;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue